GuidesAPI Reference
Guides

Use objective functions for specific optimization goals

An objective is the goal in an optimization problem. It is the value to be minimized or maximized over the set of all feasible solutions that satisfy the problem constraints. When objectives are used, they are specified together as an array using the objectives property. Not all objectives need to be specified every time, and their presence/absence and the sequence in which they are listed is important, with objectives appearing on top of the list being more important than those appearing further down. A soft constraint considers other settings; a hard constraint is an imperative. Using the sequence allows you to achieve a multi-objective solution.

📘

Note

The objectives minimizeUnassigned and minimizeCost are mandatory. There will be an API error if they are omitted.

To understand the power of these objectives, consider a scenario where drivers are paid based on how long they work. In such cases, the dispatcher tries to structure the tour to take as little time as possible to reduce operational costs and improve efficiency. Objective functions allow you to impose this logic on your solution.

The objective minimizeDuration allows you to reduce the time of the tour. Here is an example of the objectives array you would add to your problem:


"objectives": [
    {
      "type": "minimizeUnassigned"
    },
    {
      "type": "minimizeDuration"
    },
    {
      "type": "minimizeCost"
    }
]

If you do not specify any objectives, by default the solver follows this logic:

  • With highest importance, it minimizes the amount of unassigned jobs.
  • With medium importance, it minimizes the number of tours.
  • With least importance, it minimizes the total cost.

This is equivalent to the following definition:


"objectives": [
    {
      "type": "minimizeUnassigned"
    },
    {
      "type": "optimizeTourCount"
      "action": "minimize"
    },
    {
      "type": "minimizeCost"
    }
]

For more information, including a list of all objectives, see Objectives.

Optimize task sequence use case

This section looks at how to use the objective optimizeTaskOrder to control the order of job task activities in the tour. Task order can be used as either a hard or soft constraint. When optimizeTaskOrder is a soft constraint, we still try to follow the order property value, but if it can lead to the job being unassigned, we let the order constraint be violated so that the job can still be assigned.

There are three different problem formulations, and the job type is pickup:

  • First, there is a simple problem with a task order that cannot be fulfilled for some reason, for instance, due to conflicting time windows.
  • Then, there is a problem to show that without the objective no tour will be created, but with the objective it will still create the tour.
  • In the third problem, the time windows are removed and this shows that in that case the job order is obeyed. In this example, the shift end is not specified, so the shortest route is using open VRP and putting one job close to the depot and one further away. Then the solver will by default try first to serve the job close to the depot, because that gives an overall shorter tour.

Problem: No optimizeTaskOrder specification

Here is the base problem.

  • VRP with a shift with distinct depot locations for the start and the end
  • 3 jobs to be served
    • Job_1 (with specified time window)
    • Job_2
    • Job_3 can be comfortably served in sequence on the road from the location of the beginning of the shift.
    When the problem is specified without tour order, then jobs are visited as the road follows: visit Job_1, then visit Job_2, and finally Job_3. The vehicle arrives at the final location of the shift.

See the solution.

{
    "plan": {
        "jobs": [
            {
                "id": "Job_1_1h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.066063,
                                        "lng": 11.917153
                                    },
                                    "times": [
                                        [
                                            "2023-09-20T08:00:00Z",
                                            "2023-09-20T10:00:00Z"
                                        ]
                                    ],
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ]
                        }
                    ]
                }
            },
            {
                "id": "Job_2_2h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.526849,
                                        "lng": 11.066198
                                    },
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ]
                        }
                    ]
                }
            },
            {
                "id": "Job_3_3h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.785296,
                                        "lng": 10.129362
                                    },
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ]
                        }
                    ]
                }
            }
        ]
    },
    "fleet": {
        "types": [
            {
                "id": "vehicle_1",
                "profile": "normal_car",
                "costs": {
                    "fixed": 22,
                    "distance": 0.0002,
                    "time": 0.0048
                },
                "shifts": [
                    {
                        "start": {
                            "time": "2023-09-20T08:00:00Z",
                            "location": {
                                "lat": 48.821421,
                                "lng": 12.931591
                            }
                        },
                        "end": {
                            "time": "2023-09-22T23:00:00Z",
                            "location": {
                                "lat": 50.912724,
                                "lng": 7.1055
                            }
                        }
                    }
                ],
                "capacity": [
                    10
                ],
                "amount": 1
            }
        ],
        "profiles": [
            {
                "name": "normal_car",
                "type": "car",
                "traffic": {
                    "mode": "disabled"
                }
            }
        ]
    }
}

Solution: No optimizeTaskOrder specification

{
    "statistic": {
        "cost": 275.6742,
        "distance": 559867,
        "duration": 29521,
        "times": {
            "driving": 18721,
            "serving": 10800,
            "waiting": 0,
            "stopping": 0,
            "break": 0
        }
    },
    "tours": [
        {
            "vehicleId": "vehicle_1_1",
            "typeId": "vehicle_1",
            "stops": [
                {
                    "time": {
                        "arrival": "2023-09-20T08:00:00Z",
                        "departure": "2023-09-20T08:00:00Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "departure",
                            "type": "departure",
                            "location": {
                                "lat": 48.821421,
                                "lng": 12.931591
                            },
                            "time": {
                                "start": "2023-09-20T08:00:00Z",
                                "end": "2023-09-20T08:00:00Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 48.821421,
                        "lng": 12.931591
                    },
                    "distance": 0
                },
                {
                    "time": {
                        "arrival": "2023-09-20T08:50:15Z",
                        "departure": "2023-09-20T09:50:15Z"
                    },
                    "load": [
                        1
                    ],
                    "activities": [
                        {
                            "jobId": "Job_1_1h_driving",
                            "type": "pickup",
                            "location": {
                                "lat": 49.066063,
                                "lng": 11.917153
                            },
                            "time": {
                                "start": "2023-09-20T08:50:15Z",
                                "end": "2023-09-20T09:50:15Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 49.066063,
                        "lng": 11.917153
                    },
                    "distance": 86277
                },
                {
                    "time": {
                        "arrival": "2023-09-20T10:38:58Z",
                        "departure": "2023-09-20T11:38:58Z"
                    },
                    "load": [
                        2
                    ],
                    "activities": [
                        {
                            "jobId": "Job_2_2h_driving",
                            "type": "pickup",
                            "location": {
                                "lat": 49.526849,
                                "lng": 11.066198
                            },
                            "time": {
                                "start": "2023-09-20T10:38:58Z",
                                "end": "2023-09-20T11:38:58Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 49.526849,
                        "lng": 11.066198
                    },
                    "distance": 174491
                },
                {
                    "time": {
                        "arrival": "2023-09-20T12:29:23Z",
                        "departure": "2023-09-20T13:29:23Z"
                    },
                    "load": [
                        3
                    ],
                    "activities": [
                        {
                            "jobId": "Job_3_3h_driving",
                            "type": "pickup",
                            "location": {
                                "lat": 49.785296,
                                "lng": 10.129362
                            },
                            "time": {
                                "start": "2023-09-20T12:29:23Z",
                                "end": "2023-09-20T13:29:23Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 49.785296,
                        "lng": 10.129362
                    },
                    "distance": 258526
                },
                {
                    "time": {
                        "arrival": "2023-09-20T16:12:01Z",
                        "departure": "2023-09-20T16:12:01Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "arrival",
                            "type": "arrival",
                            "location": {
                                "lat": 50.912724,
                                "lng": 7.1055
                            },
                            "time": {
                                "start": "2023-09-20T16:12:01Z",
                                "end": "2023-09-20T16:12:01Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 50.912724,
                        "lng": 7.1055
                    },
                    "distance": 559867
                }
            ],
            "statistic": {
                "cost": 275.6742,
                "distance": 559867,
                "duration": 29521,
                "times": {
                    "driving": 18721,
                    "serving": 10800,
                    "waiting": 0,
                    "stopping": 0,
                    "break": 0
                }
            },
            "shiftIndex": 0
        }
    ]
}

Problem: Task order as hard constraint

When optimizeTaskOrder is not specified, but the order property is defined on the job's level, it is considered as a hard constraint, which cannot be violated.

In this example, modify the initial file and change the order. Assume the need to serve Job_3 first, Job_2 second, and Job_1 should be third, while at the same time, Job_1 still needs to be served in the 8:00 - 9:00 time window.

See the solution.

{
    "plan": {
        "jobs": [
            {
                "id": "Job_1_1h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.066063,
                                        "lng": 11.917153
                                    },
                                    "times": [
                                        [
                                            "2023-09-20T08:00:00Z",
                                            "2023-09-20T10:00:00Z"
                                        ]
                                    ],
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ],
                            "order": 3
                        }
                    ]
                }
            },
            {
                "id": "Job_2_2h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.526849,
                                        "lng": 11.066198
                                    },
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ],
                            "order": 2
                        }
                    ]
                }
            },
            {
                "id": "Job_3_3h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.785296,
                                        "lng": 10.129362
                                    },
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ],
                            "order": 1
                        }
                    ]
                }
            }
        ]
    },
    "fleet": {
        "types": [
            {
                "id": "vehicle_1",
                "profile": "normal_car",
                "costs": {
                    "fixed": 22,
                    "distance": 0.0002,
                    "time": 0.0048
                },
                "shifts": [
                    {
                        "start": {
                            "time": "2023-09-20T08:00:00Z",
                            "location": {
                                "lat": 48.821421,
                                "lng": 12.931591
                            }
                        },
                        "end": {
                            "time": "2023-09-22T23:00:00Z",
                            "location": {
                                "lat": 50.912724,
                                "lng": 7.1055
                            }
                        }
                    }
                ],
                "capacity": [
                    10
                ],
                "amount": 1
            }
        ],
        "profiles": [
            {
                "name": "normal_car",
                "type": "car",
                "traffic": {
                    "mode": "disabled"
                }
            }
        ]
    }
}

Solution: Task order as hard constraint

Now the solution is different.

  • Start with Job_3, as required
  • Visit the location of Job_2
  • It is impossible to serve Job_1 third in the required time window, so Job_1 is unassigned now - when a hard constraint is violated.
{
    "statistic": {
        "cost": 330.42359999999996,
        "distance": 751702,
        "duration": 32934,
        "times": {
            "driving": 25734,
            "serving": 7200,
            "waiting": 0,
            "stopping": 0,
            "break": 0
        }
    },
    "tours": [
        {
            "vehicleId": "vehicle_1_1",
            "typeId": "vehicle_1",
            "stops": [
                {
                    "time": {
                        "arrival": "2023-09-20T08:00:00Z",
                        "departure": "2023-09-20T08:00:00Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "departure",
                            "type": "departure",
                            "location": {
                                "lat": 48.821421,
                                "lng": 12.931591
                            },
                            "time": {
                                "start": "2023-09-20T08:00:00Z",
                                "end": "2023-09-20T08:00:00Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 48.821421,
                        "lng": 12.931591
                    },
                    "distance": 0
                },
                {
                    "time": {
                        "arrival": "2023-09-20T10:29:23Z",
                        "departure": "2023-09-20T11:29:23Z"
                    },
                    "load": [
                        1
                    ],
                    "activities": [
                        {
                            "jobId": "Job_3_3h_driving",
                            "type": "pickup",
                            "location": {
                                "lat": 49.785296,
                                "lng": 10.129362
                            },
                            "time": {
                                "start": "2023-09-20T10:29:23Z",
                                "end": "2023-09-20T11:29:23Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 49.785296,
                        "lng": 10.129362
                    },
                    "distance": 258526
                },
                {
                    "time": {
                        "arrival": "2023-09-20T12:35:50Z",
                        "departure": "2023-09-20T13:35:50Z"
                    },
                    "load": [
                        2
                    ],
                    "activities": [
                        {
                            "jobId": "Job_2_2h_driving",
                            "type": "pickup",
                            "location": {
                                "lat": 49.526849,
                                "lng": 11.066198
                            },
                            "time": {
                                "start": "2023-09-20T12:35:50Z",
                                "end": "2023-09-20T13:35:50Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 49.526849,
                        "lng": 11.066198
                    },
                    "distance": 366326
                },
                {
                    "time": {
                        "arrival": "2023-09-20T17:08:54Z",
                        "departure": "2023-09-20T17:08:54Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "arrival",
                            "type": "arrival",
                            "location": {
                                "lat": 50.912724,
                                "lng": 7.1055
                            },
                            "time": {
                                "start": "2023-09-20T17:08:54Z",
                                "end": "2023-09-20T17:08:54Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 50.912724,
                        "lng": 7.1055
                    },
                    "distance": 751702
                }
            ],
            "statistic": {
                "cost": 330.42359999999996,
                "distance": 751702,
                "duration": 32934,
                "times": {
                    "driving": 25734,
                    "serving": 7200,
                    "waiting": 0,
                    "stopping": 0,
                    "break": 0
                }
            },
            "shiftIndex": 0
        }
    ],
    "unassigned": [
        {
            "jobId": "Job_1_1h_driving",
            "reasons": [
                {
                    "code": "TIME_WINDOW_CONSTRAINT",
                    "description": "cannot be assigned due to violation of time window",
                    "details": [
                        {
                            "vehicleId": "vehicle_1_1",
                            "shiftIndex": 0
                        }
                    ]
                }
            ]
        }
    ]
}

Problem: Task order as soft constraint with time windows

When specified, optimizeTaskOrder is considered as a soft constraint, and the solver tries to minimize the number of violations, using time windows.

Here, you try to keep the new order, but instead of being unassigned, the constraint will be violated.

  • Start with Job_1, against the specified order, but within the specified time window.
  • Try to keep the order as much as possible, so go to the third job, that should have been first.
  • Last, visit Job_2. This is a compromise: the order is preserved whenever possible, but not at the cost of unassigned jobs, as that objective has been specified to be more important.

See the solution.

{  "objectives": [
    {
      "type": "minimizeUnassigned"
    },
    {
      "type": "optimizeTaskOrder"
    },
    {
      "type": "minimizeCost"
    }
  ],
    "plan": {
        "jobs": [
            {
                "id": "Job_1_1h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.066063,
                                        "lng": 11.917153
                                    },
                                    "times": [
                                        [
                                            "2023-09-20T08:00:00Z",
                                            "2023-09-20T10:00:00Z"
                                        ]
                                    ],
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ],
                            "order": 3
                        }
                    ]
                }
            },
            {
                "id": "Job_2_2h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.526849,
                                        "lng": 11.066198
                                    },
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ],
                            "order": 2
                        }
                    ]
                }
            },
            {
                "id": "Job_3_3h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.785296,
                                        "lng": 10.129362
                                    },
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ],
                            "order":1
                        }
                    ]
                }
            }
        ]
    },
    "fleet": {
        "types": [
            {
                "id": "vehicle_1",
                "profile": "normal_car",
                "costs": {
                    "fixed": 22,
                    "distance": 0.0002,
                    "time": 0.0048
                },
                "shifts": [
                    {
                        "start": {
                            "time": "2023-09-20T08:00:00Z",
                            "location": {
                                "lat": 48.821421,
                                "lng": 12.931591
                            }
                        },
                        "end": {
                            "time": "2023-09-22T23:00:00Z",
                            "location": {
                                "lat": 50.912724,
                                "lng": 7.1055
                            }
                        }
                    }
                ],
                "capacity": [
                    10
                ],
                "amount": 1
            }
        ],
        "profiles": [
            {
                "name": "normal_car",
                "type": "car",
                "traffic": {
                    "mode": "disabled"
                }
      
            }
        ]
    }
}

Solution: Task order as soft constraint with time windows

{
    "statistic": {
        "cost": 347.7036,
        "distance": 751702,
        "duration": 36534,
        "times": {
            "driving": 25734,
            "serving": 10800,
            "waiting": 0,
            "stopping": 0,
            "break": 0
        }
    },
    "tours": [
        {
            "vehicleId": "vehicle_1_1",
            "typeId": "vehicle_1",
            "stops": [
                {
                    "time": {
                        "arrival": "2023-09-20T08:00:00Z",
                        "departure": "2023-09-20T08:00:00Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "departure",
                            "type": "departure",
                            "location": {
                                "lat": 48.821421,
                                "lng": 12.931591
                            },
                            "time": {
                                "start": "2023-09-20T08:00:00Z",
                                "end": "2023-09-20T08:00:00Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 48.821421,
                        "lng": 12.931591
                    },
                    "distance": 0
                },
                {
                    "time": {
                        "arrival": "2023-09-20T08:50:15Z",
                        "departure": "2023-09-20T09:50:15Z"
                    },
                    "load": [
                        1
                    ],
                    "activities": [
                        {
                            "jobId": "Job_1_1h_driving",
                            "type": "pickup",
                            "location": {
                                "lat": 49.066063,
                                "lng": 11.917153
                            },
                            "time": {
                                "start": "2023-09-20T08:50:15Z",
                                "end": "2023-09-20T09:50:15Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 49.066063,
                        "lng": 11.917153
                    },
                    "distance": 86277
                },
                {
                    "time": {
                        "arrival": "2023-09-20T11:29:23Z",
                        "departure": "2023-09-20T12:29:23Z"
                    },
                    "load": [
                        2
                    ],
                    "activities": [
                        {
                            "jobId": "Job_3_3h_driving",
                            "type": "pickup",
                            "location": {
                                "lat": 49.785296,
                                "lng": 10.129362
                            },
                            "time": {
                                "start": "2023-09-20T11:29:23Z",
                                "end": "2023-09-20T12:29:23Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 49.785296,
                        "lng": 10.129362
                    },
                    "distance": 258526
                },
                {
                    "time": {
                        "arrival": "2023-09-20T13:35:50Z",
                        "departure": "2023-09-20T14:35:50Z"
                    },
                    "load": [
                        3
                    ],
                    "activities": [
                        {
                            "jobId": "Job_2_2h_driving",
                            "type": "pickup",
                            "location": {
                                "lat": 49.526849,
                                "lng": 11.066198
                            },
                            "time": {
                                "start": "2023-09-20T13:35:50Z",
                                "end": "2023-09-20T14:35:50Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 49.526849,
                        "lng": 11.066198
                    },
                    "distance": 366326
                },
                {
                    "time": {
                        "arrival": "2023-09-20T18:08:54Z",
                        "departure": "2023-09-20T18:08:54Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "arrival",
                            "type": "arrival",
                            "location": {
                                "lat": 50.912724,
                                "lng": 7.1055
                            },
                            "time": {
                                "start": "2023-09-20T18:08:54Z",
                                "end": "2023-09-20T18:08:54Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 50.912724,
                        "lng": 7.1055
                    },
                    "distance": 751702
                }
            ],
            "statistic": {
                "cost": 347.7036,
                "distance": 751702,
                "duration": 36534,
                "times": {
                    "driving": 25734,
                    "serving": 10800,
                    "waiting": 0,
                    "stopping": 0,
                    "break": 0
                }
            },
            "shiftIndex": 0
        }
    ]
}

Problem: Task order as soft constraint with no time windows

In this problem, the task order is considered a soft constraint and the resolution tries to minimize the number of violations using no time windows.

Assume now that it is not necessary to deliver Job_1 within a specified time window. In this situation, all the jobs can be served in the desired order without unassignment. Therefore, whether you use task order as a hard or soft constraint, you would get the same job order - Job_3, Job_2 and then Job_1.

See the solution.

{  "objectives": [
    {
      "type": "minimizeUnassigned"
    },
    {
      "type": "optimizeTaskOrder"
    },
    {
      "type": "minimizeCost"
    }
  ],
    "plan": {
        "jobs": [
            {
                "id": "Job_1_1h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.066063,
                                        "lng": 11.917153
                                    },
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ],
                            "order": 3
                        }
                    ]
                }
            },
            {
                "id": "Job_2_2h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.526849,
                                        "lng": 11.066198
                                    },
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ],
                            "order": 2
                        }
                    ]
                }
            },
            {
                "id": "Job_3_3h_driving",
                "tasks": {
                    "pickups": [
                        {
                            "places": [
                                {
                                    "location": {
                                        "lat": 49.785296,
                                        "lng": 10.129362
                                    },
                                    "duration": 3600
                                }
                            ],
                            "demand": [
                                1
                            ],
                            "order":1
                        }
                    ]
                }
            }
        ]
    },
    "fleet": {
        "types": [
            {
                "id": "vehicle_1",
                "profile": "normal_car",
                "costs": {
                    "fixed": 22,
                    "distance": 0.0002,
                    "time": 0.0048
                },
                "shifts": [
                    {
                        "start": {
                            "time": "2023-09-20T08:00:00Z",
                            "location": {
                                "lat": 48.821421,
                                "lng": 12.931591
                            }
                        },
                        "end": {
                            "time": "2023-09-22T23:00:00Z",
                            "location": {
                                "lat": 50.912724,
                                "lng": 7.1055
                            }
                        }
                    }
                ],
                "capacity": [
                    10
                ],
                "amount": 1
            }
        ],
        "profiles": [
            {
                "name": "normal_car",
                "type": "car",
                "traffic": {
                    "mode": "disabled"
                }
      
            }
        ]
    }
}

Solution: Task order as soft constraint with no time windows

{
    "statistic": {
        "cost": 418.1166,
        "distance": 945823,
        "duration": 43115,
        "times": {
            "driving": 32315,
            "serving": 10800,
            "waiting": 0,
            "stopping": 0,
            "break": 0
        }
    },
    "tours": [
        {
            "vehicleId": "vehicle_1_1",
            "typeId": "vehicle_1",
            "stops": [
                {
                    "time": {
                        "arrival": "2023-09-20T08:00:00Z",
                        "departure": "2023-09-20T08:00:00Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "departure",
                            "type": "departure",
                            "location": {
                                "lat": 48.821421,
                                "lng": 12.931591
                            },
                            "time": {
                                "start": "2023-09-20T08:00:00Z",
                                "end": "2023-09-20T08:00:00Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 48.821421,
                        "lng": 12.931591
                    },
                    "distance": 0
                },
                {
                    "time": {
                        "arrival": "2023-09-20T10:29:23Z",
                        "departure": "2023-09-20T11:29:23Z"
                    },
                    "load": [
                        1
                    ],
                    "activities": [
                        {
                            "jobId": "Job_3_3h_driving",
                            "type": "pickup",
                            "location": {
                                "lat": 49.785296,
                                "lng": 10.129362
                            },
                            "time": {
                                "start": "2023-09-20T10:29:23Z",
                                "end": "2023-09-20T11:29:23Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 49.785296,
                        "lng": 10.129362
                    },
                    "distance": 258526
                },
                {
                    "time": {
                        "arrival": "2023-09-20T12:35:50Z",
                        "departure": "2023-09-20T13:35:50Z"
                    },
                    "load": [
                        2
                    ],
                    "activities": [
                        {
                            "jobId": "Job_2_2h_driving",
                            "type": "pickup",
                            "location": {
                                "lat": 49.526849,
                                "lng": 11.066198
                            },
                            "time": {
                                "start": "2023-09-20T12:35:50Z",
                                "end": "2023-09-20T13:35:50Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 49.526849,
                        "lng": 11.066198
                    },
                    "distance": 366326
                },
                {
                    "time": {
                        "arrival": "2023-09-20T14:36:48Z",
                        "departure": "2023-09-20T15:36:48Z"
                    },
                    "load": [
                        3
                    ],
                    "activities": [
                        {
                            "jobId": "Job_1_1h_driving",
                            "type": "pickup",
                            "location": {
                                "lat": 49.066063,
                                "lng": 11.917153
                            },
                            "time": {
                                "start": "2023-09-20T14:36:48Z",
                                "end": "2023-09-20T15:36:48Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 49.066063,
                        "lng": 11.917153
                    },
                    "distance": 472233
                },
                {
                    "time": {
                        "arrival": "2023-09-20T19:58:35Z",
                        "departure": "2023-09-20T19:58:35Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "arrival",
                            "type": "arrival",
                            "location": {
                                "lat": 50.912724,
                                "lng": 7.1055
                            },
                            "time": {
                                "start": "2023-09-20T19:58:35Z",
                                "end": "2023-09-20T19:58:35Z"
                            }
                        }
                    ],
                    "location": {
                        "lat": 50.912724,
                        "lng": 7.1055
                    },
                    "distance": 945823
                }
            ],
            "statistic": {
                "cost": 418.1166,
                "distance": 945823,
                "duration": 43115,
                "times": {
                    "driving": 32315,
                    "serving": 10800,
                    "waiting": 0,
                    "stopping": 0,
                    "break": 0
                }
            },
            "shiftIndex": 0
        }
    ]
}

Optimize vehicle use case

The objective optimizeTourCount controls the use of vehicles to optimize the number of tours in the solution.

In this case the depot is in between the two jobs to be delivered.

  • In this example, there are 2 identical vehicles with capacity 2 and no fixed cost, so whether you use one or two vehicles to deliver the job, only time and distance are taken into account.

  • If you use one vehicle, both time and duration will be higher. This is because you need to visit the first job, then visit the second job and only then come back to the depot.

You can do this with the objective optimizeTourCount using the action attributes maximize and minimize.

  • If action=maximize, both vehicles are used.
  • If action=minimize, then only one vehicle is used for both jobs.

Problem: Omit optimizeTourCount

This problem is expressed without using the optimizeTourCount objective.

Without specified objectives, as mentioned previously, optimizeTourCount is higher than minimizeCost. That means, by default, you will use the fewest vehicles possible, even if it will make the cost higher.

See the solution.

{
    "fleet": {
        "types": [
            {
                "profile": "vehicle",
                "amount": 2,
                "capacity": [
                    2
                ],
                "costs": {
                    "distance": 5,
                    "time": 5,
                    "fixed": 0
                },
                "id": "vehicle_1",
                "shifts": [
                    {
                        "start": {
                            "location": {
                                "lat": 52.55364,
                                "lng": 13.41467
                            },
                            "time": "2023-11-30T08:00:00+01:00"
                        }
                    }
                ]
            }
        ],
        "profiles": [
            {
                "name": "vehicle",
                "type": "car"
            }
        ]
    },
    "plan": {
        "jobs": [
            {
                "id": "Job_1",
                "tasks": {
                    "deliveries": [
                        {
                            "places": [
                                {
                                    "duration": 300,
                                    "location": {
                                        "lat": 52.55635,
                                        "lng": 13.38465
                                    }
                                }
                            ],
                            "demand": [
                                1
                            ]
                        }
                    ]
                }
            },
            {
                "id": "Job_2",
                "tasks": {
                    "deliveries": [
                        {
                            "places": [
                                {
                                    "duration": 300,
                                    "location": {
                                        "lat": 52.55162,
                                        "lng": 13.43017
                                    }
                                }
                            ],
                            "demand": [
                                1
                            ]
                        }
                    ]
                }
            }
        ]
    }
}

Solution: Omit optimizeTourCount

{
    "statistic": {
        "cost": 28475,
        "distance": 4521,
        "duration": 1174,
        "times": {
            "driving": 574,
            "serving": 600,
            "waiting": 0,
            "stopping": 0,
            "break": 0
        }
    },
    "tours": [
        {
            "vehicleId": "vehicle_1_2",
            "typeId": "vehicle_1",
            "stops": [
                {
                    "location": {
                        "lat": 52.55364,
                        "lng": 13.41467
                    },
                    "time": {
                        "arrival": "2023-11-30T07:00:00Z",
                        "departure": "2023-11-30T07:00:00Z"
                    },
                    "load": [
                        2
                    ],
                    "activities": [
                        {
                            "jobId": "departure",
                            "type": "departure",
                            "location": {
                                "lat": 52.55364,
                                "lng": 13.41467
                            },
                            "time": {
                                "start": "2023-11-30T07:00:00Z",
                                "end": "2023-11-30T07:00:00Z"
                            }
                        }
                    ],
                    "distance": 0
                },
                {
                    "location": {
                        "lat": 52.55162,
                        "lng": 13.43017
                    },
                    "time": {
                        "arrival": "2023-11-30T07:03:06Z",
                        "departure": "2023-11-30T07:08:06Z"
                    },
                    "load": [
                        1
                    ],
                    "activities": [
                        {
                            "jobId": "Job_2",
                            "type": "delivery",
                            "location": {
                                "lat": 52.55162,
                                "lng": 13.43017
                            },
                            "time": {
                                "start": "2023-11-30T07:03:06Z",
                                "end": "2023-11-30T07:08:06Z"
                            }
                        }
                    ],
                    "distance": 1280
                },
                {
                    "location": {
                        "lat": 52.55635,
                        "lng": 13.38465
                    },
                    "time": {
                        "arrival": "2023-11-30T07:14:34Z",
                        "departure": "2023-11-30T07:19:34Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "Job_1",
                            "type": "delivery",
                            "location": {
                                "lat": 52.55635,
                                "lng": 13.38465
                            },
                            "time": {
                                "start": "2023-11-30T07:14:34Z",
                                "end": "2023-11-30T07:19:34Z"
                            }
                        }
                    ],
                    "distance": 4521
                }
            ],
            "statistic": {
                "cost": 28475,
                "distance": 4521,
                "duration": 1174,
                "times": {
                    "driving": 574,
                    "serving": 600,
                    "waiting": 0,
                    "stopping": 0,
                    "break": 0
                }
            },
            "shiftIndex": 0
        }
    ]
}

Problem: Specify optimizeTourCount to use whole fleet

You can use objectives to change this behavior. If you set the objective to use the whole fleet, you achieve a cheaper solution. You use both vehicles, each of them starts at the depot, delivers only one job, and comes back to the depot. The vehicles use the shortest east-west routes.

📘

Note

Since more tours often incur higher cost, you should place the optimizeTourCount objective with "action": "maximize" above the minimizeCost objective so that it will not overwrite its effect.

See the solution.


{
    "objectives": [
        {
            "type": "minimizeUnassigned"
        },
        {
            "type": "optimizeTourCount",
            "action": "maximize"
        },
        {
            "type": "minimizeCost"
        }
    ],
    "fleet": {
        "types": [
            {
                "profile": "vehicle",
                "amount": 2,
                "capacity": [
                    2
                ],
                "costs": {
                    "distance": 5,
                    "time": 5,
                    "fixed": 0
                },
                "id": "vehicle_1",
                "shifts": [
                    {
                        "start": {
                            "location": {
                                "lat": 52.55364,
                                "lng": 13.41467
                            },
                            "time": "2023-11-30T08:00:00+01:00"
                        }
                    }
                ]
            }
        ],
        "profiles": [
            {
                "name": "vehicle",
                "type": "car"
            }
        ]
    },
    "plan": {
        "jobs": [
            {
                "id": "Job_1",
                "tasks": {
                    "deliveries": [
                        {
                            "places": [
                                {
                                    "duration": 300,
                                    
                                    "location": {
                                        "lat": 52.55635,
                                        "lng": 13.38465
                                    }
                                }
                            ],
                            "demand": [
                                1
                            ]
                        }
                    ]
                }
            },
            {
                "id": "Job_2",
                "tasks": {
                    "deliveries": [
                        {
                            "places": [
                                {
                                    "duration": 300,
                                    "location": {
                                        "lat": 52.55162,
                                        "lng": 13.43017
                                    }
                                }
                            ],
                            "demand": [
                                1
                            ]
                        }
                    ]
                }
            }
        ]
    }
}

Solution: Specify optimizeTourCount to use whole fleet

{
    "statistic": {
        "cost": 22315,
        "distance": 3421,
        "duration": 1042,
        "times": {
            "driving": 442,
            "serving": 600,
            "waiting": 0,
            "stopping": 0,
            "break": 0
        }
    },
    "tours": [
        {
            "vehicleId": "vehicle_1_2",
            "typeId": "vehicle_1",
            "stops": [
                {
                    "location": {
                        "lat": 52.55364,
                        "lng": 13.41467
                    },
                    "time": {
                        "arrival": "2023-11-30T07:00:00Z",
                        "departure": "2023-11-30T07:00:00Z"
                    },
                    "load": [
                        1
                    ],
                    "activities": [
                        {
                            "jobId": "departure",
                            "type": "departure",
                            "location": {
                                "lat": 52.55364,
                                "lng": 13.41467
                            },
                            "time": {
                                "start": "2023-11-30T07:00:00Z",
                                "end": "2023-11-30T07:00:00Z"
                            }
                        }
                    ],
                    "distance": 0
                },
                {
                    "location": {
                        "lat": 52.55162,
                        "lng": 13.43017
                    },
                    "time": {
                        "arrival": "2023-11-30T07:03:06Z",
                        "departure": "2023-11-30T07:08:06Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "Job_2",
                            "type": "delivery",
                            "location": {
                                "lat": 52.55162,
                                "lng": 13.43017
                            },
                            "time": {
                                "start": "2023-11-30T07:03:06Z",
                                "end": "2023-11-30T07:08:06Z"
                            }
                        }
                    ],
                    "distance": 1280
                }
            ],
            "statistic": {
                "cost": 8830,
                "distance": 1280,
                "duration": 486,
                "times": {
                    "driving": 186,
                    "serving": 300,
                    "waiting": 0,
                    "stopping": 0,
                    "break": 0
                }
            },
            "shiftIndex": 0
        },
        {
            "vehicleId": "vehicle_1_1",
            "typeId": "vehicle_1",
            "stops": [
                {
                    "location": {
                        "lat": 52.55364,
                        "lng": 13.41467
                    },
                    "time": {
                        "arrival": "2023-11-30T07:00:00Z",
                        "departure": "2023-11-30T07:00:00Z"
                    },
                    "load": [
                        1
                    ],
                    "activities": [
                        {
                            "jobId": "departure",
                            "type": "departure",
                            "location": {
                                "lat": 52.55364,
                                "lng": 13.41467
                            },
                            "time": {
                                "start": "2023-11-30T07:00:00Z",
                                "end": "2023-11-30T07:00:00Z"
                            }
                        }
                    ],
                    "distance": 0
                },
                {
                    "location": {
                        "lat": 52.55635,
                        "lng": 13.38465
                    },
                    "time": {
                        "arrival": "2023-11-30T07:04:16Z",
                        "departure": "2023-11-30T07:09:16Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "Job_1",
                            "type": "delivery",
                            "location": {
                                "lat": 52.55635,
                                "lng": 13.38465
                            },
                            "time": {
                                "start": "2023-11-30T07:04:16Z",
                                "end": "2023-11-30T07:09:16Z"
                            }
                        }
                    ],
                    "distance": 2141
                }
            ],
            "statistic": {
                "cost": 13485,
                "distance": 2141,
                "duration": 556,
                "times": {
                    "driving": 256,
                    "serving": 300,
                    "waiting": 0,
                    "stopping": 0,
                    "break": 0
                }
            },
            "shiftIndex": 0
        }
    ]
}

Problem: Specify optimizeTourCount to use fewest vehicles

This solution uses the fewest number of vehicles. minimizeCost often pushes to this solution.

If you use optimizeTourCount with "action": "minimize" explicitly, you will get the same solution as the default. In the majority of cases, fewer trips would lead to cost savings.

{
    "objectives": [
        {
            "type": "minimizeUnassigned"
        },
        {
            "type": "optimizeTourCount",
            "action": "minimize"
        },
        {
            "type": "minimizeCost"
        }
    ],
    "fleet": {
        "types": [
            {
                "profile": "vehicle",
                "amount": 2,
                "capacity": [
                    2
                ],
                "costs": {
                    "distance": 5,
                    "time": 5,
                    "fixed": 0
                },
                "id": "vehicle_1",
                "shifts": [
                    {
                        "start": {
                            "location": {
                                "lat": 52.55364,
                                "lng": 13.41467
                            },
                            "time": "2023-11-30T08:00:00+01:00"
                        }
                    }
                ]
            }
        ],
        "profiles": [
            {
                "name": "vehicle",
                "type": "car"
            }
        ]
    },
    "plan": {
        "jobs": [
            {
                "id": "Job_1",
                "tasks": {
                    "deliveries": [
                        {
                            "places": [
                                {
                                    "duration": 300,
                                    "location": {
                                        "lat": 52.55635,
                                        "lng": 13.38465
                                    }
                                }
                            ],
                            "demand": [
                                1
                            ]
                        }
                    ]
                }
            },
            {
                "id": "Job_2",
                "tasks": {
                    "deliveries": [
                        {
                            "places": [
                                {
                                    "duration": 300,
                                    "location": {
                                        "lat": 52.55162,
                                        "lng": 13.43017
                                    }
                                }
                            ],
                            "demand": [
                                1
                            ]
                        }
                    ]
                }
            }
        ]
    }
}

Solution: Specify optimizeTourCount to use fewest vehicles

{
    "statistic": {
        "cost": 28475,
        "distance": 4521,
        "duration": 1174,
        "times": {
            "driving": 574,
            "serving": 600,
            "waiting": 0,
            "stopping": 0,
            "break": 0
        }
    },
    "tours": [
        {
            "vehicleId": "vehicle_1_1",
            "typeId": "vehicle_1",
            "stops": [
                {
                    "location": {
                        "lat": 52.55364,
                        "lng": 13.41467
                    },
                    "time": {
                        "arrival": "2023-11-30T07:00:00Z",
                        "departure": "2023-11-30T07:00:00Z"
                    },
                    "load": [
                        2
                    ],
                    "activities": [
                        {
                            "jobId": "departure",
                            "type": "departure",
                            "location": {
                                "lat": 52.55364,
                                "lng": 13.41467
                            },
                            "time": {
                                "start": "2023-11-30T07:00:00Z",
                                "end": "2023-11-30T07:00:00Z"
                            }
                        }
                    ],
                    "distance": 0
                },
                {
                    "location": {
                        "lat": 52.55162,
                        "lng": 13.43017
                    },
                    "time": {
                        "arrival": "2023-11-30T07:03:06Z",
                        "departure": "2023-11-30T07:08:06Z"
                    },
                    "load": [
                        1
                    ],
                    "activities": [
                        {
                            "jobId": "Job_2",
                            "type": "delivery",
                            "location": {
                                "lat": 52.55162,
                                "lng": 13.43017
                            },
                            "time": {
                                "start": "2023-11-30T07:03:06Z",
                                "end": "2023-11-30T07:08:06Z"
                            }
                        }
                    ],
                    "distance": 1280
                },
                {
                    "location": {
                        "lat": 52.55635,
                        "lng": 13.38465
                    },
                    "time": {
                        "arrival": "2023-11-30T07:14:34Z",
                        "departure": "2023-11-30T07:19:34Z"
                    },
                    "load": [
                        0
                    ],
                    "activities": [
                        {
                            "jobId": "Job_1",
                            "type": "delivery",
                            "location": {
                                "lat": 52.55635,
                                "lng": 13.38465
                            },
                            "time": {
                                "start": "2023-11-30T07:14:34Z",
                                "end": "2023-11-30T07:19:34Z"
                            }
                        }
                    ],
                    "distance": 4521
                }
            ],
            "statistic": {
                "cost": 28475,
                "distance": 4521,
                "duration": 1174,
                "times": {
                    "driving": 574,
                    "serving": 600,
                    "waiting": 0,
                    "stopping": 0,
                    "break": 0
                }
            },
            "shiftIndex": 0
        }
    ]
}