Skip to content

Instantly share code, notes, and snippets.

@Mizux
Last active January 23, 2024 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Mizux/9e37c370a459bd472a6ac13c304f0b54 to your computer and use it in GitHub Desktop.
Save Mizux/9e37c370a459bd472a6ac13c304f0b54 to your computer and use it in GitHub Desktop.
VRP with same vehicles constraints.
#!/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}")

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
@Jtoscanini
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment