Here is a basic implementation of CVRP in Python using the Google OR-Tools library:
```python
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
def create_data_model():
"""Stores the data for the problem."""
data = {}
data['distance_matrix'] = [
[0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502],
[548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594],
[776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278],
[696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514],
[582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400],
[274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 810],
[502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1016],
[194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468],
[308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810],
[194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 650],
[536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878],
[502, 594, 1278, 514, 400, 810, 1016, 468, 810, 650, 878, 0]
]
data['num_vehicles'] = 3
data['vehicle_capacities'] = [100, 100, 100]
data['depot'] = 0
return data
def print_solution(data, manager, routing, solution):
"""Prints solution on console."""
total_distance = 0
total_load = 0
for vehicle_id in range(data['num_vehicles']):
index = routing.Start(vehicle_id)
plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
route_distance = 0
route_load = 0
while not routing.IsEnd(index):
node_index = manager.IndexToNode(index)
route_load += data['demands'][node_index]
plan_output += ' {} Load({}) -> '.format(node_index, route_load)
previous_index = index
index = solution.Value(routing.NextVar(index))
route_distance += routing.GetArcCostForVehicle(
previous_index, index, vehicle_id)
plan_output += ' {} Load({})\n'.format(manager.IndexToNode(index),
route_load)
plan_output += 'Distance of the route: {}m\n'.format(route_distance)
plan_output += 'Load of the route: {}\n'.format(route_load)
print(plan_output)
total_distance += route_distance
total_load += route_load
print('Total distance of all routes: {}m'.format(total_distance))
print('Total load of all routes: {}'.format(total_load))
def main():
"""Entry point of the program."""
data = create_data_model()
manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),
data['num_vehicles'], data['depot'])
routing = pywrapcp.RoutingModel(manager)
def distance_callback(from_index, to_index):
"""Returns the distance between the two nodes."""
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)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
dimension_name = 'Capacity'
routing.AddDimension(
transit_callback_index,
0, # no slack
100, # vehicle maximum capacities
True, # start cumul to zero
dimension_name)
capacity_dimension = routing.GetDimensionOrDie(dimension_name)
for i, demand in enumerate(data['demands']):
index = manager.NodeToIndex(i)
capacity_dimension.SetDemand(index, demand)
for vehicle_id in range(data['num_vehicles']):
index = routing.Start(vehicle_id)
capacity_dimension.CumulVar(index).SetRange(data['vehicle_capacities'][vehicle_id],
data['vehicle_capacities'][vehicle_id])
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (
routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION)
solution = routing.SolveWithParameters(search_parameters)
if solution:
print_solution(data, manager, routing, solution)
if __name__ == '__main__':
main()
```
Note that this is just a basic implementation and can be modified to suit specific requirements and constraints of individual problem instances.