Set minimum number of stops
The HERE Tour Planning API allows you to set a minimum number of stops for each vehicle in a tour. This ensures that the optimization algorithm includes at least a certain number of stops in each route to fill the vehicle's capacity. In logistics scenarios, this might result in improved tour efficiency and maximized vehicle capacity. For example, by setting the minimum number of stops, you might need fewer vehicles to serve the same number of stops, leading to savings in time, fuel, and vehicle wear and tear.
Note
This is an ALPHA feature, which means it is new or experimental and under active development. Alpha features are provided for testing and feedback purposes. They may change significantly or might not become generally available.
For more information, see Explore experimental features.
Understand the minimum stops configuration
In the HERE Tour Planning API, you can use the minCount object, within the fleet.types.limits.stops problem configuration to define a minimum number of stops in a tour needed by vehicles in a specific fleet.
In the context of the minimum stops functionality, a 'stop' in a tour denotes a location where one or more pickup or delivery activities occur. For the optimization algorithm to consider a group of activities as a single stop, each activity specified within it must be configured for the same location. Otherwise, the algorithm might treat such activities as separate stops within the parameters of the minimum stops functionality.
Note
This is an experimental feature in development. To enable this feature, add
minStopstoexperimentalFeaturesarray in the problem specification.For more information, see:
The following snippet provides a sample configuration for a minimum number of 10 stops within the limits object:
// JSON shortened for brevity, showcasing the limits object.
"limits": {
"stops": {
"minCount": {
"value": 10
}
}
}Use case: Cost-efficient transportation for fleets with different vehicle types
Consider a use case where a fleet comprises one large truck and five smaller vans, which are more cost-effective compared to the truck. The truck has a minimum stop limit of 10 to maximize cost efficiency. Therefore, if there are fewer orders and the stop limit hasn't been met, the vans can be utilized instead of the truck.
Problem
See the following problem JSON that reflects the sample use case:
Click to expand/collapse the sample JSON
{
"configuration": {
"experimentalFeatures": [
"minStops"
]
},
"fleet": {
"types": [
{
"id": "van",
"profile": "car",
"costs": {
"fixed": 10,
"distance": 0.005,
"time": 0.005
},
"shifts": [
{
"start": {
"time": "2023-05-28T05:30:00Z",
"location": {
"lat": 53.586203,
"lng": 14.821028
}
},
"end": {
"time": "2023-05-28T18:00:00Z",
"location": {
"lat": 53.586203,
"lng": 14.821028
}
}
}
],
"capacity": [
300
],
"amount": 5
},
{
"id": "truck",
"profile": "truck",
"costs": {
"fixed": 40,
"distance": 0.007,
"time": 0.007
},
"shifts": [
{
"start": {
"time": "2023-05-28T05:30:00Z",
"location": {
"lat": 53.586203,
"lng": 14.821028
}
},
"end": {
"time": "2023-05-28T18:00:00Z",
"location": {
"lat": 53.586203,
"lng": 14.821028
}
}
}
],
"capacity": [
600
],
"amount": 1,
"limits": {
"stops": {
"minCount": {
"value": 10
}
}
}
}
],
"profiles": [
{
"type": "car",
"name": "car"
},
{
"type": "truck",
"name": "truck"
}
]
},
"plan": {
"jobs": [
{
"id": "Job_1_pickup",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 53.653166,
"lng": 14.629095
},
"duration": 600
}
],
"demand": [
100
]
}
]
}
},
{
"id": "Job_2_pickup",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 53.819048,
"lng": 14.755096
},
"duration": 600
}
],
"demand": [
100
]
}
]
}
},
{
"id": "Job_3_pickup",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 53.830118,
"lng": 14.629969
},
"duration": 600
}
],
"demand": [
100
]
}
]
}
},
{
"id": "Job_4_pickup",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 53.383915,
"lng": 14.710449
},
"duration": 600
}
],
"demand": [
100
]
}
]
}
},
{
"id": "Job_5_pickup",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 53.35405,
"lng": 14.799069
},
"duration": 600
}
],
"demand": [
100
]
}
]
}
},
{
"id": "Job_6_pickup",
"tasks": {
"pickups": [
{
"places": [
{
"location": {
"lat": 53.367761,
"lng": 15.066569
},
"duration": 600
}
],
"demand": [
100
]
}
]
}
}
]
}
}In this sample problem, the fleet comprises of the following vehicle types:
| truck | van | |
|---|---|---|
Profile | truck | car |
Quantity | 1 vehicle | 5 vehicles |
Fixed cost | 40 | 10 |
Capacity | 600 | 300 |
Min stops | 10 | no limit |
The tour plan consists of six pickup jobs, each with the demand value set to 100.
Solution
The solution to the problem demonstrates how setting the minimum number of stops prioritizes cost-effectiveness and tour efficiency.
Click to expand/collapse the sample JSON
{
"statistic": {
"cost": 1127.48,
"distance": 207835,
"duration": 13661,
"times": {
"driving": 10061,
"serving": 3600,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "van_1",
"typeId": "van",
"stops": [
{
"time": {
"arrival": "2023-05-28T05:30:00Z",
"departure": "2023-05-28T05:30:00Z"
},
"load": [
0
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 53.586203,
"lng": 14.821028
},
"time": {
"start": "2023-05-28T05:30:00Z",
"end": "2023-05-28T05:30:00Z"
}
}
],
"location": {
"lat": 53.586203,
"lng": 14.821028
},
"distance": 0
},
{
"time": {
"arrival": "2023-05-28T05:53:16Z",
"departure": "2023-05-28T06:03:16Z"
},
"load": [
100
],
"activities": [
{
"jobId": "Job_2_pickup",
"type": "pickup",
"location": {
"lat": 53.819048,
"lng": 14.755096
},
"time": {
"start": "2023-05-28T05:53:16Z",
"end": "2023-05-28T06:03:16Z"
}
}
],
"location": {
"lat": 53.819048,
"lng": 14.755096
},
"distance": 35175
},
{
"time": {
"arrival": "2023-05-28T06:17:09Z",
"departure": "2023-05-28T06:27:09Z"
},
"load": [
200
],
"activities": [
{
"jobId": "Job_3_pickup",
"type": "pickup",
"location": {
"lat": 53.830118,
"lng": 14.629969
},
"time": {
"start": "2023-05-28T06:17:09Z",
"end": "2023-05-28T06:27:09Z"
}
}
],
"location": {
"lat": 53.830118,
"lng": 14.629969
},
"distance": 48442
},
{
"time": {
"arrival": "2023-05-28T06:45:28Z",
"departure": "2023-05-28T06:55:28Z"
},
"load": [
300
],
"activities": [
{
"jobId": "Job_1_pickup",
"type": "pickup",
"location": {
"lat": 53.653166,
"lng": 14.629095
},
"time": {
"start": "2023-05-28T06:45:28Z",
"end": "2023-05-28T06:55:28Z"
}
}
],
"location": {
"lat": 53.653166,
"lng": 14.629095
},
"distance": 71410
},
{
"time": {
"arrival": "2023-05-28T07:13:06Z",
"departure": "2023-05-28T07:13:06Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 53.586203,
"lng": 14.821028
},
"time": {
"start": "2023-05-28T07:13:06Z",
"end": "2023-05-28T07:13:06Z"
}
}
],
"location": {
"lat": 53.586203,
"lng": 14.821028
},
"distance": 92386
}
],
"statistic": {
"cost": 502.86,
"distance": 92386,
"duration": 6186,
"times": {
"driving": 4386,
"serving": 1800,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
},
{
"vehicleId": "van_4",
"typeId": "van",
"stops": [
{
"time": {
"arrival": "2023-05-28T05:30:00Z",
"departure": "2023-05-28T05:30:00Z"
},
"load": [
0
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 53.586203,
"lng": 14.821028
},
"time": {
"start": "2023-05-28T05:30:00Z",
"end": "2023-05-28T05:30:00Z"
}
}
],
"location": {
"lat": 53.586203,
"lng": 14.821028
},
"distance": 0
},
{
"time": {
"arrival": "2023-05-28T06:02:53Z",
"departure": "2023-05-28T06:12:53Z"
},
"load": [
100
],
"activities": [
{
"jobId": "Job_6_pickup",
"type": "pickup",
"location": {
"lat": 53.367761,
"lng": 15.066569
},
"time": {
"start": "2023-05-28T06:02:53Z",
"end": "2023-05-28T06:12:53Z"
}
}
],
"location": {
"lat": 53.367761,
"lng": 15.066569
},
"distance": 39176
},
{
"time": {
"arrival": "2023-05-28T06:39:46Z",
"departure": "2023-05-28T06:49:46Z"
},
"load": [
200
],
"activities": [
{
"jobId": "Job_5_pickup",
"type": "pickup",
"location": {
"lat": 53.35405,
"lng": 14.799069
},
"time": {
"start": "2023-05-28T06:39:46Z",
"end": "2023-05-28T06:49:46Z"
}
}
],
"location": {
"lat": 53.35405,
"lng": 14.799069
},
"distance": 68995
},
{
"time": {
"arrival": "2023-05-28T07:04:19Z",
"departure": "2023-05-28T07:14:19Z"
},
"load": [
300
],
"activities": [
{
"jobId": "Job_4_pickup",
"type": "pickup",
"location": {
"lat": 53.383915,
"lng": 14.710449
},
"time": {
"start": "2023-05-28T07:04:19Z",
"end": "2023-05-28T07:14:19Z"
}
}
],
"location": {
"lat": 53.383915,
"lng": 14.710449
},
"distance": 85519
},
{
"time": {
"arrival": "2023-05-28T07:34:35Z",
"departure": "2023-05-28T07:34:35Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 53.586203,
"lng": 14.821028
},
"time": {
"start": "2023-05-28T07:34:35Z",
"end": "2023-05-28T07:34:35Z"
}
}
],
"location": {
"lat": 53.586203,
"lng": 14.821028
},
"distance": 115449
}
],
"statistic": {
"cost": 624.62,
"distance": 115449,
"duration": 7475,
"times": {
"driving": 5675,
"serving": 1800,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}The following figure provides the solution visualization:
Conclusions
By utilizing the minimum stops functionality within the given context, the optimization algorithm ensured that the truck vehicle would be selected only when it proved cost-efficient to do so. However, as is evident in the solution, the optimization algorithm did not select the truck vehicle. Instead, it opted for smaller and less expensive van vehicles, which operated more efficiently to fulfill the planned jobs at full capacity. This configuration ultimately fosters cost savings and tour efficiency by optimizing vehicle selection and capacity utilization.
Next steps
- For more information about formulating problems in the HERE Tour Planning API, see Problem.
- For an in-depth exploration of the HERE Tour Planning API methods, endpoints, and parameters, see the API Reference.
- To explore other limit types, see Set route limits.
Updated 28 days ago