メインコンテンツまでスキップ

Finalization Type

The Finalization Type is a post-processing instruction that fine-tunes the exact scheduled time for a stop after the optimal route has already been determined.

It does not change the sequence of stops in a route, but it adjusts when a vehicle is scheduled to arrive at a node within its available time window. This allows planners to control for preferences like minimizing vehicle waiting time or prioritizing early arrivals.

This setting is applied on a per-node basis using the finalization_type property.

How Finalization Type Works

Once the optimization engine has found the most efficient sequence of stops for a vehicle, the finalization step adjusts the arrival times based on one of two settings:

  • max: Schedule as late as possible. The optimizer pushes the scheduled arrival time to the latest possible moment within the node's time window.
  • min: Schedule as early as possible. The optimizer sets the scheduled arrival time to the earliest possible moment.

Value for Planners and Impact on Routes

The finalization_type provides a powerful tool for planners to align route execution with specific business goals without altering the fundamental efficiency of the route itself.

  • For Planners:

    • Minimize Slack: max is the key to reducing costly vehicle and driver idle time. It creates a more "just-in-time" schedule.
    • Improve Customer Service: min can be used to meet the expectations of customers who want their service as early as possible.
    • Operational Flexibility: It allows for fine-grained control over the schedule on a stop-by-stop basis.
  • Impact on Routes:

    • No change in stop sequence: The actual path the vehicle takes remains the same.
    • Adjusts slack and arrival times: Its primary impact is redistributing slack within the route. It can shift waiting time from one stop to another or eliminate it entirely by scheduling a previous stop later.

A Concrete Example

Consider a single vehicle route with two drop-off stops:

  • Stop A: Time Window from 9:00 AM to 10:00 AM.
  • Stop B: Time Window from 11:00 AM to 12:00 PM.

The optimizer determines the best route is Depot -> Stop A -> Stop B.

  • Travel time from Depot to Stop A is 30 minutes. Vehicle leaves depot at 8:30 AM.
  • Earliest arrival at Stop A is 9:00 AM.
  • Service at Stop A takes 15 minutes.
  • Travel from Stop A to Stop B is 45 minutes.

Scenario 1: No Finalization (Default Behavior)

  • Arrive at Stop A: 9:00 AM.
  • Depart Stop A: 9:15 AM.
  • Arrive at Stop B: 10:00 AM.
  • Wait at Stop B: 60 minutes (until the 11:00 AM window opens). This is vehicle slack.

Scenario 2: finalization_type: "max" at Stop A

  • The optimizer sees the 60-minute slack at Stop B.
  • To minimize this slack, it pushes the schedule for Stop A later.
  • New arrival at Stop A: 10:00 AM (the end of its window).
  • Depart Stop A: 10:15 AM.
  • New arrival at Stop B: 11:00 AM.
  • Wait at Stop B: 0 minutes. The slack has been absorbed by arriving later at the earlier stop.

Scenario 3: finalization_type: "min" at Stop A

  • The schedule would be the same as the default behavior. The vehicle arrives as early as it can.
  • This would be useful if the customer at Stop A prefers the earliest possible delivery.

Example Configuration

Here is a JSON snippet for a node_scheduler request. In this example, the first dropoff node is set to max to minimize potential waiting time before the second stop.

{
"nodes": [
{
"uid": "f0de0001-2024-0731-88ad-05ddd46ce72d",
"booking_uid": "b00c0000-2024-0421-0616-000000000001",
"node_type": "dropoff",
"lat": 1.280097,
"lon": 103.889129,
"open_time_ts": "2026-01-01T09:00:00+00:00",
"close_time_ts": "2026-01-01T10:00:00+00:00",
"service_time": 360,
"demand": { "units": 10 },
"finalization_type": "max"
},
{
"uid": "f0de0001-2024-0731-88ad-05ddd46ce74d",
"booking_uid": "b00c0000-2024-0421-0616-000000000002",
"node_type": "dropoff",
"lat": 1.290097,
"lon": 103.989129,
"open_time_ts": "2026-01-01T11:00:00+00:00",
"close_time_ts": "2026-01-01T12:00:00+00:00",
"service_time": 360,
"demand": { "units": 10 }
}
// ... other nodes and vehicle configuration
]
}

Playground

You can experiment with the Finalization Type concept using the playground below. The example is set up with two drop-off nodes with a time gap between them.

  • Try setting the finalization_type of the first drop-off node to "max" to see how it reduces the slack time at the second node.
  • Then, change it to "min" to see the vehicle arriving as early as possible, resulting in a longer wait at the next stop.
Loading...

Interaction with Slack Cost

The solver's behavior regarding slack (waiting time) depends heavily on the chosen optimization goal and the finalization_type.

  • Goal: total_time: The solver naturally aims to minimize total time, which implicitly minimizes slack. However, setting finalization_type to "min" (earliest possible) or "max" (latest possible) constrains departure and arrival times, potentially forcing the solver to accept unwanted slack to satisfy the "edge" constraint.
  • Goal: total_distance: In this mode, the solver optimizes purely for mileage. Slack and duration are not primary factors and therefore can produce a low of unwanted slack if slack optimization is disabled. If finalization_type is used here, it will dictate the schedule timings without regard for accumulated waiting time, potentially leading to significant idle periods.

If minimizing slack is critical but you require specific finalization behaviors, consider these strategies:

  1. Adjust slack_cost_factor: Increasing the cost of slack encourages the solver to reduce waiting time. However, be aware that minimizing slack often encourages positioning timings "in the middle" of time windows to make connections seamless, which directly contradicts the "push to edges" behavior of "min" or "max" finalization types.
  2. Accept the Trade-off: If you strictly need the finalization behavior (e.g., "always arrive ASAP"), you may have to accept that slack is a necessary byproduct of that constraint, regardless of the optimization goal.

The example below features fine-tuned time windows that allow you to experiment with various finalization_type behaviors, with or without slack optimization enabled. This is controlled by the "path_constraints_mode": "logistics" and "slack_cost_factor": 1 parameters. Consider switching off slack optimization to observe how adjusting the finalization type for drop-off (for example, setting min for one dropoff and max for another dropoff nodes) affects the route in isolation. The example is using PDP mode, but the same principles are applicable to the CVRPTW mode.

Loading...