Modela la lógica empresarial con atributos de transición

En esta guía, se muestran los posibles usos de los atributos de transición. Te enseñará a modelar situaciones del mundo real en dos ejemplos: incorporar el tiempo para estacionar el vehículo en las rutas optimizadas y asegurarse de que cada ruta finalice con una visita a una ubicación específica.

Antes de comenzar

Usas los atributos de transición para agregar costos y demoras específicos del modelo a ciertas transiciones en las rutas optimizadas. Estos costos y retrasos se agregan a las duraciones de transición y los costos calculados a partir de los datos del mapa según los parámetros del vehículo utilizado.

Una transición es el tramo de la ruta que conecta una ubicación con la siguiente.

Una ubicación hace referencia a cualquiera de los siguientes puntos en la ruta de un vehículo:

  • Es el punto de partida de la ruta.
  • Es una parada en la que se realiza una recolección o entrega.
  • Es el punto final de la ruta.

Para definir todos los atributos de transición del modelo, agrégalos a la lista ShipmentModel.transition_attributes. Cada elemento de la lista define un conjunto de atributos de transición y se hace coincidir con las transiciones en las rutas mediante etiquetas en la ubicación de inicio y la ubicación de destino de la transición. Para obtener más información sobre los atributos de transición, consulta la documentación de referencia de TransitionAttributes.

Modela situaciones del mundo real

En esta sección, se muestran dos ejemplos pequeños de cómo implementar restricciones comerciales del mundo real con atributos de transición.

Reserva tiempo para estacionar

En esta situación, el conductor debe estacionar el vehículo antes de visitar la ubicación A. La ubicación B está cerca, y el conductor puede usar el mismo lugar de estacionamiento para ambas visitas. Si el conductor visita B justo después de A, ahorra tiempo porque no necesita salir del lugar de estacionamiento y volver a estacionar el vehículo. En la API de Route Optimization, puedes usar atributos de transición para agregar tiempo adicional para estacionar el vehículo solo cuando el conductor se mueve de un lugar de estacionamiento a otro.

Cuando modelas el tiempo de estacionamiento por separado de las duraciones de las visitas, haces que las rutas en las que se agrupan las visitas que usan el mismo estacionamiento tarden menos tiempo. Haces que el modelo sea más preciso y también haces que el optimizador prefiera las rutas en las que se agrupan las visitas.

Sigue estos pasos para hacerlo en una solicitud a la API de Route Optimization:

  1. Usa VisitRequest.duration solo durante el tiempo necesario para realizar la visita. Por ejemplo, para entregar el paquete y obtener la firma del cliente.

  2. Para cada lugar de estacionamiento distinto que se use en el modelo, usa una etiqueta nueva que no se use para nada más en el modelo, por ejemplo, PARKING_123.

  3. Agrega esta etiqueta a lo siguiente:

    1. VisitRequest.tags en todas las solicitudes de visita que usen este lugar de estacionamiento.

    2. Vehicle.start_tags si el vehículo inicia su ruta en este lugar de estacionamiento.

    3. Vehicle.end_tags si el vehículo inicia o finaliza su ruta en este lugar de estacionamiento.

  4. Para cada nueva etiqueta de estacionamiento, agrega una entrada a ShipmentModel.transition_attributes que agregue una demora para estacionar cuando se llega desde un lugar de estacionamiento diferente. Para ello, haz lo siguiente:

    1. Establece TransitionAttributes.excluded_src_tag y TransitionAttributes.dst_tag en PARKING_123.

    2. Establece TransitionAttributes.delay en el tiempo necesario para estacionar el vehículo.

    Por ejemplo, cuando la etiqueta de una ubicación es PARKING_123 y el vehículo tarda 150 segundos en estacionarse, agregas la siguiente entrada a ShipmentModel.transition_attributes:

    {
      "excluded_src_tag": "PARKING_123",
      "dst_tag": "PARKING_123",
      "delay": "150s"
    }
    

Limpieza obligatoria al final de la ruta

En esta situación, el vehículo debe limpiarse al final de la ruta, con las siguientes restricciones adicionales:

  • La limpieza se realiza en una instalación especializada antes de regresar al depósito de vehículos. La ruta optimizada utiliza la mejor instalación de limpieza según su ubicación y las ubicaciones de las cargas y entregas que realiza el vehículo.
  • Después de la limpieza, el vehículo no debe realizar ninguna entrega ni recolección adicional.
  • El tiempo de conducir hasta allí y limpiar el vehículo se considera como parte de las horas de trabajo del conductor y debe ajustarse a la duración máxima de la ruta.

Para modelar este requisito, permite solo las rutas que están vacías o cuya última visita es a una instalación de limpieza. En la API de Route Optimization, puedes hacerlo prohibiendo las transiciones al punto de referencia de destino de la ruta desde cualquier ubicación, excepto desde la instalación de limpieza o desde el punto de partida de la ruta:

  1. Elige dos etiquetas nuevas que no se usen en ninguna parte del modelo, por ejemplo, CLEANED y ROUTE_END. El primero es para las ubicaciones donde el vehículo está limpio o se limpia, y el segundo es para el final de la ruta.
  2. Para cada vehículo, agrega un envío nuevo solo de entrega que represente la visita a una instalación de limpieza con los siguientes atributos:
    1. Cada ubicación de la instalación de limpieza debe representarse como una solicitud de visita de entrega de este envío.
    2. Agrega CLEANED a VisitRequest.tags de cada solicitud de visita del envío de la instalación de limpieza. Indica que un vehículo que sale de esta ubicación está limpio. Las demás solicitudes de visita del modelo no deben usar esta etiqueta para que el vehículo se considere "no limpio" cuando se salga de él.
    3. Para permitir que el optimizador omita este envío cuando el vehículo no se use, configura su penalty_cost en un número pequeño.
  3. Para cada vehículo, agrega CLEANED a Vehicle.start_tags. Se usa para marcar el vehículo como limpio antes de que realice cualquier retiro o entrega, siempre que se haya limpiado al final del día de trabajo anterior, y permitir que vaya del punto de referencia de partida directamente al punto de referencia de destino. Incluso si esas rutas no ocurren en la práctica, permitir esta situación ayuda al optimizador a buscar rutas optimizadas de manera más eficiente.

  4. Para cada vehículo, agrega ROUTE_END a Vehicle.end_tags.

  5. Agrega una entrada nueva a ShipmentModel.transition_attributes que prohíba que los vehículos lleguen al punto de destino final cuando no estén limpios, con las siguientes propiedades:

    1. Establece TransitionAttributes.excluded_src_tag como CLEANED.

    2. Establece TransitionAttributes.dst_tag como ROUTE_END.

    3. Establece TransitionAttributes.delay en un valor grande. Cuando haces que la demora sea más larga que la duración máxima de la ruta, prohíbes de manera eficaz que el optimizador use esta transición en una ruta.

    Por ejemplo, cuando la escala de tiempo del modelo es de un día laboral, puedes usar una demora de 24 horas (86,400 segundos) para prohibir la transición al final de la ruta desde cualquier lugar, excepto desde una instalación de limpieza y el inicio de la ruta:

    {
      "excluded_src_tag": "CLEANED",
      "dst_tag": "ROUTE_END",
      "delay": "86400s"
    }
    

Cómo elegir entre demoras y costos

La elección entre demoras y costos depende de la naturaleza de la lógica y las restricciones comerciales implementadas. Es mejor establecer TransitionAttributes.delay para implementar restricciones estrictas o expresar una compensación en términos del tiempo dedicado. TransitionAttributes.cost se adapta mejor cuando se implementan preferencias flexibles o compensaciones expresadas como un costo adicional. Puedes combinar demoras y costos de forma arbitraria cuando se trata del tiempo dedicado y el costo.

En el ejemplo de limpieza de vehículos, se usa una demora muy larga, ya que limpiar el vehículo al final de la ruta es un requisito estricto, y la demora prolongada evita que el optimizador lo ignore. Si solo estableces un costo, el optimizador podría omitir la limpieza si encuentra una forma de compensar el costo en otro lugar, por ejemplo, entregando más envíos en el tiempo que se “ahorró” por no limpiar el vehículo.

En el ejemplo de estacionamiento, se usa una demora breve que corresponde al tiempo adicional necesario para estacionar el vehículo. También puedes usar costs en combinación con retrasos si el conductor se detiene en un estacionamiento pagado.

Cómo agregar un atributo de transición que coincida con todas las solicitudes de visita

En los ejemplos anteriores, se usan atributos de transición que coinciden con ubicaciones que tienen una etiqueta determinada o que no la tienen. Pero ¿qué sucede si necesitas agregar atributos de transición que se apliquen a todas las transiciones?

No puedes omitir las etiquetas, ya que cada mensaje TransitionAttributes debe tener una de TransitionAttributes.src_tag y TransitionAttributes.excluded_src_tag, y una de TransitionAttributes.dst_tag y TransitionAttributes.excluded_dst_tag.

Sin embargo, puedes hacer coincidir todas las etiquetas configurando TransitionAttributes.excluded_src_tag o TransitionAttributes.excluded_dst_tag en una etiqueta que no se use en ninguna parte del modelo. Esto coincidirá con todas las ubicaciones que no tengan esta etiqueta, pero como elegiste de forma intencional una etiqueta que ninguna ubicación usa, estos atributos de transición coincidirán con todas las ubicaciones.

Lecturas adicionales