Server Data Construction and Result with Cost/Time Matrix¶
[9]:
import json
Accumulate Problem Data¶
[10]:
json_data = {}
Set Cost/Travel Time Matrix
We need to provide square matrices for cost/time matrices which have positive float values.
Cost matrices act as a cost of travel between one location to another. This cost can be accumulated over the result to find the best possible solution. By default, this cost is accumulated, and it can be disabled with the objective value set to 0.
The travel time matrix is used to evaluate time window constraints for vehicles and tasks. So if any kind of time related constraint is used, the Time Matrix is a must-have.
Multiple cost and travel time matrices can be provided for different vehicle types when cost and time differ between types (For example, CAR and BIKE).
[11]:
# Considering cost is half of travel time
# Car
car_cost_matrix = [
[0, 5, 4, 3, 5],
[5, 0, 6, 4, 3],
[4, 8, 0, 4, 2],
[1, 4, 3, 0, 4],
[3, 3, 5, 6, 0],
]
car_time_matrix = [
[ 0, 10, 8, 6, 10],
[10, 0, 12, 8, 6],
[ 8, 16, 0, 8, 4],
[ 2, 8, 6, 0, 8],
[ 6, 6, 10, 12, 0],
]
# 1 represents car type and 2 represents bike type
# Add cost matrix
json_data["cost_matrix_data"] = {
"data" : {
1:car_cost_matrix
}
}
# Add time matrix
json_data["travel_time_matrix_data"] = {
"data" : {
1:car_time_matrix
}
}
Set Fleet Data
Provide vehicle start and end locations along with vehicle features and capacity.
[12]:
fleet_data = {
"vehicle_locations": [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
"vehicle_ids": ["Car-A", "Car-B", "Car-C", "Car-D", "Car-E"],
"vehicle_types": [1, 1, 1, 1, 1],
"capacities": [[75, 75, 75, 75, 75]],
"vehicle_time_windows": [
[0, 100],
[0, 100],
[0, 100],
[0, 100],
[0, 100]
],
# Vehicle can take breaks in this time window as per break duration provided
"vehicle_break_time_windows":[
[
[20, 25],
[20, 25],
[20, 25],
[20, 25],
[20, 25]
]
],
"vehicle_break_durations": [[1, 1, 1, 1, 1]],
# Maximum cost a vehicle can incur while delivering
"vehicle_max_costs": [100, 100, 100, 100, 100],
# Maximum time a vehicle can be working
"vehicle_max_times": [120, 120, 120, 120, 120]
}
json_data["fleet_data"] = fleet_data
Set Task Data
Provide details on task locations, demand, and time window; there are other options as well.
[13]:
task_data = {
"task_locations": [1, 2, 3, 4],
"demand": [[30, 40, 40, 30]],
"task_time_windows": [
[3, 20],
[5, 30],
[1, 20],
[4, 40],
],
"service_times": [3, 1, 8, 4],
"prizes": [50, 50, 100, 50]
}
json_data["task_data"] = task_data
Set Solver Config
Larger problems might require more time.
[14]:
solver_config = {
"objectives": {
"cost": 1,
"travel_time": 1,
"prize": 2
}
}
json_data["solver_config"] = solver_config
Solve the Problem¶
cuOpt endpoints can be triggered as shown in the thin client example.
Use this data and invoke cuOpt endpoint, which would return routes.
If the response status is 0,
then cuOpt found a feasible solution, under dictionary solver_response
.
if status is 1,
then it found an infeasible solution by going over constraints. Warnings will list what constraints caused the infeasible solution, which can be analyzed further. Any other state indicating that cuOpt failed may be due to invalid data or some unhandled issue. This will be under dictionary solver_infeasible_response
.
{
'response': {
'solver_response': {
'status': 0,
'num_vehicles': 2,
'solution_cost': -407.0,
'vehicle_data': {
'Car-A': {
'task_id': ['Depot', '0', 'Break', '1', 'Depot'],
'arrival_stamp': [0.0, 10.0, 25.0, 26.0, 35.0],
'route': [0, 1, 2, 2, 0],
'type': ['Depot', 'Delivery', 'Break', 'Delivery', 'Depot']
},
'Car-B': {
'task_id': ['Depot', '2', 'Break', '3', 'Depot'],
'arrival_stamp': [6.0, 12.0, 20.0, 29.0, 39.0],
'route': [0, 3, 3, 4, 0],
'type': ['Depot', 'Delivery', 'Break', 'Delivery', 'Depot']
}
},
'dropped_tasks': {
'task_id': [],
'task_index': []
},
'msg': ''
},
'perf_times': None
},
'reqId': '13f4e591-525f-4f22-9f4d-4e3c81f9b0d7'
}
Solution cost is -407.0
, this is due to objective value being set for prize, which gets negated from other values.