Possible output:
./same_vehicle.py
...
objective: 20
Dropped nodes:
Vehicle 0:
0 -> 7
7 -> 8
8 -> 5
5 -> 6
6 -> 0
Vehicle 1:
0 -> 1
1 -> 2
2 -> 3
3 -> 4
4 -> 0
#!/usr/bin/env python3 | |
"""Vehicles Routing Problem (VRP).""" | |
import sys | |
from ortools.constraint_solver import routing_enums_pb2, pywrapcp | |
# Model | |
dim_name = 'Dimension' | |
def duration_callback(from_index, to_index): | |
from_node = manager.IndexToNode(from_index) | |
to_node = manager.IndexToNode(to_index) | |
return 2 | |
manager = pywrapcp.RoutingIndexManager(9, 2, 0) | |
routing = pywrapcp.RoutingModel(manager) | |
transit_callback_index = routing.RegisterTransitCallback(duration_callback) | |
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) | |
MAX_ROUTE_TIME = 400 | |
routing.AddDimension(transit_callback_index, 0, MAX_ROUTE_TIME, True, dim_name) | |
time_dimension = routing.GetDimensionOrDie(dim_name) | |
pickups_deliveries = [ | |
(1, 2), | |
(3, 4), | |
(5, 6), | |
(7, 8) | |
] | |
for pickup, delivery in pickups_deliveries: | |
pickup_index = manager.NodeToIndex(pickup) | |
delivery_index = manager.NodeToIndex(delivery) | |
routing.AddPickupAndDelivery(pickup_index, delivery_index) | |
routing.solver().Add(routing.VehicleVar(pickup_index) == routing.VehicleVar(delivery_index)) | |
routing.solver().Add(time_dimension.CumulVar(pickup_index) <= time_dimension.CumulVar(delivery_index)) | |
start_0 = routing.Start(0) | |
start_1 = routing.Start(1) | |
pickup_1 = manager.NodeToIndex(1) | |
pickup_3 = manager.NodeToIndex(3) | |
pickup_5 = manager.NodeToIndex(5) | |
# P1 == P3 | |
active_p1_p3 = routing.ActiveVar(pickup_1) * routing.ActiveVar(pickup_3) | |
#active_p1_p3 = 1 | |
routing.solver().Add( | |
active_p1_p3 * routing.VehicleVar(pickup_1) == | |
active_p1_p3 * routing.VehicleVar(pickup_3)) | |
# P1 != P5 | |
active_p1_p5 = routing.ActiveVar(pickup_1) * routing.ActiveVar(pickup_5) | |
#active_p1_p5 = 1 | |
routing.solver().Add( | |
active_p1_p5 * (routing.VehicleVar(pickup_1) - routing.VehicleVar(pickup_5)) != | |
(1 - active_p1_p5)) | |
# S0 == P5 | |
active_s0_p5 = routing.ActiveVar(start_0) * routing.ActiveVar(pickup_5) | |
#active_s0_p5 = 1 | |
routing.solver().Add( | |
active_s0_p5 * routing.VehicleVar(start_0) == | |
active_s0_p5 * routing.VehicleVar(pickup_5)) | |
# S1 == P1 | |
active_s1_p1 = routing.ActiveVar(start_1) * routing.ActiveVar(pickup_1) | |
#active_s1_p1 = 1 | |
routing.solver().Add( | |
active_s1_p1 * routing.VehicleVar(start_1) == | |
active_s1_p1 * routing.VehicleVar(pickup_1)) | |
for node in range(1, 9): | |
routing.AddDisjunction([manager.NodeToIndex(node)], 1000) | |
search_parameters = pywrapcp.DefaultRoutingSearchParameters() | |
search_parameters.log_search = True | |
search_parameters.first_solution_strategy = routing_enums_pb2.FirstSolutionStrategy.ALL_UNPERFORMED | |
#search_parameters.first_solution_strategy = routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC | |
search_parameters.local_search_metaheuristic = routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH | |
#search_parameters.lns_time_limit.seconds = 1 | |
search_parameters.time_limit.seconds = 5 | |
solution = routing.SolveWithParameters(search_parameters) | |
if solution == None: | |
print("No solution found !") | |
sys.exit(0) | |
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 += ' {}'.format(manager.IndexToNode(node)) | |
print(dropped_nodes) | |
for vehicle_id in range(manager.GetNumberOfVehicles()): | |
print(f"Vehicle {vehicle_id}:") | |
index = routing.Start(vehicle_id) | |
node = manager.IndexToNode(index) | |
while not routing.IsEnd(index): | |
previous_node = node | |
previous_index = index | |
index = solution.Value(routing.NextVar(index)) | |
node = manager.IndexToNode(index) | |
nmap = node | |
print(f"{previous_node} -> {node}") |
Estimados, me podrán ayudar con un código de Python usando OR Tools, para resolver un problema de ruteo de varios camiones con dos depositos de partida.
Tendrán, algo para ver como se hace.
Gracias