Compatibility attributes¶
Info
This feature is configurable via .json input, without the need for code
customization and is available for both the Marketplace app and Platform. You
can find a list of all available features.
| Field name | Required | Data type | SI Unit | Defined on | Example | Configurable via defaults |
|---|---|---|---|---|---|---|
compatibility_attributes |
No | array of string |
NA | vehicle |
{"compatibility_attributes": ["foo", "bar"]} |
✅ |
compatibility_attributes |
No | array of string |
NA | stop |
{"compatibility_attributes": ["foo", "bar"]} |
✅ |
In vehicle routing problems stops can sometimes only be served by specific vehicles. E.g., some delivery items may need a cooling system to keep fresh or maybe larger items must be delivered on a truck and do not fit in a smaller vehicle.
The compatibility_attributes feature can be added to vehicles and stops to
specify characteristics of the vehicle and requirements of the stop. This is
done by specifying an array of string (list of attributes) for stops and
vehicles.
- Stops that have configured attributes are only compatible with vehicles that match at least one of them. The vehicle may have additional attributes that are not specified on the stop.
- If you want all attributes to be considered when matching, you can
concatenate them into a single
stringand specify that as the only element of thearray. Instead of having["A", "B", "C"]as the attributes, change them for["A,B,C"]. - Stops that do not have any specified attributes are compatible with any vehicle.
- Vehicles that do not have any specified attributes are only compatible with stops without attributes.
compatibility_attributes determine whether a vehicle is eligible to service a
stop and ultimately whether a given solution is feasible.
For each vehicle, add the relevant attributes to the compatibility_attributes
array, as needed. The string must be an exact match for the
relevant vehicles and stops; spelling or phrasing errors will prevent correct
attribute matching.
Here is an example input defining an assortment of stops and vehicles with or without compatibility attributes. A sample output obtained after solving the problem is also shown.
{
"defaults": {
"vehicles": {
"speed": 20
}
},
"stops": [
{
"id": "Fushimi Inari Taisha",
"location": { "lon": 135.772695, "lat": 34.967146 }
},
{
"id": "Kiyomizu-dera",
"location": { "lon": 135.78506, "lat": 34.994857 }
},
{
"id": "Nijō Castle",
"location": { "lon": 135.748134, "lat": 35.014239 },
"compatibility_attributes": ["level_1"]
},
{
"id": "Kyoto Imperial Palace",
"location": { "lon": 135.762057, "lat": 35.025431 },
"compatibility_attributes": ["level_1"]
},
{
"id": "Gionmachi",
"location": { "lon": 135.775682, "lat": 35.002457 },
"compatibility_attributes": ["level_2"]
},
{
"id": "Kinkaku-ji",
"location": { "lon": 135.728898, "lat": 35.039705 },
"compatibility_attributes": ["level_2"]
},
{
"id": "Arashiyama Bamboo Forest",
"location": { "lon": 135.672009, "lat": 35.017209 },
"compatibility_attributes": ["level_3"]
}
],
"vehicles": [
{
"id": "v1",
"start_location": { "lon": 135.772695, "lat": 34.967146 }
},
{
"id": "v2",
"compatibility_attributes": ["level_1"],
"start_location": { "lon": 135.762057, "lat": 35.025431 }
},
{
"id": "v3",
"compatibility_attributes": ["level_1", "level_2"],
"start_location": { "lon": 135.78506, "lat": 34.994857 }
},
{
"id": "v4",
"compatibility_attributes": ["level_3"]
}
]
}
{
"options": {
"check": {
"duration": 30000000000,
"verbosity": "off"
},
"format": {
"disable": {
"progression": true
}
},
"model": {
"constraints": {
"disable": {
"attributes": false,
"capacities": null,
"capacity": false,
"distance_limit": false,
"groups": false,
"maximum_duration": false,
"maximum_stops": false,
"maximum_wait_stop": false,
"maximum_wait_vehicle": false,
"mixing_items": false,
"precedence": false,
"start_time_windows": false,
"vehicle_end_time": false,
"vehicle_start_time": false
},
"enable": {
"cluster": false
}
},
"objectives": {
"capacities": "",
"cluster": 0,
"distance": 0,
"early_arrival_penalty": 1,
"late_arrival_penalty": 1,
"min_stops": 1,
"stop_balance": 0,
"travel_duration": 0,
"unplanned_penalty": 1,
"vehicle_activation_penalty": 1,
"vehicles_duration": 1
},
"properties": {
"disable": {
"duration_groups": false,
"durations": false,
"initial_solution": false,
"stop_duration_multipliers": false
},
"maximum_time_horizon": 15552000
},
"validate": {
"disable": {
"resources": false,
"start_time": false
},
"enable": {
"matrix": false,
"matrix_asymmetry_tolerance": 20
}
}
},
"solve": {
"duration": 10000000000,
"iterations": 50,
"parallel_runs": 1,
"plateau": {
"absolute_threshold": -1,
"delay": 0,
"duration": 0,
"iterations": 0,
"relative_threshold": 0
},
"run_deterministically": true,
"solver": {
"plan_group_size": {
"delta": 0,
"delta_after_iterations": 1000000000,
"max_value": 2,
"min_value": 2,
"snap_back_after_improvement": true,
"start_value": 2,
"zigzag": true
},
"unplan_units": {
"delta": 2,
"delta_after_iterations": 125,
"max_value": -1,
"min_value": 2,
"snap_back_after_improvement": true,
"start_value": 2,
"zigzag": true
},
"unplan_weights": "Vehicle:3,Island:1,Location:293"
},
"start_solutions": 1
}
},
"solutions": [
{
"objective": {
"name": "1 * vehicles_duration + 1 * unplanned_penalty",
"objectives": [
{
"base": 368.0821280755173,
"factor": 1,
"name": "vehicles_duration",
"value": 368.0821280755173
},
{
"factor": 1,
"name": "unplanned_penalty",
"value": 0
}
],
"value": 368.0821280755173
},
"unplanned": [],
"vehicles": [
{
"id": "v1",
"route": [
{
"cumulative_travel_duration": 0,
"stop": {
"id": "v1-start",
"location": {
"lat": 34.967146,
"lon": 135.772695
}
},
"travel_duration": 0
},
{
"cumulative_travel_duration": 0,
"stop": {
"id": "Fushimi Inari Taisha",
"location": {
"lat": 34.967146,
"lon": 135.772695
}
},
"travel_duration": 0
}
],
"route_duration": 0,
"route_travel_duration": 0
},
{
"id": "v2",
"route": [
{
"cumulative_travel_duration": 0,
"stop": {
"id": "v2-start",
"location": {
"lat": 35.025431,
"lon": 135.762057
}
},
"travel_duration": 0
},
{
"cumulative_travel_duration": 0,
"stop": {
"id": "Kyoto Imperial Palace",
"location": {
"lat": 35.025431,
"lon": 135.762057
}
},
"travel_duration": 0
}
],
"route_duration": 0,
"route_travel_duration": 0
},
{
"id": "v3",
"route": [
{
"cumulative_travel_duration": 0,
"stop": {
"id": "v3-start",
"location": {
"lat": 34.994857,
"lon": 135.78506
}
},
"travel_duration": 0
},
{
"cumulative_travel_duration": 0,
"stop": {
"id": "Kiyomizu-dera",
"location": {
"lat": 34.994857,
"lon": 135.78506
}
},
"travel_duration": 0
},
{
"cumulative_travel_distance": 1201,
"cumulative_travel_duration": 60,
"stop": {
"id": "Gionmachi",
"location": {
"lat": 35.002457,
"lon": 135.775682
}
},
"travel_distance": 1201,
"travel_duration": 60
},
{
"cumulative_travel_distance": 4031,
"cumulative_travel_duration": 201,
"stop": {
"id": "Nijō Castle",
"location": {
"lat": 35.014239,
"lon": 135.748134
}
},
"travel_distance": 2830,
"travel_duration": 141
},
{
"cumulative_travel_distance": 7360,
"cumulative_travel_duration": 368,
"stop": {
"id": "Kinkaku-ji",
"location": {
"lat": 35.039705,
"lon": 135.728898
}
},
"travel_distance": 3329,
"travel_duration": 166
}
],
"route_duration": 368,
"route_travel_distance": 7360,
"route_travel_duration": 368
},
{
"id": "v4",
"route": [
{
"cumulative_travel_duration": 0,
"stop": {
"id": "Arashiyama Bamboo Forest",
"location": {
"lat": 35.017209,
"lon": 135.672009
}
},
"travel_duration": 0
}
],
"route_duration": 0,
"route_travel_duration": 0
}
]
}
],
"statistics": {
"result": {
"custom": {
"activated_vehicles": 4,
"max_duration": 0.123,
"max_stops_in_vehicle": 4,
"max_travel_duration": 0.123,
"min_duration": 0.123,
"min_stops_in_vehicle": 1,
"min_travel_duration": 0.123,
"unplanned_stops": 0
},
"duration": 0.123,
"value": 0.123
},
"run": {
"duration": 0.123,
"iterations": 50
},
"schema": "v1"
},
"version": {
"sdk": "VERSION"
}
}