This guide shows possible uses of transition attributes. It will teach you how to model real-world scenarios on two examples: incorporating time to park the vehicle into the optimized routes, and ensuring that each route ends with a visit to a specific location.
Before you begin
You use transition attributes to add model-specific costs and delays to certain transitions in the optimized routes. These costs and delays are added on top of the transition durations and costs computed from the map data based on the parameters of the vehicle used.
A transition is the segment of the route that connects one location to the next.
A location refers to any of the following points in a vehicle's route:
- The starting point of the route.
- A stop where a pickup or a delivery is made.
- The ending point of the route.
You define all transition attributes for the model by adding them to the list
ShipmentModel.transition_attributes
.
Each element of the list defines one set of transition attributes, and it is
matched with transitions in the routes using tags on the start location and the
end location of the transition. To learn more about transition attributes, see
the reference documentation for
TransitionAttributes
.
Model real-world scenarios
This section shows two small examples of how to implement real-world business constraints using transition attributes.
Reserve time for parking
In this scenario, the driver needs to park the vehicle before they can visit location A. Location B is nearby, and the driver can use the same parking spot for both visits. If the driver visits B right after A, they save time because they don't need to leave the parking spot and park the vehicle again. In the Route Optimization API, you can use transition attributes to add extra time to park the vehicle only when the driver moves from one parking spot to other.
When you model the parking time separately from visit durations, you make routes where visits that use the same parking are grouped take less time. You make the model more precise, and you also make the optimizer prefer routes where the visits are grouped.
Use the following steps to do this in a Route Optimization API request:
Use
VisitRequest.duration
only for the time needed to perform the visit. For example, to hand over the package and collect a signature from the customer.For each distinct parking spot used in the model, use a new tag that is not used for anything else in the model, for example
PARKING_123
.Add this tag to the following:
VisitRequest.tags
in all visit requests that use this parking spot.Vehicle.start_tags
if the vehicle starts its route at this parking spot.Vehicle.end_tags
if the vehicle starts ends its route at this parking spot.
For each new parking tag, add an entry to
ShipmentModel.transition_attributes
that adds a delay for parking when coming from a different parking spot by doing the following:Set
TransitionAttributes.excluded_src_tag
andTransitionAttributes.dst_tag
toPARKING_123
.Set
TransitionAttributes.delay
to the time needed to park the vehicle.
For example, when the tag of a location is
PARKING_123
and it takes 150 seconds to park the vehicle, you add the following entry toShipmentModel.transition_attributes
:{ "excluded_src_tag": "PARKING_123", "dst_tag": "PARKING_123", "delay": "150s" }
Mandatory cleaning at the end of the route
In this scenario, the vehicle needs to be cleaned at the end of the route, with the following additional constraints:
- The cleaning is done at a specialized cleaning facility before returning to the vehicle depot. The optimized route uses the best cleaning facility based on its location and the locations of the pickups and deliveries made by the vehicle.
- After the cleaning, the vehicle must not perform any additional pickups or deliveries.
- The time to drive there and clean the vehicle counts against the working hours of the driver, and it must fit into the maximal duration of the route.
You model this requirement by allowing only routes that are either empty or whose last visit is to a cleaning facility. In the Route Optimization API, you do this by prohibiting transitions to the ending waypoint of the route from any location except from the cleaning facility or from the starting point of the route:
- Pick two new tags that are not used anywhere in the model, for example
CLEANED
andROUTE_END
. The former is for locations where the vehicle is or becomes clean, and the latter is for end of the route. - For each vehicle, add a new delivery-only shipment that represents the visit
to a cleaning facility with the following attributes:
- Each cleaning facility location should be represented as a delivery visit request of this shipment.
- Add
CLEANED
toVisitRequest.tags
of each visit request of the cleaning facility shipment. It signals that a vehicle leaving this location is clean. Other visit requests in the model shouldn't use this tag so that the vehicle is considered "not clean" when leaving them. - Allow the optimizer to skip this shipment when the vehicle is otherwise
unused by setting its
penalty_cost
to a small number.
For each vehicle, add
CLEANED
toVehicle.start_tags
. This is used to mark the vehicle as clean before it performs any pickups or deliveries, assuming that it has been cleaned at the end of the previous working day, and allow it to go from the starting waypoint directly to its end waypoint. Even if such routes don't happen in practice, allowing this scenario helps the optimizer search for optimized routes more efficiently.For each vehicle, add
ROUTE_END
toVehicle.end_tags
.Add a new entry to
ShipmentModel.transition_attributes
that prohibits vehicles from arriving at the vehicle end waypoint when they are not clean, with the following properties:Set
TransitionAttributes.excluded_src_tag
toCLEANED
.Set
TransitionAttributes.dst_tag
toROUTE_END
.Set
TransitionAttributes.delay
to a large value. When you make the delay longer than the maximal route duration, you effectively prohibit the optimizer from using this transition in a route.
For example, when the time scale of the model is one working day, you can use a delay of 24 hours (86400 seconds) to prohibit the transition to the end of the route from anywhere except a cleaning facility and the start of the route:
{ "excluded_src_tag": "CLEANED", "dst_tag": "ROUTE_END", "delay": "86400s" }
How to choose between delays and costs
The choice between delays and costs depends on the nature of the implemented
business logic and constraints. Setting
TransitionAttributes.delay
is best for implementing hard constraints or to express a trade-off in terms of
the time spent.
TransitionAttributes.cost
fits better when implementing soft preferences or trade-offs expressed as an
additional cost. You may combine delays and costs arbitrarily when both time
spent and cost are concerned.
The vehicle cleaning example uses a very long delay, because cleaning the vehicle at the end of the route is a hard requirement and the long delay prevents the optimizer from ignoring the requirement. If you set only a cost, the optimizer could choose to skip the cleaning, if it finds a way to make up for the cost elsewhere, for example by delivering more shipments in the time "saved" by not cleaning the vehicle.
The parking example uses a short delay that corresponds to the additional time needed to park the vehicle. You could also use costs in combination with delays, if the driver stops at a paid parking lot.
How to add a transition attribute that matches all visit requests
The examples above use transition attributes that match locations that have a given tag, or locations that don't have the tag. But what if you need to add transition attributes that apply to all transitions?
You can't just omit the tags, because each
TransitionAttributes
message must have one of
TransitionAttributes.src_tag
and
TransitionAttributes.excluded_src_tag
and one of
TransitionAttributes.dst_tag
and
TransitionAttributes.excluded_dst_tag
.
However, you can match all tags by setting
TransitionAttributes.excluded_src_tag
or
TransitionAttributes.excluded_dst_tag
to a tag that is not used anywhere in the model. This will match all locations
that don't have this tag, but since you intentionally chose a tag that is not
used by any location, these transition attributes will match all locations.