Reputation: 79
I am trying to solve the vehicle routing problem using or tools and i want to modify the below solution such that each vehicle at least cover 100 unit of distance before moving on to next vehicle.
Below is my code so far : The distance matrix is passed as variable data.
def print_solution(data, manager, routing, solution):
"""Prints solution on console."""
max_route_distance = 0
for vehicle_id in range(data['num_vehicles']):
sap_index = []
index = routing.Start(vehicle_id)
print(routing.IsEnd(index))
plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
route_distance = 0
while not routing.IsEnd(index):
plan_output += ' {} -> '.format(manager.IndexToNode(index))
sap_index.append(manager.IndexToNode(index))
previous_index = index
index = solution.Value(routing.NextVar(index))
route_distance += routing.GetArcCostForVehicle(
previous_index, index, vehicle_id)
plan_output += '{}\n'.format(manager.IndexToNode(index))
sap_index.append(manager.IndexToNode(index))
plan_output += 'Distance of the route: {}\n'.format(route_distance)
print(plan_output)
for z in sap_index:
print(sapids[z],end=" -> ")
print("\n")
max_route_distance = max(route_distance, max_route_distance)
print('Maximum of the route distances: {}'.format(max_route_distance))
def main():
"""Solve the CVRP problem."""
# Instantiate the data problem.
data = create_data_model()
# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),
data['num_vehicles'], data['depot'])
# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)
# Create and register a transit callback.
def distance_callback(from_index, to_index):
"""Returns the distance between the two nodes."""
# Convert from routing variable Index to distance matrix NodeIndex.
from_node = manager.IndexToNode(from_index)
to_node = manager.IndexToNode(to_index)
return data['distance_matrix'][from_node][to_node]
transit_callback_index = routing.RegisterTransitCallback(distance_callback)
# Define cost of each arc.
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# Add Distance constraint.
dimension_name = 'Distance'
routing.AddDimension(
transit_callback_index,
0, # no slack
100, # vehicle maximum travel distance
True, # start cumul to zero
dimension_name)
distance_dimension = routing.GetDimensionOrDie(dimension_name)
distance_dimension.SetGlobalSpanCostCoefficient(100)
# Setting first solution heuristic.
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
# Solve the problem.
solution = routing.SolveWithParameters(search_parameters)
# Print solution on console.
if solution:
print_solution(data, manager, routing, solution)
if __name__ == '__main__':
main()
answer for 50 sites and 4 vehicle is coming as under :
Route for vehicle 0:
0 -> 22 -> 11 -> 21 -> 39 -> 49 -> 24 -> 41 -> 35 -> 0
Distance of the route: 13
Route for vehicle 1:
0 -> 0
Distance of the route: 0
Route for vehicle 2:
0 -> 10 -> 43 -> 38 -> 6 -> 17 -> 36 -> 37 -> 14 -> 19 -> 15 -> 20 -> 40 -> 18 -> 16 -> 34 -> 12 -> 13 -> 5 -> 7 -> 8 -> 42
-> 0
Distance of the route: 20
Route for vehicle 3:
0 -> 23 -> 27 -> 26 -> 1 -> 48 -> 46 -> 47 -> 45 -> 30 -> 2 -> 33 -> 32 -> 31 -> 9 -> 28 -> 25 -> 29 -> 3 -> 44 -> 4 -> 0
Distance of the route: 25
Maximum of the route distances: 25
in the def print_solution
function i tried giving route_distance < 100
condition in while loop along with not routing.IsEnd(index)
but that did not work.
Need help!
Upvotes: 1
Views: 830
Reputation: 9281
in your sample, you have used:
100, # vehicle maximum travel distance
i.e. the hard upper bound for each vehicle is 100, so how you can expect vehicle to travel more than its limit ?
Also you should comment out the GlobalSpan
coefficient which currently give incentive to the solver to limit the maximum route length (it is the dominant factor here)...
Upvotes: 1
Reputation: 11014
This is a bad idea. You will create unfeasible problems very easily. You need to get the end var of each vehicle, and add a soft lower bound on that one.
See this doc entry
Upvotes: 1