henryfarreal

Untitled

Apr 27th, 2024
306
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.83 KB | Help | 0 0
  1. """Simple Vehicles Routing Problem."""
  2.  
  3. from ortools.constraint_solver import routing_enums_pb2
  4. from ortools.constraint_solver import pywrapcp
  5.  
  6.  
  7. def create_data_model():
  8.     """Stores the data for the problem."""
  9.     data = {}
  10.     data["distance_matrix"] = [
  11.         # fmt: off
  12.         [0.0, 10055.107404417138, 3721.69821382381, 6420.976150377692, 10055.107404417138, 11494.252586094712, 9509.686718064775, 7194.254050220477, 8705.952660049456, 6379.850683975058, 3886.900964162668, 1822.1360080334186, 3514.397119387665, 3610.3415490478765, 4450.3356475054825],
  13. [10055.107404417138, 0.0, 6352.487948803106, 3865.3718588710813, 0.0, 3114.6631911491004, 10068.043552617626, 10377.997097781765, 14786.349611907537, 13486.132557208786, 6253.518796049527, 8261.902076161898, 8160.72865983126, 6491.504886964134, 5605.700303676604],
  14. [3721.69821382381, 6352.487948803106, 0.0, 2730.044895787093, 6352.487948803106, 8078.121076188516, 8719.693526224311, 7282.548022588702, 10492.857847079005, 8541.725451568233, 360.96767380841925, 2000.8925577888222, 3238.5044012376, 774.9043974937284, 775.4208008567286],
  15. [6420.976150377692, 3865.3718588710813, 2730.044895787093, 0.0, 3865.3718588710813, 6218.598554216611, 9614.791265876564, 8881.003492652062, 12690.637615496404, 10949.313370896472, 2534.078159796496, 4730.651505366733, 5438.512889903392, 3143.0180785142356, 2124.888787887561],
  16. [10055.107404417138, 0.0, 6352.487948803106, 3865.3718588710813, 0.0, 3114.6631911491004, 10068.043552617626, 10377.997097781765, 14786.349611907537, 13486.132557208786, 6253.518796049527, 8261.902076161898, 8160.72865983126, 6491.504886964134, 5605.700303676604],
  17. [11494.252586094712, 3114.6631911491004, 8078.121076188516, 6218.598554216611, 3114.6631911491004, 0.0, 8587.837026595082, 9691.228569020373, 14301.09183819817, 13476.252318321056, 8107.3462921088385, 9682.100007629035, 8789.80103415498, 7927.193029999964, 7307.725343561157],
  18. [9509.686718064775, 10068.043552617626, 8719.693526224311, 9614.791265876564, 10068.043552617626, 8587.837026595082, 0.0, 2723.4335025409605, 6559.769557118661, 6881.23742757047, 9047.410868946314, 8527.023016095842, 6145.117859044644, 7972.602982178097, 8454.126339805342],
  19. [7194.254050220477, 10377.997097781765, 7282.548022588702, 8881.003492652062, 10377.997097781765, 9691.228569020373, 2723.4335025409605, 0.0, 4614.784858405044, 4308.139315054496, 7639.660704478896, 6556.960595239801, 4204.749390769965, 6508.164370346345, 7246.068597913849],
  20. [8705.952660049456, 14786.349611907537, 10492.857847079005, 12690.637615496404, 14786.349611907537, 14301.09183819817, 6559.769557118661, 4614.784858405044, 0.0, 2395.635698408829, 10844.49614996829, 9034.5034090655, 7302.614530267333, 9789.122518627675, 10733.938152600293],
  21. [6379.850683975058, 13486.132557208786, 8541.725451568233, 10949.313370896472, 13486.132557208786, 13476.252318321056, 6881.23742757047, 4308.139315054496, 2395.635698408829, 0.0, 8878.125391048365, 6901.8917190574975, 5517.974514751043, 7897.332824366355, 8891.714263023221],
  22. [3886.900964162668, 6253.518796049527, 360.96767380841925, 2534.078159796496, 6253.518796049527, 8107.3462921088385, 9047.410868946314, 7639.660704478896, 10844.49614996829, 8878.125391048365, 0.0, 2238.569086322884, 3598.221078392358, 1131.6846740391532, 838.9685870948458],
  23. [1822.1360080334186, 8261.902076161898, 2000.8925577888222, 4730.651505366733, 8261.902076161898, 9682.100007629035, 8527.023016095842, 6556.960595239801, 9034.5034090655, 6901.8917190574975, 2238.569086322884, 0.0, 2397.491113642382, 1790.1374118031774, 2675.8725837926613],
  24. [3514.397119387665, 8160.72865983126, 3238.5044012376, 5438.512889903392, 8160.72865983126, 8789.80103415498, 6145.117859044644, 4204.749390769965, 7302.614530267333, 5517.974514751043, 3598.221078392358, 2397.491113642382, 0.0, 2500.849919010973, 3431.7098964898996],
  25. [3610.3415490478765, 6491.504886964134, 774.9043974937284, 3143.0180785142356, 6491.504886964134, 7927.193029999964, 7972.602982178097, 6508.164370346345, 9789.122518627675, 7897.332824366355, 1131.6846740391532, 1790.1374118031774, 2500.849919010973, 0.0, 1019.8137083490479],
  26. [4450.3356475054825, 5605.700303676604, 775.4208008567286, 2124.888787887561, 5605.700303676604, 7307.725343561157, 8454.126339805342, 7246.068597913849, 10733.938152600293, 8891.714263023221, 838.9685870948458, 2675.8725837926613, 3431.7098964898996, 1019.8137083490479, 0.0],
  27.         # fmt: on
  28.     ]
  29.     data["demands"] = [0, 10, 20, 5, 5, 2, 3, 3, 5, 20, 2, 4, 1, 0]
  30.     data["vehicle_capacities"] = [20, 20, 20, 20]
  31.     data["num_vehicles"] = 4
  32.     data["starts"] = [0, 0, 0, 0]
  33.     data["ends"] = [14, 14, 14, 14]
  34.  
  35.     return data
  36.  
  37. def print_solution(data, manager, routing, solution):
  38.     """Prints solution on console."""
  39.     print(f"Objective: {solution.ObjectiveValue()}")
  40.     # Display routes
  41.     total_distance = 0
  42.     total_load = 0
  43.     for vehicle_id in range(data["num_vehicles"]):
  44.         index = routing.Start(vehicle_id)
  45.         plan_output = f"Route for vehicle {vehicle_id}:\n"
  46.         route_distance = 0
  47.         route_load = 0
  48.         while not routing.IsEnd(index):
  49.             node_index = manager.IndexToNode(index)
  50.             route_load += data["demands"][node_index]
  51.             plan_output += f" {node_index} Load({route_load}) -> "
  52.             previous_index = index
  53.             index = solution.Value(routing.NextVar(index))
  54.             route_distance += data["distance_matrix"][manager.IndexToNode(previous_index)][manager.IndexToNode(index)]
  55.         plan_output += f" {manager.IndexToNode(index)} Load({route_load})\n"
  56.         plan_output += f"Distance of the route: {route_distance}m\n"
  57.         plan_output += f"Load of the route: {route_load}\n"
  58.         print(plan_output)
  59.         total_distance += route_distance
  60.         total_load += route_load
  61.     print(f"Total distance of all routes: {total_distance}m")
  62.     print(f"Total load of all routes: {total_load}")
  63.  
  64.  
  65. def main():
  66.     """Entry point of the program."""
  67.     # Instantiate the data problem.
  68.     data = create_data_model()
  69.  
  70.     # Create the routing index manager.
  71.     manager = pywrapcp.RoutingIndexManager(
  72.         len(data["distance_matrix"]), data["num_vehicles"], data["starts"], data["ends"]
  73.     )
  74.  
  75.     # Create Routing Model.
  76.     routing = pywrapcp.RoutingModel(manager)
  77.  
  78.     # Create and register a transit callback.
  79.     def distance_callback(from_index, to_index):
  80.         """Returns the distance between the two nodes."""
  81.         # Convert from routing variable Index to distance matrix NodeIndex.
  82.         from_node = manager.IndexToNode(from_index)
  83.         to_node = manager.IndexToNode(to_index)
  84.         distance = data["distance_matrix"][from_node][to_node]
  85.  
  86.          # Debug printing
  87.         print(f"From Index: {from_index}, To Index: {to_index}")
  88.         print(f"From Node: {from_node}, To Node: {to_node}")
  89.         print(f"Distance: {distance}")
  90.  
  91.         return distance
  92.  
  93.     transit_callback_index = routing.RegisterTransitCallback(distance_callback)
  94.  
  95.     # Define cost of each arc.
  96.     routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
  97.  
  98.     # Add Capacity constraint.
  99.     def demand_callback(from_index):
  100.         """Returns the demand of the node."""
  101.         # Convert from routing variable Index to demands NodeIndex.
  102.         from_node = manager.IndexToNode(from_index)
  103.         return data["demands"][from_node]
  104.  
  105.     demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback)
  106.     routing.AddDimensionWithVehicleCapacity(
  107.         demand_callback_index,
  108.         0,  # null capacity slack
  109.         data["vehicle_capacities"],  # vehicle maximum capacities
  110.         True,  # start cumul to zero
  111.         "Capacity",
  112.     )
  113.  
  114.     # Convert maximum travel distance from kilometers to meters (assuming 3000 km).
  115.     max_travel_distance_km = 2
  116.     max_travel_distance_m = max_travel_distance_km * 1000  # Convert km to meters
  117.  
  118.     # Add Distance constraint.
  119.     dimension_name = "Distance"
  120.     routing.AddDimension(
  121.         transit_callback_index,
  122.         0,  # no slack
  123.         max_travel_distance_m,  # vehicle maximum travel distance
  124.         True,  # start cumul to zero
  125.         dimension_name,
  126.     )
  127.     distance_dimension = routing.GetDimensionOrDie(dimension_name)
  128.     distance_dimension.SetGlobalSpanCostCoefficient(100)
  129.  
  130.  
  131.  
  132.     # Setting first solution heuristic.
  133.     search_parameters = pywrapcp.DefaultRoutingSearchParameters()
  134.     search_parameters.first_solution_strategy = (
  135.         routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC
  136.     )
  137.    
  138.     search_parameters.time_limit.seconds = 60
  139.     search_parameters.log_search = True
  140.  
  141.     # Solve the problem.
  142.     solution = routing.SolveWithParameters(search_parameters)
  143.  
  144.     print("Solver status: ", routing.status())
  145.  
  146.     # Print solution on console.
  147.     if solution:
  148.         print_solution(data, manager, routing, solution)
  149.  
  150.  
  151. if __name__ == "__main__":
  152.     main()
  153.  
Advertisement
Add Comment
Please, Sign In to add comment