%diff -u --color main.py cvrptw_pd.py
--- main.py 2024-07-04 16:11:07.524848863 +0200
+++ cvrptw_pd.py 2024-07-04 16:10:16.518365568 +0200
@@ -17,8 +17,12 @@
"""
import numpy as np
-from ortools.constraint_solver import routing_enums_pb2
-from ortools.constraint_solver import pywrapcp
+from ortools.routing import enums_pb2
+from ortools.routing import pywraprouting
+
+FirstSolutionStrategy = enums_pb2.FirstSolutionStrategy
+LocalSearchMetaheuristic = enums_pb2.LocalSearchMetaheuristic
+RoutingSearchStatus = enums_pb2.RoutingSearchStatus
def create_data_model():
@@ -86,47 +90,89 @@
return data
-def print_solution(data, manager, routing, solution):
+def print_solution(manager, routing, solution):
"""Prints solution on console."""
+ status = routing.status()
+ print(f"Status: {RoutingSearchStatus.Value.Name(status)}")
+ if (
+ status != RoutingSearchStatus.ROUTING_OPTIMAL
+ and status != RoutingSearchStatus.ROUTING_SUCCESS
+ ):
+ print("No solution found!")
+ return
print(f"Objective: {solution.ObjectiveValue()}")
+ # Display dropped nodes.
+ dropped_nodes = "Dropped nodes:"
+ for node in range(routing.Size()):
+ if routing.IsStart(node) or routing.IsEnd(node):
+ continue
+ if solution.Value(routing.NextVar(node)) == node:
+ dropped_nodes += f" {manager.IndexToNode(node)}"
+ print(dropped_nodes)
+ # Display routes.
+ time_dimension = routing.GetDimensionOrDie("Time")
+ capacity_dimension = routing.GetDimensionOrDie("Capacity")
total_distance = 0
- for vehicle_id in range(data["num_vehicles"]):
- nodes_visited = [] # To Keep Track of Vehicles Visited by Vehicle
+ total_time = 0
+ total_load = 0
+ for vehicle_id in range(manager.GetNumberOfVehicles()):
+ nodes_visited = [] # To Keep Track of Node Visited by Vehicle
index = routing.Start(vehicle_id)
plan_output = f"Route for vehicle {vehicle_id}:\n"
route_distance = 0
nodes_visited.append(manager.IndexToNode(index))
while not routing.IsEnd(index):
- node = manager.IndexToNode(index)
- plan_output += f" {node} -> "
+ time_var = time_dimension.CumulVar(index)
+ capacity_var = capacity_dimension.CumulVar(index)
+ plan_output += (
+ f"Node_{manager.IndexToNode(index)}"
+ f" {route_distance}m"
+ f" TW:[{time_var.Min()},{time_var.Max()}]"
+ f" Time({solution.Min(time_var)},{solution.Max(time_var)})"
+ f" Load({solution.Value(capacity_var)}/{capacity_var.Max()})"
+ " -> "
+ )
previous_index = index
index = solution.Value(routing.NextVar(index))
nodes_visited.append(manager.IndexToNode(index))
route_distance += routing.GetArcCostForVehicle(
previous_index, index, vehicle_id
)
- if (
- len(nodes_visited) > 2
- ): # Condition does not prints vehicels that are not assigned
- plan_output += f"{manager.IndexToNode(index)}\n"
+ if len(nodes_visited) > 2: # Condition does not prints vehicels that are not assigned
+ time_var = time_dimension.CumulVar(index)
+ capacity_var = capacity_dimension.CumulVar(index)
+ plan_output += (
+ f"Node_{manager.IndexToNode(index)}"
+ f" {route_distance}m"
+ f" Time({solution.Min(time_var)},{solution.Max(time_var)})"
+ f" Load({solution.Value(capacity_var)}/{capacity_var.Max()})"
+ "\n"
+ )
plan_output += f"Distance of the route: {route_distance}m\n"
+ plan_output += f"Time of the route: {solution.Min(time_var)}min\n"
+ plan_output += f"Load of the route: {solution.Value(capacity_var)}\n"
print(plan_output)
total_distance += route_distance
+ total_time += solution.Min(time_var)
+ total_load += solution.Value(capacity_var)
print(nodes_visited)
+ print(f"Total distance of all routes: {total_distance}m")
+ print(f"Total time of all routes: {total_time}min")
+ print(f"Total load of all routes: {total_load}")
# print(f"Total Distance of all routes: {total_distance}m")
def main():
data = create_data_model()
- manager = pywrapcp.RoutingIndexManager(
+ manager = pywraprouting.RoutingIndexManager(
data["num_Locations"], data["num_vehicles"], data["depot"]
)
- routing = pywrapcp.RoutingModel(manager)
+ routing = pywraprouting.RoutingModel(manager)
def distance_callback(from_index, to_index):
from_node = manager.IndexToNode(from_index)
- to_node = manager.IndexToNode(to_node)
+ to_node = manager.IndexToNode(to_index)
if from_node in range(data["duplicate_nodes"], data["num_Locations"]):
from_node = 0
if to_node in range(data["duplicate_nodes"], data["num_Locations"]):
@@ -148,9 +194,6 @@
)
capacity_dimension = routing.GetDimensionOrDie(capacity)
- for node in range(data["num_Locations"]):
- routing.AddDisjunction([manager.NodeToIndex(node)], 100)
-
def time_callback(from_index, to_index):
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
@@ -165,8 +208,8 @@
time_dim = "Time"
routing.AddDimension(
time_callback_index,
- 300,
- 100000000000, # Some Big Number so that Model should not limit itself.
+ 300_000,
+ 100_000_000_000, # Some Big Number so that Model should not limit itself.
False,
time_dim,
)
@@ -214,24 +257,20 @@
# Consraint End-----------
routing.AddPickupAndDelivery(pickup_index, delivery_index)
- search_parameters = pywrapcp.DefaultRoutingSearchParameters()
+ routing.AddDisjunction([pickup_index, delivery_index], 20_000, 2)
+
+ search_parameters = pywraprouting.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
- routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION
+ FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION
)
search_parameters.local_search_metaheuristic = (
- routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
+ LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
)
- search_parameters.time_limit.seconds = 30
+ search_parameters.time_limit.FromSeconds(3)
# search_parameters.log_search = True
solution = routing.SolveWithParameters(search_parameters)
-
- if solution:
- print("Solution Found")
- print_solution(data, manager, routing, solution)
-
- else:
- print("NO SOLUTION")
+ print_solution(manager, routing, solution)
if __name__ == "__main__":
Last active
July 4, 2024 14:14
-
-
Save Mizux/36a87040af87eb9c5324d49224f709ac to your computer and use it in GitHub Desktop.
CVRPTW_PD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
"""Development In Progress | |
CVRPTW. | |
or-tools == 9.9.3963 | |
python == 3.11.7 | |
Number of Regular Nodes = 16, | |
Depot Nodes = 1 | |
Number of Nodes Duplicated = 16(Same as Number of Regular Nodes) | |
Total Nodes = 16+16+1 = 33 | |
Demnds = 0 for Depot, 1 for Regular Nodes and -1 for Duplicate Nodes. | |
Time Windwos = Applied Business Logic for Regular Nodes and Whole Day for Duplicate Nodes. | |
pickup_dropoff = Regular Node Index, len(data)+Regular Node Index | |
""" | |
import numpy as np | |
from ortools.routing import enums_pb2 | |
from ortools.routing import pywraprouting | |
FirstSolutionStrategy = enums_pb2.FirstSolutionStrategy | |
LocalSearchMetaheuristic = enums_pb2.LocalSearchMetaheuristic | |
RoutingSearchStatus = enums_pb2.RoutingSearchStatus | |
def create_data_model(): | |
data = {} | |
num_depots = 1 | |
patient_len = 16 | |
vehicle_capacity = 3 | |
data["num_Locations"] = 2 * patient_len + num_depots | |
# fmt:off | |
# data['demands'] = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3] | |
# for the Demands Tried adding Vehicle_Capacity(-3) instead of -1, Vehicle Didnt Visit Any Nodes. But adding -1 yielded result | |
data['demands']=[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1] | |
data['time_windows']=[(0, 86400), (23400, 25200), (23400, 25200), (23400, 25200), (23400, 25200), (23400, 25200), (28800, 28800), (28800, 28800), (32400, 32400), (32400, 32400), (36000, 36000), (36000, 36000), (36000, 36000), (39600, 39600), (39600, 39600), (43200, 43200), (43200, 43200), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400), (0, 86400)] | |
data['num_vehicles']= 40 | |
data['vehicle_capacity'] = [vehicle_capacity for _ in range(data['num_vehicles'])] | |
data['depot']=0 | |
data['pickup_dropoff']=[(1, 17), (2, 18), (3, 19), (4, 20), (5, 21), (6, 22), (7, 23), (8, 24), (9, 25), (10, 26), (11, 27), (12, 28), (13, 29), (14, 30), (15, 31), (16, 32)] | |
data['duplicate_nodes']=patient_len+1 # INdex of Start of Duplicate Node | |
data['distance_matrix'] = [ | |
[ 0 ,18432 , 8219 , 7741 ,21036 ,11099 ,28697 ,21912 ,31279 ,39777 ,35803 , 8667 ,71688 ,12592 ,11929 ,21985 ,18432 ], | |
[17866 , 0 ,10701 ,16151 ,21228 ,29756 ,25445 ,22105 ,31472 ,36525 ,48423 ,10499 ,68436 ,14823 ,14225 ,12439 , 0 ], | |
[ 8084 ,10986 , 0 , 6369 ,13032 ,19974 ,21474 ,13909 ,23623 ,32555 ,38641 , 1221 ,64465 , 4799 , 4140 ,14762 ,10986 ], | |
[ 7268 ,16304 , 6090 , 0 ,18907 ,19158 ,26568 ,19783 ,31148 ,37649 ,32296 , 6538 ,69559 ,10463 , 9800 ,19856 ,16304 ], | |
[19622 ,21970 ,12496 ,17908 , 0 ,31512 ,13404 , 4291 ,13905 ,26053 ,37574 ,11758 ,56084 , 8945 , 9289 ,18362 ,21970 ], | |
[11208 ,30040 ,19827 ,19349 ,32644 , 0 ,40305 ,33520 ,42887 ,51385 ,47721 ,20275 ,83296 ,24200 ,23536 ,33593 ,30040 ], | |
[28383 ,26104 ,21364 ,26669 ,15291 ,40273 , 0 ,13247 ,15930 ,14162 ,46324 ,20465 ,46072 ,21785 ,22129 ,15111 ,26104 ], | |
[20790 ,23138 ,13664 ,19075 , 4208 ,32680 ,11417 , 0 ,10501 ,24831 ,37917 ,12926 ,54862 ,10113 ,10457 ,20970 ,23138 ], | |
[31108 ,33154 ,23981 ,29142 ,14263 ,42997 ,17630 ,11016 , 0 ,24328 ,31712 ,23243 ,50310 ,19040 ,19699 ,28100 ,33154 ], | |
[39053 ,36774 ,32034 ,37339 ,26278 ,50943 ,12623 ,24234 ,25334 , 0 ,69610 ,31135 ,32389 ,36012 ,35353 ,25781 ,36774 ], | |
[37147 ,49357 ,39144 ,31154 ,39309 ,45936 ,47054 ,38162 ,32604 ,57812 , 0 ,39592 ,87181 ,43516 ,42853 ,52910 ,49357 ], | |
[ 8344 ,10812 , 1179 , 6629 ,12035 ,20234 ,20257 ,12911 ,22229 ,31337 ,38901 , 0 ,63248 , 5003 , 4344 ,13545 ,10812 ], | |
[70605 ,68325 ,63585 ,68890 ,54839 ,82495 ,43646 ,52795 ,49929 ,26387 ,80816 ,62687 , 0 ,61333 ,61677 ,57333 ,68325 ], | |
[12370 ,14944 , 4734 ,10655 , 8988 ,24259 ,24531 , 9864 ,18076 ,35611 ,42926 , 4653 ,62123 , 0 , 658 ,17819 ,14944 ], | |
[11711 ,14285 , 4075 , 9996 , 9332 ,23600 ,23872 ,10208 ,18734 ,34952 ,42267 , 3994 ,62467 , 658 , 0 ,17160 ,14285 ], | |
[21792 ,12856 ,14773 ,20077 ,19004 ,33682 ,15385 ,19880 ,26223 ,26465 ,52349 ,13874 ,58376 ,18750 ,18091 , 0 ,12856 ], | |
[17866 , 0 ,10701 ,16151 ,21228 ,29756 ,25445 ,22105 ,31472 ,36525 ,48423 ,10499 ,68436 ,14823 ,14225 ,12439 , 0 ], | |
] | |
data['duration_matrix']=[ | |
[ 0 , 1468 , 564 , 528 , 1535 , 864 , 1797 , 1630 , 2442 , 2552 , 1737 , 614 , 3806 , 916 , 870 , 1501 , 1468 ], | |
[1391 , 0 , 939 , 1229 , 1685 , 2157 , 1949 , 1781 , 2592 , 2704 , 2610 , 921 , 3958 , 1194 , 1167 , 1167 , 0 ], | |
[ 612 , 1026 , 0 , 450 , 1165 , 1378 , 1475 , 1260 , 2017 , 2230 , 1832 , 173 , 3485 , 445 , 388 , 1180 , 1026 ], | |
[ 515 , 1306 , 402 , 0 , 1373 , 1282 , 1635 , 1468 , 2238 , 2390 , 1506 , 452 , 3644 , 755 , 708 , 1339 , 1306 ], | |
[1488 , 1699 , 1077 , 1327 , 0 , 2255 , 1216 , 450 , 1297 , 1998 , 2616 , 968 , 2941 , 895 , 929 , 1470 , 1699 ], | |
[ 801 , 2204 , 1301 , 1265 , 2272 , 0 , 2533 , 2367 , 3178 , 3288 , 2511 , 1351 , 4542 , 1653 , 1607 , 2238 , 2204 ], | |
[1805 , 1968 , 1438 , 1644 , 1069 , 2572 , 0 , 958 , 1318 , 1113 , 2858 , 1318 , 2368 , 1572 , 1607 , 1051 , 1968 ], | |
[1620 , 1831 , 1208 , 1458 , 445 , 2386 , 1062 , 0 , 1060 , 1879 , 2512 , 1100 , 2821 , 1026 , 1061 , 1557 , 1831 ], | |
[2427 , 2680 , 2015 , 2189 , 1345 , 3194 , 1433 , 1097 , 0 , 2052 , 2065 , 1907 , 2937 , 1802 , 1860 , 2218 , 2680 ], | |
[2549 , 2712 , 2182 , 2387 , 1980 , 3315 , 1130 , 1869 , 1986 , 0 , 3769 , 2062 , 1751 , 2421 , 2363 , 1794 , 2712 ], | |
[1906 , 2784 , 1880 , 1494 , 2655 , 2516 , 3025 , 2534 , 2047 , 3862 , 0 , 1930 , 4808 , 2233 , 2186 , 2817 , 2784 ], | |
[ 617 , 989 , 165 , 456 , 1059 , 1384 , 1308 , 1154 , 1937 , 2063 , 1837 , 0 , 3317 , 451 , 393 , 1012 , 989 ], | |
[3862 , 4024 , 3495 , 3700 , 2895 , 4628 , 2432 , 2784 , 2858 , 1643 , 4725 , 3375 , 0 , 3397 , 3432 , 3107 , 4024 ], | |
[ 913 , 1297 , 428 , 751 , 922 , 1679 , 1684 , 1017 , 1752 , 2439 , 2132 , 431 , 3435 , 0 , 57 , 1388 , 1297 ], | |
[ 855 , 1240 , 371 , 693 , 957 , 1622 , 1626 , 1052 , 1810 , 2381 , 2075 , 374 , 3470 , 57 , 0 , 1331 , 1240 ], | |
[1488 , 1267 , 1120 , 1326 , 1529 , 2254 , 1121 , 1624 , 2266 , 1876 , 2707 , 1000 , 3130 , 1360 , 1302 , 0 , 1267 ], | |
[1391 , 0 , 939 , 1229 , 1685 , 2157 , 1949 , 1781 , 2592 , 2704 , 2610 , 921 , 3958 , 1194 , 1167 , 1167 , 0 ], | |
] | |
# fmt:off | |
assert data['num_Locations']==len(data['time_windows']) | |
assert len(data['distance_matrix'])*2-1 == data['num_Locations'] | |
assert len(data['duration_matrix'])*2-1 == data['num_Locations'] | |
assert data['num_Locations']==len(data['demands']) | |
return data | |
def print_solution(manager, routing, solution): | |
"""Prints solution on console.""" | |
status = routing.status() | |
print(f"Status: {RoutingSearchStatus.Value.Name(status)}") | |
if ( | |
status != RoutingSearchStatus.ROUTING_OPTIMAL | |
and status != RoutingSearchStatus.ROUTING_SUCCESS | |
): | |
print("No solution found!") | |
return | |
print(f"Objective: {solution.ObjectiveValue()}") | |
# Display dropped nodes. | |
dropped_nodes = "Dropped nodes:" | |
for node in range(routing.Size()): | |
if routing.IsStart(node) or routing.IsEnd(node): | |
continue | |
if solution.Value(routing.NextVar(node)) == node: | |
dropped_nodes += f" {manager.IndexToNode(node)}" | |
print(dropped_nodes) | |
# Display routes. | |
time_dimension = routing.GetDimensionOrDie("Time") | |
capacity_dimension = routing.GetDimensionOrDie("Capacity") | |
total_distance = 0 | |
total_time = 0 | |
total_load = 0 | |
for vehicle_id in range(manager.GetNumberOfVehicles()): | |
nodes_visited = [] # To Keep Track of Node Visited by Vehicle | |
index = routing.Start(vehicle_id) | |
plan_output = f"Route for vehicle {vehicle_id}:\n" | |
route_distance = 0 | |
nodes_visited.append(manager.IndexToNode(index)) | |
while not routing.IsEnd(index): | |
time_var = time_dimension.CumulVar(index) | |
capacity_var = capacity_dimension.CumulVar(index) | |
plan_output += ( | |
f"Node_{manager.IndexToNode(index)}" | |
f" {route_distance}m" | |
f" TW:[{time_var.Min()},{time_var.Max()}]" | |
f" Time({solution.Min(time_var)},{solution.Max(time_var)})" | |
f" Load({solution.Value(capacity_var)}/{capacity_var.Max()})" | |
" -> " | |
) | |
previous_index = index | |
index = solution.Value(routing.NextVar(index)) | |
nodes_visited.append(manager.IndexToNode(index)) | |
route_distance += routing.GetArcCostForVehicle( | |
previous_index, index, vehicle_id | |
) | |
if len(nodes_visited) > 2: # Condition does not prints vehicels that are not assigned | |
time_var = time_dimension.CumulVar(index) | |
capacity_var = capacity_dimension.CumulVar(index) | |
plan_output += ( | |
f"Node_{manager.IndexToNode(index)}" | |
f" {route_distance}m" | |
f" Time({solution.Min(time_var)},{solution.Max(time_var)})" | |
f" Load({solution.Value(capacity_var)}/{capacity_var.Max()})" | |
"\n" | |
) | |
plan_output += f"Distance of the route: {route_distance}m\n" | |
plan_output += f"Time of the route: {solution.Min(time_var)}min\n" | |
plan_output += f"Load of the route: {solution.Value(capacity_var)}\n" | |
print(plan_output) | |
total_distance += route_distance | |
total_time += solution.Min(time_var) | |
total_load += solution.Value(capacity_var) | |
print(nodes_visited) | |
print(f"Total distance of all routes: {total_distance}m") | |
print(f"Total time of all routes: {total_time}min") | |
print(f"Total load of all routes: {total_load}") | |
# print(f"Total Distance of all routes: {total_distance}m") | |
def main(): | |
data = create_data_model() | |
manager = pywraprouting.RoutingIndexManager( | |
data["num_Locations"], data["num_vehicles"], data["depot"] | |
) | |
routing = pywraprouting.RoutingModel(manager) | |
def distance_callback(from_index, to_index): | |
from_node = manager.IndexToNode(from_index) | |
to_node = manager.IndexToNode(to_index) | |
if from_node in range(data["duplicate_nodes"], data["num_Locations"]): | |
from_node = 0 | |
if to_node in range(data["duplicate_nodes"], data["num_Locations"]): | |
to_node = 0 | |
return data["distance_matrix"][from_node][to_node] | |
data_callback_index = routing.RegisterTransitCallback(distance_callback) | |
routing.SetArcCostEvaluatorOfAllVehicles(data_callback_index) | |
def demand_callback(from_index): | |
from_node = manager.IndexToNode(from_index) | |
return data["demands"][from_node] | |
demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback) | |
capacity = "Capacity" | |
routing.AddDimensionWithVehicleCapacity( | |
demand_callback_index, 0, data["vehicle_capacity"], True, capacity | |
) | |
capacity_dimension = routing.GetDimensionOrDie(capacity) | |
def time_callback(from_index, to_index): | |
from_node = manager.IndexToNode(from_index) | |
to_node = manager.IndexToNode(to_index) | |
if from_node in range(data["duplicate_nodes"], data["num_Locations"]): | |
from_node = 0 | |
if to_node in range(data["duplicate_nodes"], data["num_Locations"]): | |
to_node = 0 | |
return data["duration_matrix"][from_node][to_node] | |
time_callback_index = routing.RegisterTransitCallback(time_callback) | |
time_dim = "Time" | |
routing.AddDimension( | |
time_callback_index, | |
300_000, | |
100_000_000_000, # Some Big Number so that Model should not limit itself. | |
False, | |
time_dim, | |
) | |
time_dimension = routing.GetDimensionOrDie(time_dim) | |
for location_idx, time_window in enumerate(data["time_windows"]): | |
if location_idx == 0: | |
continue | |
index = manager.NodeToIndex(location_idx) | |
time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1]) | |
routing.AddToAssignment(time_dimension.SlackVar(index)) | |
for vehicle_id in range(data["num_vehicles"]): | |
index = routing.Start(vehicle_id) | |
time_dimension.CumulVar(index).SetRange( | |
data["time_windows"][0][0], data["time_windows"][0][1] | |
) | |
routing.AddToAssignment(time_dimension.SlackVar(index)) | |
for i in range(data["num_vehicles"]): | |
routing.AddVariableMinimizedByFinalizer( | |
time_dimension.CumulVar(routing.Start(i)) | |
) | |
routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(routing.End(i))) | |
for request in data["pickup_dropoff"]: | |
pickup_index = manager.NodeToIndex(request[0]) | |
delivery_index = manager.NodeToIndex(request[1]) | |
routing.solver().Add( | |
routing.VehicleVar(pickup_index) == routing.VehicleVar(delivery_index) | |
) | |
routing.solver().Add( | |
time_dimension.CumulVar(pickup_index) | |
<= time_dimension.CumulVar(delivery_index) | |
) | |
# Not Sure about whether this is right or wrong. Added Here Baesd Upon the issue #685 | |
min_dur = time_callback(pickup_index, delivery_index) | |
max_dur = int(1.3 * min_dur) | |
dur_expr = time_dimension.CumulVar(delivery_index) - time_dimension.CumulVar( | |
index | |
) | |
routing.solver().Add(dur_expr <= max_dur) | |
# Consraint End----------- | |
routing.AddPickupAndDelivery(pickup_index, delivery_index) | |
routing.AddDisjunction([pickup_index, delivery_index], 20_000, 2) | |
search_parameters = pywraprouting.DefaultRoutingSearchParameters() | |
search_parameters.first_solution_strategy = ( | |
FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION | |
) | |
search_parameters.local_search_metaheuristic = ( | |
LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH | |
) | |
search_parameters.time_limit.FromSeconds(3) | |
# search_parameters.log_search = True | |
solution = routing.SolveWithParameters(search_parameters) | |
print_solution(manager, routing, solution) | |
if __name__ == "__main__": | |
main() |
python /tmp/cvrptw_pd.py
Status: ROUTING_SUCCESS
Objective: 268314
Dropped nodes: 1 5 6 8 9 10 12 15 16 17 21 22 24 25 26 28 31 32
Route for vehicle 0:
Node_0 0m TW:[0,86400] Time(0,0) Load(0/0) -> Node_3 7741m TW:[23400,25200] Time(23400,24121) Load(0/3) -> Node_19 15009m TW:[0,86400] Time(23915,24636) Load(1/3) -> Node_2 23228m TW:[23400,25200] Time(24479,25200) Load(0/3) -> Node_11 24449m TW:[36000,36000] Time(36000,36000) Load(1/3) -> Node_14 28793m TW:[39600,39600] Time(39600,39600) Load(2/3) -> Node_18 40504m TW:[0,86400] Time(40455,40455) Load(3/3) -> Node_27 40504m TW:[0,86400] Time(40455,40455) Load(2/3) -> Node_30 40504m TW:[0,86400] Time(40455,40455) Load(1/3) -> Node_0 40504m Time(40455,40455) Load(0/3)
Distance of the route: 40504m
Time of the route: 40455min
Load of the route: 0
[0, 3, 19, 2, 11, 14, 18, 27, 30, 0]
Route for vehicle 3:
Node_0 0m TW:[0,86400] Time(0,0) Load(0/0) -> Node_4 21036m TW:[23400,25200] Time(23400,25200) Load(0/3) -> Node_7 25327m TW:[28800,28800] Time(28800,28800) Load(1/3) -> Node_13 35440m TW:[39600,39600] Time(39600,39600) Load(2/3) -> Node_23 47810m TW:[0,86400] Time(40513,40513) Load(3/3) -> Node_20 47810m TW:[0,86400] Time(40513,40513) Load(2/3) -> Node_29 47810m TW:[0,86400] Time(40513,40513) Load(1/3) -> Node_0 47810m Time(40513,40513) Load(0/3)
Distance of the route: 47810m
Time of the route: 40513min
Load of the route: 0
[0, 4, 7, 13, 23, 20, 29, 0]
Total distance of all routes: 88314m
Total time of all routes: 80968min
Total load of all routes: 0
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment