def main(): # Enter filename of a manifest. Will be automated in production version. fname = '243884' # Run Java code GraphHopper on manifest to create distance matrix as csv. os.system('java -jar dmatrix.jar ./manifests/'+fname +'.csv') # Load manifest data and split. df = pd.read_csv('./manifests/'+fname+'.csv') city_names = df['Address'][:] lats = df['Latitude'][:] lons = df['Longitude'][:] tsp_size = len(df) # Create routing model if tsp_size > 0: # TSP of size tsp_size # Second argument = 1 to build a single tour (used for TSP with single delivery truck rather than full # vehicle routing problem with fleet). # Nodes are indexed from 0 to tsp_size - 1. By default the start of # the route is node 0. routing = pywrapcp.RoutingModel(tsp_size, 1, 0) #had to add depot index search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() # Setting first solution heuristic: the # method for finding a first solution to the problem. search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # Create the distance callback, which takes two arguments (the from and to node indices) # and returns the distance between these nodes. dist_between_nodes = CreateDistanceCallback(fname) dist_callback = dist_between_nodes.Distance routing.SetArcCostEvaluatorOfAllVehicles(dist_callback) # Solve, returns a solution if any. assignment = routing.SolveWithParameters(search_parameters) if assignment: # Solution cost. print "Total distance: " + str(assignment.ObjectiveValue()) + " meters\n" # Inspect solution. # Only one route here; otherwise iterate from 0 to routing.vehicles() - 1 leadingurl = 'http://localhost:8989/?point=' trailingurl = '&locale=en-US&vehicle=car&weighting=fastest&elevation=false&use_miles=false&layer=Omniscale' urlspace = '%2C' urlnext = '&point=' theurl = leadingurl route_number = 0 index = routing.Start(route_number) # Index of the variable for the starting node. route = '' while not routing.IsEnd(index): # Convert variable indices to node indices in the displayed route. route += str(city_names[routing.IndexToNode(index)]) + ' -> ' theurl += str(lats[routing.IndexToNode(index)]) + urlspace + str(lons[routing.IndexToNode(index)]) + urlnext index = assignment.Value(routing.NextVar(index)) route += str(city_names[routing.IndexToNode(index)]) theurl += str(lats[routing.IndexToNode(index)]) + urlspace + str(lons[routing.IndexToNode(index)]) print "Route:\n\n" + route print theurl + trailingurl else: print 'No solution found.' else: print 'Specify an instance greater than 0.'
def main(data, num_vehicles,vehicle_capacity ): # Create the data. #data = create_data_array() locations = data[0] demands = data[1] num_locations = len(locations) depot = 0 # The depot is the start and end point of each route. # Create routing model. if num_locations > 0: routing = pywrapcp.RoutingModel(num_locations, num_vehicles, depot) search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() # Setting first solution heuristic: the # method for finding a first solution to the problem. search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # The 'PATH_CHEAPEST_ARC' method does the following: # Starting from a route "start" node, connect it to the node which produces the # cheapest route segment, then extend the route by iterating on the last # node added to the route. # Put a callback to the distance function here. The callback takes two # arguments (the from and to node indices) and returns the distance between # these nodes. dist_between_locations = CreateDistanceCallback(locations) dist_callback = dist_between_locations.Distance routing.SetArcCostEvaluatorOfAllVehicles(dist_callback) # Put a callback to the demands. demands_at_locations = CreateDemandCallback(demands) demands_callback = demands_at_locations.Demand # Add a dimension for demand. slack_max = 0 fix_start_cumul_to_zero = True demand = "Demand" routing.AddDimension(demands_callback, slack_max, vehicle_capacity, fix_start_cumul_to_zero, demand) # Solve, displays a solution if any. assignment = routing.SolveWithParameters(search_parameters) if assignment: # Display solution. # Solution cost. print( "Total distance of all routes: " + str(assignment.ObjectiveValue()) + "\n") total_tour = [] for vehicle_nbr in range(num_vehicles): index = routing.Start(vehicle_nbr) index_next = assignment.Value(routing.NextVar(index)) route = '' route_dist = 0 route_demand = 0 while not routing.IsEnd(index_next): node_index = routing.IndexToNode(index) node_index_next = routing.IndexToNode(index_next) route += str(node_index) + " -> " # Add the distance to the next node. route_dist += dist_callback(node_index, node_index_next) # Add demand. route_demand += demands[node_index_next] index = index_next index_next = assignment.Value(routing.NextVar(index)) node_index = routing.IndexToNode(index) node_index_next = routing.IndexToNode(index_next) route += str(node_index) + " -> " + str(node_index_next) route_dist += dist_callback(node_index, node_index_next) temp = route.split('->') temp = [int(i) for i in temp if i != 0] total_tour.append(temp) print ("Route for vehicle " + str(vehicle_nbr) + ":\n\n" + route + "\n") print ("Distance of route " + str(vehicle_nbr) + ": " + str(route_dist)) print ("Demand met by vehicle " + str(vehicle_nbr) + ": " + str(route_demand) + "\n") return total_tour else: print ('No solution found.') else: print ('Specify an instance greater than 0.')
def main(): """Entry point of the program.""" # Instantiate the data problem. # [START data] data = create_data_model() # [END data] # Create the routing index manager. # [START index_manager] manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['depot']) # [END index_manager] # Create Routing Model. # [START routing_model] routing = pywrapcp.RoutingModel(manager) # [END routing_model] # Define cost of each arc. # [START arc_cost] def distance_callback(from_index, to_index): """Returns the manhattan 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) routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) # [END arc_cost] # Add Distance constraint. # [START distance_constraint] dimension_name = 'Distance' routing.AddDimension( transit_callback_index, 0, # no slack 3000, # vehicle maximum travel distance True, # start cumul to zero dimension_name) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) # [END distance_constraint] # Define Transportation Requests. # [START pickup_delivery_constraint] for request in data['pickups_deliveries']: pickup_index = manager.NodeToIndex(request[0]) delivery_index = manager.NodeToIndex(request[1]) routing.AddPickupAndDelivery(pickup_index, delivery_index) routing.solver().Add( routing.VehicleVar(pickup_index) == routing.VehicleVar( delivery_index)) routing.solver().Add( distance_dimension.CumulVar(pickup_index) <= distance_dimension.CumulVar(delivery_index)) routing.SetPickupAndDeliveryPolicyOfAllVehicles( pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_LIFO) # [END pickup_delivery_constraint] # Setting first solution heuristic. # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION) # [END parameters] # Solve the problem. # [START solve] assignment = routing.SolveWithParameters(search_parameters) # [END solve] # Print solution on console. # [START print_solution] if assignment: print_solution(data, manager, routing, assignment)
def run_vrptur(pois, measurement, num_days): depot = 0 # The depot is the start and end point of each route. num_pois = len(pois) tour = Tour(num_days) # Create routing model. if num_pois > 0: routing = pywrapcp.RoutingModel(num_pois, num_days, depot) search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() # Setting first solution heuristic: the # method for finding a first solution to the problem. search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # search_parameters.first_solution_strategy = ( # routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) # The 'PATH_CHEAPEST_ARC' method does the following: # Starting from a route "start" node, connect it to the node which produces the # cheapest route segment, then extend the route by iterating on the last # node added to the route. # Put a callback to the measurement function here. The callback takes two # arguments (the from and to node indices) and returns the duration between # these nodes. measurement_between_pois = CreateMeasurementCallback(pois, measurement) duration_callback = measurement_between_pois.duration distance_callback = measurement_between_pois.distance routing.SetArcCostEvaluatorOfAllVehicles(duration_callback) # Add a dimension for duration. max_day_duration = 480 # in minutes fix_start_cumul_to_zero = True duration = "Duration" routing.AddDimension(duration_callback, max_day_duration, max_day_duration, fix_start_cumul_to_zero, duration) # Solve, displays a solution if any. assignment = routing.SolveWithParameters(search_parameters) if assignment: # Solution cost. tour.duration = assignment.ObjectiveValue() for day_nbr in range(num_days): trip = Trip(day_nbr) # Start: nodes 0 and 1 index = routing.Start(day_nbr) index_next = assignment.Value(routing.NextVar(index)) while not routing.IsEnd(index_next): # Get indexes of nodes node_index = routing.IndexToNode(index) node_index_next = routing.IndexToNode(index_next) # Increment trip trip.add_poi(pois[node_index]) trip.add_duration( duration_callback(node_index, node_index_next)) trip.add_distance( distance_callback(node_index, node_index_next)) # Get next nodes index = index_next index_next = assignment.Value(routing.NextVar(index)) # Get indexes of last nodes: (n-2) and (n-1) node_index = routing.IndexToNode(index) node_index_next = routing.IndexToNode(index_next) # Increment trip with last indexes trip.add_poi(pois[node_index]) trip.add_poi(pois[node_index_next]) trip.add_duration( duration_callback(node_index, node_index_next)) trip.add_distance( distance_callback(node_index, node_index_next)) tour.trips.append(trip) else: print('No solution found for num_days = ' + str(num_days)) else: print('Specify an instance (PoIs) greater than 0.') return tour
def main(): """Solve the CVRP problem.""" # Instantiate the data problem. # [START data] data = create_data_model() # [END data] # Create the routing index manager. # [START index_manager] manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['depot']) # [END index_manager] # Create Routing Model. # [START routing_model] routing = pywrapcp.RoutingModel(manager) # [END routing_model] # Create and register a transit callback. # [START 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) # [END transit_callback] # Define cost of each arc. # [START arc_cost] routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) # [END arc_cost] # Add Distance constraint. # [START distance_constraint] dimension_name = 'Distance' routing.AddDimension( transit_callback_index, 0, # no slack 3000, # vehicle maximum travel distance True, # start cumul to zero dimension_name) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) # [END distance_constraint] # [START print_initial_solution] initial_solution = routing.ReadAssignmentFromRoutes( data['initial_routes'], True) print('Initial solution:') print_solution(data, manager, routing, initial_solution) # [END print_initial_solution] # Set default search parameters. # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() # [END parameters] # Solve the problem. # [START solve] solution = routing.SolveFromAssignmentWithParameters( initial_solution, search_parameters) # [END solve] # Print solution on console. # [START print_solution] if solution: print('Solution after search:') print_solution(data, manager, routing, solution)
def solve_vrp(vehicle_count, vehicle_capacity, customers: Customer, big_number=100000, strategy=FSS.FIRST_UNBOUND_MIN_VALUE, ls_option=LSM.GUIDED_LOCAL_SEARCH): """Solve the CVRP problem.""" # Instantiate the data problem. data = create_data_model(vehicle_count, vehicle_capacity, customers, big_number) # 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 Capacity constraint. def demand_callback(from_index): """Returns the demand of the node.""" # Convert from routing variable Index to demands NodeIndex. from_node = manager.IndexToNode(from_index) return data['demands'][from_node] demand_callback_index = routing.RegisterUnaryTransitCallback( demand_callback) routing.AddDimensionWithVehicleCapacity( demand_callback_index, 0, # null capacity slack data['vehicle_capacities'], # vehicle maximum capacities True, # start cumul to zero 'Capacity') # Setting first solution heuristic. search_parameters = pywrapcp.DefaultRoutingSearchParameters() if 10 <= vehicle_count < 16: search_parameters.time_limit.seconds = 600 else: search_parameters.time_limit.seconds = 90 search_parameters.first_solution_strategy = strategy search_parameters.local_search_metaheuristic = ls_option # Solve the problem. solution = routing.SolveWithParameters(search_parameters) # Print solution on console. objective = -1 if solution: tours, objective = print_solution(data, manager, routing, solution, customers, big_number, do_print=False) else: tours = trivial_solution(vehicle_count, vehicle_capacity, customers) return tours, objective
def solve_vrp(vrp_points, problem_id, depot_id, ffs, lsm, n_veh): """Solve the CVRP problem.""" # Instantiate the data problem. data = create_data_model(vrp_points, depot_id, n_veh) # 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 3000000, # 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() firstSolutions = { 'PATH_CHEAPEST_ARC': (routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC), 'AUTOMATIC': (routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC), 'PATH_MOST_CONSTRAINED_ARC': (routing_enums_pb2.FirstSolutionStrategy.PATH_MOST_CONSTRAINED_ARC), 'EVALUATOR_STRATEGY': (routing_enums_pb2.FirstSolutionStrategy.EVALUATOR_STRATEGY), 'SAVINGS': (routing_enums_pb2.FirstSolutionStrategy.SAVINGS), 'SWEEP': (routing_enums_pb2.FirstSolutionStrategy.SWEEP), 'CHRISTOFIDES': (routing_enums_pb2.FirstSolutionStrategy.CHRISTOFIDES), 'ALL_UNPERFORMED': (routing_enums_pb2.FirstSolutionStrategy.ALL_UNPERFORMED), 'BEST_INSERTION': (routing_enums_pb2.FirstSolutionStrategy.BEST_INSERTION), 'PARALLEL_CHEAPEST_INSERTION': (routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION), 'LOCAL_CHEAPEST_INSERTION': (routing_enums_pb2.FirstSolutionStrategy.LOCAL_CHEAPEST_INSERTION), 'GLOBAL_CHEAPEST_ARC': (routing_enums_pb2.FirstSolutionStrategy.GLOBAL_CHEAPEST_ARC), 'LOCAL_CHEAPEST_ARC': (routing_enums_pb2.FirstSolutionStrategy.LOCAL_CHEAPEST_ARC), 'FIRST_UNBOUND_MIN_VALUE': (routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) } search_parameters.first_solution_strategy = firstSolutions[ffs] localSearchMetas = { 'AUTOMATIC': (routing_enums_pb2.LocalSearchMetaheuristic.AUTOMATIC), 'GREEDY_DESCENT': (routing_enums_pb2.LocalSearchMetaheuristic.GREEDY_DESCENT), 'GUIDED_LOCAL_SEARCH': (routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH), 'SIMULATED_ANNEALING': (routing_enums_pb2.LocalSearchMetaheuristic.SIMULATED_ANNEALING), 'TABU_SEARCH': (routing_enums_pb2.LocalSearchMetaheuristic.TABU_SEARCH) } search_parameters.local_search_metaheuristic = localSearchMetas[lsm] # Solve the problem. solution = routing.SolveWithParameters(search_parameters) # Print solution on console. if solution: total_string = print_solution(data, manager, routing, solution) rez = solution_dict(data, manager, routing, solution) # save_pickle_data('routing_rez.pkl', rez) exists = RoutingPlan.objects.filter( problem=VrpProblem.objects.get(id=problem_id), vehicle_num=n_veh).exists() if not exists: for r in rez: rp = ';'.join([str(i) for i in r['route']]) routing_plan = RoutingPlan( problem=VrpProblem.objects.get(id=problem_id), routing_plan=rp, vehicle_num=n_veh, vehicle_id=r['veh_id'], total_distance=r['distance']) routing_plan.save() return total_string, rez return None, None
def main(): # Create the data. data = create_data_array() locations = data[0] demands = data[1] start_times = data[2] num_locations = len(locations) depot = 0 num_vehicles = 5 search_time_limit = 400000 # Create routing model. if num_locations > 0: # The number of nodes of the VRP is num_locations. # Nodes are indexed from 0 to num_locations - 1. By default the start of # a route is node 0. routing = pywrapcp.RoutingModel(num_locations, num_vehicles) search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() # Setting first solution heuristic: the # method for finding a first solution to the problem. search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # The 'PATH_CHEAPEST_ARC' method does the following: # Starting from a route "start" node, connect it to the node which produces the # cheapest route segment, then extend the route by iterating on the last # node added to the route. # Set the depot. routing.SetDepot(depot) # Put callbacks to the distance function and travel time functions here. dist_between_locations = CreateDistanceCallback(locations) dist_callback = dist_between_locations.Distance routing.SetArcCostEvaluatorOfAllVehicles(dist_callback) demands_at_locations = CreateDemandCallback(demands) demands_callback = demands_at_locations.Demand # Adding capacity dimension constraints. VehicleCapacity = 100 NullCapacitySlack = 0 fix_start_cumul_to_zero = True capacity = "Capacity" routing.AddDimension(demands_callback, NullCapacitySlack, VehicleCapacity, fix_start_cumul_to_zero, capacity) # Adding time dimension constraints. time_per_demand_unit = 300 horizon = 24 * 3600 time = "Time" tw_duration = 5 * 3600 speed = 10 service_times = CreateServiceTimeCallback(demands, time_per_demand_unit) service_time_callback = service_times.ServiceTime total_times = CreateTotalTimeCallback(service_time_callback, dist_callback, speed) total_time_callback = total_times.TotalTime # Add a dimension for time-window constraints and limits on the start times and end times. routing.AddDimension( total_time_callback, # total time function callback horizon, horizon, fix_start_cumul_to_zero, time) # Add limit on size of the time windows. time_dimension = routing.GetDimensionOrDie(time) for order in range(1, num_locations): start = start_times[order] time_dimension.CumulVar(order).SetRange(start, start + tw_duration) # Solve displays a solution if any. assignment = routing.SolveWithParameters(search_parameters) if assignment: data = create_data_array() locations = data[0] demands = data[1] start_times = data[2] size = len(locations) # Solution cost. print "Total distance of all routes: " + str( assignment.ObjectiveValue()) + "\n" # Inspect solution. capacity_dimension = routing.GetDimensionOrDie(capacity) time_dimension = routing.GetDimensionOrDie(time) for vehicle_nbr in range(num_vehicles): index = routing.Start(vehicle_nbr) plan_output = 'Route {0}:'.format(vehicle_nbr) while not routing.IsEnd(index): node_index = routing.IndexToNode(index) load_var = capacity_dimension.CumulVar(index) time_var = time_dimension.CumulVar(index) plan_output += \ " {node_index} Load({load}) Time({tmin}, {tmax}) -> ".format( node_index=node_index, load=assignment.Value(load_var), tmin=str(assignment.Min(time_var)), tmax=str(assignment.Max(time_var))) index = assignment.Value(routing.NextVar(index)) node_index = routing.IndexToNode(index) load_var = capacity_dimension.CumulVar(index) time_var = time_dimension.CumulVar(index) plan_output += \ " {node_index} Load({load}) Time({tmin}, {tmax})".format( node_index=node_index, load=assignment.Value(load_var), tmin=str(assignment.Min(time_var)), tmax=str(assignment.Max(time_var))) print plan_output print "\n" else: print 'No solution found.' else: print 'Specify an instance greater than 0.'
def solve_it(input_data): # Create routing model # if args.tsp_size > 0: # TSP of size args.tsp_size # Second argument = 1 to build a single tour (it's a TSP). # Nodes are indexed from 0 to parser_tsp_size - 1, by default the start of # the route is node 0. matrix = RandomMatrix(input_data) tsp_size = len(matrix.points) routing = pywrapcp.RoutingModel(tsp_size, 1, 0) search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() # Setting first solution heuristic (cheapest addition). search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # Setting the cost function. # Put a callback to the distance accessor here. The callback takes two # arguments (the from and to node inidices) and returns the distance between # these nodes. matrix_callback = matrix.Distance tsp_use_random_matrix = True if tsp_use_random_matrix: routing.SetArcCostEvaluatorOfAllVehicles(matrix_callback) else: routing.SetArcCostEvaluatorOfAllVehicles(Distance) # Forbid node connections (randomly). rand = random.Random() rand.seed(1) # rand.seed(args.tsp_random_seed) forbidden_connections = 0 while forbidden_connections < 0: # while forbidden_connections < args.tsp_random_forbidden_connections: from_node = rand.randrange(tsp_size - 1) to_node = rand.randrange(tsp_size - 1) + 1 if routing.NextVar(from_node).Contains(to_node): print('Forbidding connection ' + str(from_node) + ' -> ' + str(to_node)) routing.NextVar(from_node).RemoveValue(to_node) forbidden_connections += 1 # Solve, returns a solution if any. # assignment = routing.SolveWithParameters(search_parameters) assignment = routing.Solve() if assignment: # Solution cost. # print(assignment.ObjectiveValue()) # Inspect solution. # Only one route here; otherwise iterate from 0 to routing.vehicles() - 1 route_number = 0 node = routing.Start(route_number) route = '' while not routing.IsEnd(node): route += ' ' + str(node) node = assignment.Value(routing.NextVar(node)) # route += '0' nodeList = route.split()[1:] # totalDistance = assignment.ObjectiveValue() + matrix.points[int(nodeList[0])].distanceTo(matrix.points[int(nodeList[-1])]) # print(totalDistance) output_data = '%.2f' % assignment.ObjectiveValue() + ' ' + str( 0) + '\n' output_data += route # output_data += ' '.join(map(str, solution)) csvOutput(matrix, route.split(' ')) return output_data else: print('No solution found.')
def main(): vehicleList = None waypointsList = None depotList = None flightTime = 15 maxSpeed = 5 for arg in sys.argv[1:]: #print('{}'.format(arg)) tokens = arg.split(":") if tokens[0] == "Vehicles": vehicleList = (tokens[1].split(",")) elif tokens[0] == "Waypoints": waypointsList = parseWaypoints(tokens[1]) elif tokens[0] == "Depot": depotList = parseDepots(tokens[1]) elif tokens[0] == "Flight Time": flightTime = int(tokens[1]) elif tokens[0] == "Speed": maxSpeed = int(tokens[1]) print("Vehicles: {}".format(vehicleList)) print("Waypoints: {}".format(waypointsList)) print("Depot: {}".format(depotList)) #Waypoints have no demaonds demands = None #Add the depot(s) to the begining of the waypoints list depotIndices = [] for idx in range(len(depotList)): waypointsList.insert(idx, depotList[idx]) depotIndices.append(idx) # Create a set of customer, (and depot) stops. customers = Customers( num_stops=len(waypointsList), lats=[loc[0] for loc in waypointsList], lons=[loc[1] for loc in waypointsList], dems=demands, maxFlightTime=flightTime, #min_demand=1, #max_demand=15, #box_size=40, min_tw=15, max_tw=15) # Create callback fns for distances, demands, service and transit-times. dist_fn = customers.return_dist_callback() dem_fn = customers.return_dem_callback() #serv_time_fn = customers.make_service_time_call_callback() #Turn the ## Create a list of inhomgenious vehicle capacities as integer units. #capacity = [50, 175, 200, 250] capacity = [] for veh in vehicleList: capacity.append(100) transit_time_fn = customers.make_transit_time_callback(speed_kmph=maxSpeed) def tot_time_fn(a, b): """ The time function we want is both transit time and service time. """ #return serv_time_fn(a, b) + transit_time_fn(a, b) return transit_time_fn(a, b) # Create a list of inhomogenious fixed vehicle costs. cost = [int(100) for c in capacity] # Create a set of vehicles, the number set by the length of capacity. vehicles = Vehicles(capacity=capacity, cost=cost) ## check to see that the problem is feasible, if we don't have enough ## vehicles to cover the demand, there is no point in going further. #assert (customers.get_total_demand() < vehicles.get_total_capacity()) # Set the starting nodes, and create a callback fn for the starting node. start_fn = vehicles.return_starting_callback(customers, sameStartFinish=True) # Set model parameters model_parameters = pywrapcp.RoutingModel.DefaultModelParameters() # The solver parameters can be accessed from the model parameters. For example : # model_parameters.solver_parameters.CopyFrom( # pywrapcp.Solver.DefaultSolverParameters()) # model_parameters.solver_parameters.trace_propagation = True # Make the routing model instance. # if we have multiple depots, then each vehicle has a differnt start/end location, pass those in # instead of start/ends in the vehicle class routing = pywrapcp.RoutingModel( customers.number, #in tnumber vehicles.number, #int number depotIndices, #list of start depot depotIndices, #list of end depots model_parameters) #routing = pywrapcp.RoutingModel( # customers.number, # int number # vehicles.number, # int number # vehicles.starts, # List of int start depot # vehicles.ends, # List of int end depot # model_parameters) parameters = routing.DefaultSearchParameters() # Setting first solution heuristic (cheapest addition). parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # Disabling Large Neighborhood Search, (this is the default behaviour) parameters.local_search_operators.use_path_lns = False parameters.local_search_operators.use_inactive_lns = False # Routing: forbids use of TSPOpt neighborhood, parameters.local_search_operators.use_tsp_opt = False parameters.time_limit_ms = 30 * 1000 # 30 seconds parameters.use_light_propagation = False # parameters.log_search = True # Set the cost function (distance callback) for each arc, homogenious for # all vehicles. routing.SetArcCostEvaluatorOfAllVehicles(dist_fn) # Set vehicle costs for each vehicle, not homogenious. for veh in vehicles.vehicles: routing.SetFixedCostOfVehicle(veh.cost, int(veh.index)) # Add a dimension for vehicle capacities null_capacity_slack = 0 routing.AddDimensionWithVehicleCapacity( dem_fn, # demand callback null_capacity_slack, capacity, # capacity array True, 'Capacity') # Add a dimension for time and a limit on the total time_horizon routing.AddDimension( tot_time_fn, # total time function callback customers.time_horizon, customers.time_horizon, True, 'Time') time_dimension = routing.GetDimensionOrDie('Time') for cust in customers.customers: if cust.tw_open is not None: time_dimension.CumulVar(routing.NodeToIndex(cust.index)).SetRange( cust.tw_open.seconds, cust.tw_close.seconds) """ To allow the dropping of orders, we add disjunctions to all the customer nodes. Each disjunction is a list of 1 index, which allows that customer to be active or not, with a penalty if not. The penalty should be larger than the cost of servicing that customer, or it will always be dropped! """ # To add disjunctions just to the customers, make a list of non-depots. non_depot = set(range(customers.number)) non_depot.difference_update(depotIndices) non_depot.difference_update(depotIndices) penalty = 400000 # The cost for dropping a node from the plan. nodes = [routing.AddDisjunction([int(c)], penalty) for c in non_depot] # This is how you would implement partial routes if you already knew part # of a feasible solution for example: # partial = np.random.choice(list(non_depot), size=(4,5), replace=False) # routing.CloseModel() # partial_list = [partial[0,:].tolist(), # partial[1,:].tolist(), # partial[2,:].tolist(), # partial[3,:].tolist(), # [],[],[],[]] # print(routing.ApplyLocksToAllVehicles(partial_list, False)) # Solve the problem ! assignment = routing.SolveWithParameters(parameters) # The rest is all optional for saving, printing or plotting the solution. if assignment: #print('The Objective Value is {0}'.format(assignment.ObjectiveValue())) buildQGCReturn(routing, assignment, waypointsList, vehicleList, len(depotList)) #plan_output, dropped = vehicle_output_string(routing, assignment) #print(plan_output) #print('dropped nodes: ' + ', '.join(dropped)) # you could print debug information like this: # print(routing.DebugOutputAssignment(assignment, 'Capacity')) #vehicle_routes = {} #for veh in range(vehicles.number): # vehicle_routes[veh] = build_vehicle_route(routing, assignment, customers,veh) else: print('No assignment')
def cvrp(data, set, vehicles, strategy): """Solve the CVRP problem.""" # Instantiate the data problem. data, name = modelData.create_data_model(data, set, vehicles) # Create the routing index manager. manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['depot']) # Create Routing Model. routing = pywrapcp.RoutingModel(manager) # initial plot plot.create_initial_plot(data['points'], name) # 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 Capacity constraint. def demand_callback(from_index): """Returns the demand of the node.""" # Convert from routing variable Index to demands NodeIndex. from_node = manager.IndexToNode(from_index) return data['demands'][from_node] demand_callback_index = routing.RegisterUnaryTransitCallback( demand_callback) routing.AddDimensionWithVehicleCapacity( demand_callback_index, 0, # null capacity slack data['vehicle_capacities'], # vehicle maximum capacities True, # start cumul to zero 'Capacity') # Setting solution heuristic. search_parameters = pywrapcp.DefaultRoutingSearchParameters() if strategy == 'first-solution': search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC) elif strategy == 'local-search': search_parameters.local_search_metaheuristic = ( routing_enums_pb2.LocalSearchMetaheuristic.AUTOMATIC) search_parameters.time_limit.seconds = 20 else: search_parameters.local_search_metaheuristic = ( routing_enums_pb2.LocalSearchMetaheuristic.AUTOMATIC) search_parameters.time_limit.seconds = 25 # search_parameters.local_search_metaheuristic = ( # routing_enums_pb2.LocalSearchMetaheuristic.TABU_SEARCH) # search_parameters.time_limit.seconds = 20 # Solve the problem. assignment = routing.SolveWithParameters(search_parameters) # Print solution. if assignment: vehicle_distance, vehicle_load, text = print.print_solution( data, manager, routing, assignment) routes = getRoutes.get_routes(manager, routing, assignment, data['num_vehicles']) # Display the routes. route_arr = print.print_routes(routes) plot.create_plot(data['points'], routes, vehicle_distance, name) return vehicle_distance, vehicle_load, text, name, route_arr
def main(data, truck_options): # Create the data. # data = create_data_array() locations = data[0] demands = data[1] start_times = data[2] end_times = data[3] volume = data[4] address = data[5] nodes = data[6] num_locations = len(locations) depot = 0 try: num_vehicles = truck_options['number_of_trucks'] except: num_vehicles = 100 search_time_limit = 400000 # Create routing model. if num_locations > 0: # The number of nodes of the VRP is num_locations. # Nodes are indexed from 0 to num_locations - 1. By default the start of # a route is node 0. routing = pywrapcp.RoutingModel(num_locations, num_vehicles, depot) search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() # Callbacks to the distance function and travel time functions here. if num_vehicles == 1: dist_between_locations = CreateDistanceCallbackNEW(locations) else: dist_between_locations = CreateDistanceCallback(locations) # dist_between_locations.matrix = matrix dist_callback = dist_between_locations.Distance routing.SetArcCostEvaluatorOfAllVehicles(dist_callback) demands_at_locations = CreateDemandCallback(demands) demands_callback = demands_at_locations.Demand maximum_dist = int(truck_options['MaxDistancePerVehicle']) NullDistanceStack = 0 fix_start_cumul_to_zero = True distance_check = "Distances" routing.AddDimension(dist_callback, NullDistanceStack, maximum_dist, fix_start_cumul_to_zero, distance_check) # Adding capacity dimension constraints. VehicleCapacity = 0 VolumeCapacity = 0 for i in truck_options['SelectedDeliveryVehicles']: if i['Code'] == 'V400': VehicleCapacity = int(i['WeightAllowed']) VolumeCapacity = int(i['VmWtAllowed']) selected_vehicle = i if VehicleCapacity == 0: for i in truck_options['SelectedDeliveryVehicles']: if i['Code'] == 'V500': VehicleCapacity = int(i['WeightAllowed']) VolumeCapacity = int(i['VmWtAllowed']) selected_vehicle = i if VehicleCapacity == 0: for i in truck_options['SelectedDeliveryVehicles']: if i['Code'] == 'V200': VehicleCapacity = int(i['WeightAllowed']) VolumeCapacity = int(i['VmWtAllowed']) selected_vehicle = i NullCapacitySlack = 0 fix_start_cumul_to_zero = True capacity = "Capacity" routing.AddDimension(demands_callback, NullCapacitySlack, VehicleCapacity, fix_start_cumul_to_zero, capacity) ## Adding Volume constraint volume_at_locations = CreateVolumeCallback(volume) volume_callback = volume_at_locations.Volume NullVolumeSlack = 0 fix_start_cumul_to_zero = True volumes = "Volume" routing.AddDimension(volume_callback, NullVolumeSlack, VolumeCapacity, fix_start_cumul_to_zero, volumes) # Add time dimension. time_per_demand_unit = int(truck_options['MHaltTimeAtDropPoint']) * 60 horizon = 24 * 3600 time = "Time" speed = int(truck_options['AverageSpeedOfVehicle']) service_times = CreateServiceTimeCallback(demands, time_per_demand_unit) service_time_callback = service_times.ServiceTime travel_times = CreateTravelTimeCallback(dist_callback, speed) travel_time_callback = travel_times.TravelTime total_times = CreateTotalTimeCallback(service_time_callback, travel_time_callback) total_time_callback = total_times.TotalTime duration = end_times[0] - start_times[0] routing.AddDimension( total_time_callback, # total time function callback horizon, duration, False, time) # Add time window constraints. time_dimension = routing.GetDimensionOrDie(time) for location in range(1, num_locations): start = start_times[location] - start_times[0] end = start + end_times[location] - start_times[location] location_idx = routing.NodeToIndex(location) time_dimension.CumulVar(location_idx).SetRange(start, end) routing.AddToAssignment(time_dimension.SlackVar(location_idx)) for vehicle_id in xrange(num_vehicles): index = routing.Start(vehicle_id) time_dimension.CumulVar(index).SetRange(0, duration) routing.AddToAssignment(time_dimension.SlackVar(index)) # Solve displays a solution if any. # search_parameters.time_limit_ms = 30000 # search_parameters.solution_limit = 100 # assignment = routing.SolveWithParameters(search_parameters) if assignment: size = len(locations) # Solution cost. # print "Total distance of all routes: " + str(assignment.ObjectiveValue()) + "\n" # Inspect solution. capacity_dimension = routing.GetDimensionOrDie(capacity) time_dimension = routing.GetDimensionOrDie(time) volume_dimension = routing.GetDimensionOrDie(volumes) distance_dimension = routing.GetDimensionOrDie(distance_check) plans = [] distances = [] cum_distance = [] address1 = [] truck = [] volume1 = [] cum_volume = [] time_range = [] weight = [] cum_weight = [] for vehicle_nbr in range(num_vehicles): index = routing.Start(vehicle_nbr) plan_output = 'Route {0}:'.format(vehicle_nbr) plan1 = [] dist = 0 number_del = 0 while not routing.IsEnd(index): node_index = routing.IndexToNode(index) number_del += 1 if node_index == 0: node_prev = 0 dist += 0 dist1 = 0 else: dist1 = dist_between_locations.matrix[node_index][ node_prev] dist += dist1 node_prev = node_index distances.append(dist1) cum_distance.append(dist) address1.append(address[node_index]) truck.append("Truck" + str(vehicle_nbr + 1)) weight.append(demands[node_index]) volume1.append(volume[node_index]) dist_var = distance_dimension.CumulVar(index) load_var = capacity_dimension.CumulVar(index) vol_var = volume_dimension.CumulVar(index) time_var = time_dimension.CumulVar(index) cum_weight.append(assignment.Value(load_var)) cum_volume.append(assignment.Value(vol_var)) time_range.append( str(assignment.Min(time_var)) + " - " + str(assignment.Max(time_var))) plan1.append( (nodes[node_index], dist1, assignment.Value(load_var), assignment.Value(vol_var), str(assignment.Min(time_var) + start_times[0]), str(assignment.Max(time_var) + start_times[0]), locations[node_index], node_index)) plan_output += \ " {node_index} Load({load}) Vol({vol}) Dist({dist}) Time({tmin}, {tmax}) -> ".format( node_index=node_index, load=assignment.Value(load_var), vol = assignment.Value(vol_var), dist = dist, tmin=str(assignment.Min(time_var)), tmax=str(assignment.Max(time_var))) index = assignment.Value(routing.NextVar(index)) node_index = routing.IndexToNode(index) dist1 = dist_between_locations.matrix[node_index][node_prev] dist += dist1 node_prev = node_index distances.append(dist1) cum_distance.append(dist) address1.append(address[node_index]) truck.append("Truck" + str(vehicle_nbr + 1)) weight.append(demands[node_index]) volume1.append(volume[node_index]) dist_var = distance_dimension.CumulVar(index) load_var = capacity_dimension.CumulVar(index) vol_var = volume_dimension.CumulVar(index) time_var = time_dimension.CumulVar(index) cum_weight.append(assignment.Value(load_var)) cum_volume.append(assignment.Value(vol_var)) time_range.append( str(assignment.Min(time_var)) + " - " + str(assignment.Max(time_var))) plan1.append( (nodes[node_index], dist1, assignment.Value(load_var), assignment.Value(vol_var), str(assignment.Min(time_var) + start_times[0]), str(assignment.Max(time_var) + start_times[0]), locations[node_index], node_index)) plan_output += \ " {node_index} Load({load}) Vol({vol}) Dist({dist}) Time({tmin}, {tmax})".format( node_index=node_index, load=assignment.Value(load_var), vol = assignment.Value(vol_var), dist = dist, tmin=str(assignment.Min(time_var)), tmax=str(assignment.Max(time_var))) # print plan_output # # print "\n" # print dist, number_del # print "\n" if len(plan1) == 2 and plan1[1][0] == 0: pass else: plans.append(plan1) else: print 'No solution found.' else: print 'Specify an instance greater than 0.' return (plans, selected_vehicle)
def main(): # Cities #city_names = ['Ghatkesar', 'B N Reddy Nagar', 'Nagole', 'LB Nagar', 'DSNR', 'Champapet', 'SC', 'Boduppal', 'Meerpet', 'Tarnaka', 'Malakpet', 'Hastinapuram', 'Kothapet', 'Ramanthapur', 'Banjara Hills', 'Pocharam', 'Nadergul'] #city_names=stores city_names = city_dist # Distance matrix dist_matrix = dms # dist_matrix=[[ 0, 32358, 19813, 21847, 24806, 36389, 25079, 14146, 36418, # 20957, 25149, 34520, 20128, 21223, 34173, 5716, 39778], # [30517, 0, 9023, 5808, 10374, 7659, 19841, 14838, 5551, # 15719, 13032, 2350, 8345, 12765, 22147, 31482, 6316], # [24709, 9058, 0, 4785, 7722, 10566, 13500, 8497, 10596, # 9378, 10380, 9565, 3067, 8105, 22594, 25675, 14904], # [29751, 4973, 4611, 0, 7114, 5781, 16251, 11247, 5811, # 12129, 9772, 4780, 5818, 9505, 18887, 30716, 10819], # [22064, 8844, 6218, 4512, 0, 4138, 15342, 10339, 7646, # 11220, 4911, 8651, 2627, 4278, 14026, 19489, 14690], # [34340, 7974, 9958, 5051, 4361, 0, 13574, 14130, 4206, # 15011, 5735, 7781, 6418, 6752, 14948, 35305, 10818], # [23772, 20281, 13274, 15308, 13379, 15039, 0, 12282, 19047, # 5848, 10349, 20088, 13590, 13425, 9614, 21197, 26127], # [13681, 16143, 9136, 11170, 12457, 16951, 12240, 0, 16980, # 6653, 12800, 15950, 9452, 8873, 21334, 11106, 21989], # [35606, 5651, 11224, 7383, 8561, 4016, 17394, 16962, 0, # 17843, 9555, 3280, 9920, 10951, 27579, 36571, 8067], # [19293, 15802, 8794, 10829, 10280, 16610, 6022, 6682, 16639, # 0, 9797, 15608, 9110, 8945, 15116, 16718, 21647], # [24165, 13171, 10544, 8838, 4353, 6013, 8863, 12440, 10020, # 10691, 0, 12978, 6953, 6230, 10237, 21590, 16633], # [32495, 2449, 8983, 5692, 10258, 6500, 19725, 14721, 3238, # 15603, 12916, 0, 8229, 12649, 22031, 33460, 8295], # [19437, 8019, 3591, 3686, 4655, 6171, 12715, 7712, 8356, # 8593, 7313, 7826, 0, 7320, 16428, 16862, 13865], # [20308, 12793, 8079, 8460, 3975, 6859, 11377, 8582, 10583, # 7255, 6187, 12600, 6576, 0, 12658, 17732, 18639], # [32769, 33276, 22271, 18998, 14513, 16173, 10628, 21280, 29141, # 14845, 11482, 31892, 17113, 12939, 0, 30194, 33357], # [ 5483, 32298, 17089, 19123, 22082, 24904, 22355, 11423, 24933, # 18233, 22426, 34461, 17405, 18499, 31449, 0, 39718], # [38908, 6109, 14944, 11729, 16295, 11159, 25762, 20758, 8075, # 21640, 18953, 8271, 14266, 18686, 32675, 39873, 0]] # tsp_size = len(city_names) num_routes = 1 depot = 0 # Create routing model if tsp_size > 0: routing = pywrapcp.RoutingModel(tsp_size, num_routes, depot) search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() # Create the distance callback. dist_callback = create_distance_callback(dist_matrix) routing.SetArcCostEvaluatorOfAllVehicles(dist_callback) # Solve the problem. assignment = routing.SolveWithParameters(search_parameters) if assignment: # Solution distance. print("Total distance: " + str(assignment.ObjectiveValue()) + " miles\n") # Display the solution. # Only one route here; otherwise iterate from 0 to routing.vehicles() - 1 route_number = 0 index = routing.Start( route_number) # Index of the variable for the starting node. route = '' while not routing.IsEnd(index): # Convert variable indices to node indices in the displayed route. shortest_path.append(city_names[routing.IndexToNode( index)]) ###list for solution route += str(city_names[routing.IndexToNode(index)]) + ' --> ' index = assignment.Value(routing.NextVar(index)) route += str(city_names[routing.IndexToNode(index)]) print("Route:\n\n" + route) else: print('No solution found.') else: print('Specify an instance greater than 0.')
def main(): """Entry point of the program""" # Instantiate the data problem. data = create_data_model() # Create Routing Model routing = pywrapcp.RoutingModel(data["num_locations"], data["num_vehicles"], data["depot"]) # Define weight of each edge distance_callback = create_distance_callback(data) routing.SetArcCostEvaluatorOfAllVehicles(distance_callback) # Add Capacity constraint demand_callback = create_demand_callback(data) add_capacity_constraints(routing, data, demand_callback) # Add Time Window constraint time_callback = distance_callback #create_time_callback(data) add_time_window_constraints(routing, data, time_callback) # WEN TODO: What is it can deliver to SC_1 or SC_2 or SC_3 #routing.AddPickupAndDelivery(LocationEnum.PICKUP_0.value, LocationEnum.SC_1_TAKEIN_0.value) v0_default_node_idx = routing.NodeToIndex(8) v0_end_node_idx = routing.NodeToIndex(11) routing.solver().Add( routing.VehicleVar(routing.Start(0)) == routing.VehicleVar( LocationEnum.V0_DEFAULT_START.value)) routing.Start(0).SetRange(0, 110) #routing.solver().Add(routing.VehicleVar(routing.End(0)) == routing.VehicleVar(LocationEnum.V0_END.value)) #routing.solver().Add(routing.VehicleVar(v0_end_node_idx) == routing.VehicleVar(routing.End(0))) v1_default_node_idx = routing.NodeToIndex(9) v1_end_node_idx = routing.NodeToIndex(12) routing.solver().Add( routing.VehicleVar(v1_default_node_idx) == routing.VehicleVar( routing.Start(1))) #routing.solver().Add(routing.VehicleVar(v1_end_node_idx) == routing.VehicleVar(routing.End(1))) v2_default_node_idx = routing.NodeToIndex(10) routing.solver().Add( routing.VehicleVar(v2_default_node_idx) == routing.VehicleVar( routing.Start(2))) # TODO: punish for miss one in the list? or punish for couldn't do any one in the list? routing.AddDisjunction( [LocationEnum.SC_1_TAKEIN_0.value, LocationEnum.SC_2_TAKEIN_0.value], 100000) routing.AddDisjunction( [LocationEnum.SC_1_TAKEIN_1.value, LocationEnum.SC_2_TAKEIN_1.value], 100000) routing.AddDisjunction([LocationEnum.RETURN_0.value], 100000) routing.AddDisjunction([LocationEnum.RETURN_1.value], 100000) routing.AddDisjunction([LocationEnum.PICKUP_0.value], 100000) routing.AddDisjunction([LocationEnum.PICKUP_1.value], 100000) # routing.AddDisjunction([LocationEnum.SC_1_TAKEIN_0.value], 10000) routing.AddDisjunction([LocationEnum.SC_2.value], 0) # we actually don't need SC_2 # ??? not working? routing.AddPickupAndDelivery(LocationEnum.SC_2_RETURN_0.value, LocationEnum.RETURN_0.value) routing.AddPickupAndDelivery(LocationEnum.SC_1_RETURN_1.value, LocationEnum.RETURN_1.value) #routing.AddPickupAndDelivery(LocationEnum.V0_DEFAULT_START.value, LocationEnum.V0_END.value) #routing.AddPickupAndDelivery(LocationEnum.V2_DEFAULT_START.value, LocationEnum.V2_END.value) #routing.AddPickupAndDelivery(LocationEnum.SC_1_TAKEIN_0.value, LocationEnum.SC_1_RETURN_1.value) # v0_end_node_idx = routing.NodeToIndex(11) # routing.solver().Add(routing.VehicleVar(v0_end_node_idx) == routing.VehicleVar(routing.End(0))) # # v1_end_node_idx = routing.NodeToIndex(12) # routing.solver().Add(routing.VehicleVar(v1_end_node_idx) == routing.VehicleVar(routing.End(1))) # # v2_end_node_idx = routing.NodeToIndex(13) # routing.solver().Add(routing.VehicleVar(v2_end_node_idx) == routing.VehicleVar(routing.End(2))) # Setting first solution heuristic (cheapest addition). search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_MOST_CONSTRAINED_ARC) # routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # routing_enums_pb2.FirstSolutionStrategy.ALL_UNPERFORMED) # Solve the problem. assignment = routing.SolveWithParameters(search_parameters) if assignment: printer = print_solution(data, routing, assignment)
def run(): """Solve the problem""" # Create a set of customer, (and depot) stops. customers = Customers( num_stops=50, min_demand=1, max_demand=15, box_size=40, min_tw=3, max_tw=6 ) # Create a list of inhomgenious vehicle capacities as integer units. capacity = [50, 75, 100, 125, 150, 175, 200, 250] # Create a list of inhomogeneous fixed vehicle costs. cost = [int(100 + 2 * np.sqrt(c)) for c in capacity] # Create a set of vehicles, the number set by the length of capacity. vehicles = Vehicles(capacity=capacity, cost=cost) # check to see that the problem is feasible, if we don't have enough # vehicles to cover the demand, there is no point in going further. assert (customers.get_total_demand() < vehicles.get_total_capacity()) # Set the starting nodes, and create a callback fn for the starting node. start_fn = vehicles.return_starting_callback( customers, same_start_finish=False ) # Create the routing index manager. manager = pywrapcp.RoutingIndexManager( customers.number, # int number vehicles.number, # int number vehicles.starts, # List of int start depot vehicles.ends) # List of int end depot customers.set_manager(manager) # Set model parameters model_parameters = pywrapcp.DefaultRoutingModelParameters() # The solver parameters can be accessed from the model parameters. For example : # model_parameters.solver_parameters.CopyFrom( # pywrapcp.Solver.DefaultSolverParameters()) # model_parameters.solver_parameters.trace_propagation = True # Make the routing model instance. routing = pywrapcp.RoutingModel(manager, model_parameters) parameters = pywrapcp.DefaultRoutingSearchParameters() # Setting first solution heuristic (cheapest addition). parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # Routing: forbids use of TSPOpt neighborhood, (this is the default behaviour) parameters.local_search_operators.use_tsp_opt = pywrapcp.BOOL_FALSE # Disabling Large Neighborhood Search, (this is the default behaviour) parameters.local_search_operators.use_path_lns = pywrapcp.BOOL_FALSE parameters.local_search_operators.use_inactive_lns = pywrapcp.BOOL_FALSE parameters.time_limit.seconds = 10 parameters.use_full_propagation = True # parameters.log_search = True # Create callback fns for distances, demands, service and transit-times. dist_fn = customers.return_dist_callback() dist_fn_index = routing.RegisterTransitCallback(dist_fn) dem_fn = customers.return_dem_callback() dem_fn_index = routing.RegisterUnaryTransitCallback(dem_fn) # Create and register a transit callback. serv_time_fn = customers.make_service_time_call_callback() transit_time_fn = customers.make_transit_time_callback() def tot_time_fn(from_index, to_index): """ The time function we want is both transit time and service time. """ # Convert from routing variable Index to distance matrix NodeIndex. from_node = manager.IndexToNode(from_index) to_node = manager.IndexToNode(to_index) return serv_time_fn( from_node, to_node ) + transit_time_fn( from_node, to_node ) tot_time_fn_index = routing.RegisterTransitCallback(tot_time_fn) # Set the cost function (distance callback) for each arc, homogeneous for # all vehicles. routing.SetArcCostEvaluatorOfAllVehicles(dist_fn_index) # Set vehicle costs for each vehicle, not homogeneous. for veh in vehicles.vehicles: routing.SetFixedCostOfVehicle(veh.cost, int(veh.index)) # Add a dimension for vehicle capacities null_capacity_slack = 0 routing.AddDimensionWithVehicleCapacity( dem_fn_index, # demand callback null_capacity_slack, capacity, # capacity array True, 'Capacity') # Add a dimension for time and a limit on the total time_horizon routing.AddDimension( tot_time_fn_index, # total time function callback customers.time_horizon, customers.time_horizon, True, 'Time') time_dimension = routing.GetDimensionOrDie('Time') for cust in customers.customers: if cust.tw_open is not None: time_dimension.CumulVar(manager.NodeToIndex(cust.index)).SetRange( cust.tw_open.seconds, cust.tw_close.seconds) """ To allow the dropping of orders, we add disjunctions to all the customer nodes. Each disjunction is a list of 1 index, which allows that customer to be active or not, with a penalty if not. The penalty should be larger than the cost of servicing that customer, or it will always be dropped! """ # To add disjunctions just to the customers, make a list of non-depots. non_depot = set(range(customers.number)) non_depot.difference_update(vehicles.starts) non_depot.difference_update(vehicles.ends) penalty = 400000 # The cost for dropping a node from the plan. nodes = [ routing.AddDisjunction([ manager.NodeToIndex(c) ], penalty) for c in non_depot ] # This is how you would implement partial routes if you already knew part # of a feasible solution for example: # partial = np.random.choice(list(non_depot), size=(4,5), replace=False) # routing.CloseModel() # partial_list = [partial[0,:].tolist(), # partial[1,:].tolist(), # partial[2,:].tolist(), # partial[3,:].tolist(), # [],[],[],[]] # print(routing.ApplyLocksToAllVehicles(partial_list, False)) # Solve the problem ! assignment = routing.SolveWithParameters(parameters) # The rest is all optional for saving, printing or plotting the solution. if assignment: # # save the assignment, (Google Protobuf format) # save_file_base = os.path.realpath(__file__).split('.')[0] # if routing.WriteAssignment(save_file_base + '_assignment.ass'): # print('succesfully wrote assignment to file ' + save_file_base + # '_assignment.ass') print('The Objective Value is {0}'.format(assignment.ObjectiveValue())) plan_output, dropped = vehicle_output_string( manager, routing, assignment ) print(plan_output) print('dropped nodes: ' + ', '.join(dropped)) # you could print debug information like this: # print(routing.DebugOutputAssignment(assignment, 'Capacity')) vehicle_routes = {} for veh in range(vehicles.number): vehicle_routes[veh] = build_vehicle_route( manager, routing, assignment, customers, veh ) # Plotting of the routes in matplotlib. fig = plt.figure() ax = fig.add_subplot(111) # Plot all the nodes as black dots. clon, clat = zip(*[(c.lon, c.lat) for c in customers.customers]) ax.plot(clon, clat, 'k.') # plot the routes as arrows plot_vehicle_routes(vehicle_routes, ax, customers, vehicles) plt.show() else: print('No assignment')
def mySolver(): """Solve the CVRP problem.""" # Instantiate the data problem. # [START data] data = create_data_model() # [END data] # Create the routing index manager. # [START index_manager] manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], # data['depot'], data['starts'], data['ends'] ) # [END index_manager] # Create Routing Model. # [START routing_model] routing = pywrapcp.RoutingModel(manager) # [END routing_model] # Create and register a transit callback. # [START 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) # [END transit_callback] # Define cost of each arc. # [START arc_cost] routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) # [END arc_cost] # Add Distance constraint. # dimension_name = 'Distance' # routing.AddDimension( # transit_callback_index, # 0, # no slack # 3000, # vehicle maximum travel distance # True, # start cumul to zero # dimension_name) # distance_dimension = routing.GetDimensionOrDie(dimension_name) # distance_dimension.SetGlobalSpanCostCoefficient(100) # Add Capacity constraint. # [START capacity_constraint] def demand_callback(from_index): """Returns the demand of the node.""" # Convert from routing variable Index to demands NodeIndex. from_node = manager.IndexToNode(from_index) return data['demands'][from_node] demand_callback_index = routing.RegisterUnaryTransitCallback( demand_callback) routing.AddDimensionWithVehicleCapacity( demand_callback_index, 0, # null capacity slack data['vehicle_capacities'], # vehicle maximum capacities True, # start cumul to zero 'Capacity') # [END capacity_constraint] # Add Time Window constraint time_evaluator_index = routing.RegisterTransitCallback( partial(create_time_evaluator(data), manager)) add_time_window_constraints(routing, manager, data, time_evaluator_index) penalty = 20000 for node in range(0, len(data['distance_matrix'])): if manager.NodeToIndex(node) == -1: continue routing.AddDisjunction([manager.NodeToIndex(node)], penalty) # Setting first solution heuristic. # [START parameters] # Setting first solution heuristic (cheapest addition). search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # pylint: disable=no-membe # [END parameters] # Solve the problem. # [START solve] assignment = routing.SolveWithParameters(search_parameters) # [END solve] data['previous_solution'] = assignment # Print solution on console. # [START print_solution] if assignment: print_solution(data, manager, routing, assignment) # [END print_solution] print('\n\n\n') ### Running new instance #### data['demands'][14] = 0 new_solution = routing.SolveFromAssignmentWithParameters(data['previous_solution'] , search_parameters) if new_solution: print('New solution from previous one : ') print_solution(data, manager , routing, new_solution)
def solve(self): logger.info("Calculating solution.") depot = 0 num_locations = len(self.locations) routing = pywrapcp.RoutingModel(num_locations, self.num_vehicles, depot) search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() # Set heuristics and time limit search_parameters.local_search_metaheuristic = routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH search_parameters.time_limit_ms = self.time_limit_ms # Try to minimize the amount of vehicles node_indices = [] for i in range(len(self.locations)): node_indices.append(routing.IndexToNode(i)) # Add additional cost for each vehicle. routing.AddSoftSameVehicleConstraint(node_indices, 100000) # Set cost function. We use total distance. cost_function = self.__cost_function routing.SetArcCostEvaluatorOfAllVehicles(cost_function) # Add time dimension. total_time_callback = self.__total_time_callback # I honestly have no idea why this is necessary, but if I don't do it, a segmentation fault is thrown. time_horizon = 24 * 3600 # Used as both the upper bound for the slack variable (maximum amount of time between 2 nodes) and the upper bound for the cummulative variable (total maximum amount of time). time = "Time" time_fix_start_cumul_to_zero_time = True routing.AddDimension(total_time_callback, time_horizon, time_horizon, time_fix_start_cumul_to_zero_time, time) # Add time window constraints. time_dimension = routing.GetDimensionOrDie(time) for location in range(1, num_locations): start = self.time_windows[location][0] end = self.time_windows[location][1] time_dimension.CumulVar(location).SetRange(start, end) # Set a cost coefficient on time. This should minimize "idle" time of vehicles. time_dimension.SetSpanCostCoefficientForAllVehicles(2) # Solve the problem. assignment = routing.SolveWithParameters(search_parameters) # No solution, nothing to return. if not assignment: return None # Create the solution time_dimension = routing.GetDimensionOrDie(time); vehicles = [] for vehicle_nbr in range(self.num_vehicles): index = routing.Start(vehicle_nbr) nodes = [] while not routing.IsEnd(index): node_index = routing.IndexToNode(index) time_var = time_dimension.CumulVar(index) nodes.append(Node(self.locations[node_index], assignment.Value(time_var))) index = assignment.Value(routing.NextVar(index)) node_index = routing.IndexToNode(index) time_var = time_dimension.CumulVar(index) nodes.append(Node(self.locations[node_index], assignment.Value(time_var))) if len(nodes) > 2: # 2 is from start to finish directly vehicles.append(Vehicle(nodes)) return Solution(vehicles)
def solve_tsp(all_elements, ground_nodes, node_points, printed, initial_point, final_point, bidirectional=False, layers=True, max_time=30, visualize=True, verbose=False): # https://developers.google.com/optimization/routing/tsp # https://developers.google.com/optimization/reference/constraint_solver/routing/RoutingModel # http://www.math.uwaterloo.ca/tsp/concorde.html # https://developers.google.com/optimization/reference/python/constraint_solver/pywrapcp # AddDisjunction # TODO: pick up and delivery # TODO: time window for skipping elements # TODO: Minimum Spanning Tree (MST) bias # TODO: time window constraint to ensure connected # TODO: reuse by simply swapping out the first vertex # arc-routing from ortools.constraint_solver import routing_enums_pb2, pywrapcp from extrusion.visualization import draw_ordered, draw_model start_time = time.time() assert initial_point is not None remaining = all_elements - printed #printed_nodes = compute_printed_nodes(ground_nodes, printed) if not remaining: cost = get_distance(initial_point, final_point) return [], cost # TODO: use as a lower bound total_distance = compute_element_distance(node_points, remaining) # TODO: some of these are invalid still level_from_node, cost_from_edge, sequence = greedily_plan( all_elements, node_points, ground_nodes, remaining, initial_point) if sequence is None: return None, INF extrusion_edges = set() point_from_vertex = {INITIAL_NODE: initial_point, FINAL_NODE: final_point} frame_nodes = nodes_from_elements(remaining) min_level = min(level_from_node[n] for n in frame_nodes) max_level = max(level_from_node[n] for n in frame_nodes) frame_keys = set() keys_from_node = defaultdict(set) for element in remaining: mid = (element, element) point_from_vertex[mid] = get_midpoint(node_points, element) for node in element: key = (element, node) point_from_vertex[key] = node_points[node] frame_keys.add(key) keys_from_node[node].add(key) for reverse in [True, False]: directed = reverse_element(element) if reverse else element node1, node2 = directed #delta = node_points[node2] - node_points[node1] #pitch = get_pitch(delta) #upward = -SUPPORT_THETA <= pitch # theta = angle_between(delta, [0, 0, -1]) # upward = theta < (np.pi / 2 - SUPPORT_THETA) #if (directed in tree_elements): # or upward: if bidirectional or (directed in cost_from_edge): # Add edges from anything that is roughly the correct cost start = (element, node1) end = (element, node2) extrusion_edges.update({(start, mid), (mid, end)}) for node in keys_from_node: for edge in product(keys_from_node[node], repeat=2): extrusion_edges.add(edge) # Key thing is partial order on buckets of elements to adhere to height # Connect v2 to v1 if v2 is the same level # Traversing an edge might move to a prior level (but at most one) transit_edges = set() for directed in product(frame_keys, repeat=2): key1, key2 = directed element1, node1 = key1 #level1 = min(level_from_node[n] for n in element1) level1 = level_from_node[get_other_node(node1, element1)] _, node2 = key2 level2 = level_from_node[node2] if level2 in [level1, level1 + 1]: # TODO: could bucket more coarsely transit_edges.add(directed) for key in frame_keys: _, node = key if level_from_node[node] == min_level: transit_edges.add((INITIAL_NODE, key)) if level_from_node[node] in [max_level, max_level - 1]: transit_edges.add((key, FINAL_NODE)) # TODO: can also remove restriction that elements are printed in a single direction if not layers: transit_edges.update( product(frame_keys | {INITIAL_NODE, FINAL_NODE}, repeat=2)) # TODO: apply to greedy as well key_from_index = list( {k for pair in extrusion_edges | transit_edges for k in pair}) edge_weights = { pair: INVALID for pair in product(key_from_index, repeat=2) } for k1, k2 in transit_edges | extrusion_edges: p1, p2 = point_from_vertex[k1], point_from_vertex[k2] edge_weights[k1, k2] = get_distance(p1, p2) #edge_weights.update({e: 0. for e in extrusion_edges}) # frame edges are free edge_weights[FINAL_NODE, INITIAL_NODE] = 0. edge_weights[INITIAL_NODE, FINAL_NODE] = INVALID # Otherwise might be backward print( 'Elements: {} | Vertices: {} | Edges: {} | Structure: {:.3f} | Min Level {} | Max Level: {}' .format(len(remaining), len(key_from_index), len(edge_weights), total_distance, min_level, max_level)) index_from_key = dict(map(reversed, enumerate(key_from_index))) num_vehicles, depot = 1, index_from_key[INITIAL_NODE] manager = pywrapcp.RoutingIndexManager(len(key_from_index), num_vehicles, depot) #[depot], [depot]) solver = pywrapcp.RoutingModel(manager) cost_from_index = {} for (k1, k2), weight in edge_weights.items(): i1, i2 = index_from_key[k1], index_from_key[k2] cost_from_index[i1, i2] = int(math.ceil(SCALE * weight)) solver.SetArcCostEvaluatorOfAllVehicles( solver.RegisterTransitCallback( lambda i1, i2: cost_from_index[manager.IndexToNode( i1), manager.IndexToNode(i2)])) # from -> to # sequence = plan_stiffness(None, None, node_points, ground_nodes, elements, # initial_position=initial_point, stiffness=False, max_backtrack=INF) initial_order = [] #initial_order = [INITIAL_NODE] # Start and end automatically included for directed in sequence: node1, node2 = directed element = get_undirected(remaining, directed) initial_order.extend([ (element, node1), (element, element), (element, node2), ]) initial_order.append(FINAL_NODE) #initial_order.append(INITIAL_NODE) initial_route = [index_from_key[key] for key in initial_order] #index = initial_route.index(0) #initial_route = initial_route[index:] + initial_route[:index] + [0] initial_solution = solver.ReadAssignmentFromRoutes( [initial_route], ignore_inactive_indices=True) assert initial_solution is not None #print_solution(manager, solver, initial_solution) #print(solver.GetAllDimensionNames()) #print(solver.ComputeLowerBound()) objective = initial_solution.ObjectiveValue() / SCALE invalid = int(objective / INVALID) order = parse_solution(solver, manager, key_from_index, initial_solution)[:-1] ordered_pairs = get_pairs(order) cost = sum(edge_weights[pair] for pair in ordered_pairs) #print('Initial solution | Invalid: {} | Objective: {:.3f} | Cost: {:.3f} | Duration: {:.3f}s'.format( # invalid, objective, cost, elapsed_time(start_time))) if False and visualize: # and invalid remove_all_debug() draw_model(printed, node_points, None, color=BLACK) draw_point(initial_point, color=BLACK) draw_point(final_point, color=GREEN) for pair in ordered_pairs: if edge_weights[pair] == INVALID: for key in pair: draw_point(point_from_vertex[key], color=RED) draw_ordered(ordered_pairs, point_from_vertex) wait_for_user() # TODO: pause only if viewer #sequence = extract_sequence(level_from_node, remaining, ordered_pairs) #print(compute_sequence_distance(node_points, sequence, start=initial_point, end=final_point), total_distance+cost) #print([cost_from_edge[edge] for edge in sequence]) #return sequence, cost start_time = time.time() search_parameters = pywrapcp.DefaultRoutingSearchParameters() #search_parameters.solution_limit = 1 search_parameters.time_limit.seconds = int(max_time) search_parameters.log_search = verbose # AUTOMATIC | PATH_CHEAPEST_ARC | LOCAL_CHEAPEST_ARC | GLOBAL_CHEAPEST_ARC | LOCAL_CHEAPEST_INSERTION #search_parameters.first_solution_strategy = ( # routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC) # AUTOMATIC | GREEDY_DESCENT | GUIDED_LOCAL_SEARCH | SIMULATED_ANNEALING | TABU_SEARCH | OBJECTIVE_TABU_SEARCH #search_parameters.local_search_metaheuristic = ( # routing_enums_pb2.LocalSearchMetaheuristic.GREEDY_DESCENT) #solution = solver.SolveWithParameters(search_parameters) solution = solver.SolveFromAssignmentWithParameters( initial_solution, search_parameters) #print_solution(manager, solver, solution) print('Status: {} | Text: {}'.format(solver.status(), STATUS[solver.status()])) if not solution: print('Failure! Duration: {:.3f}s'.format(elapsed_time(start_time))) return None, INF objective = solution.ObjectiveValue() / SCALE invalid = int(objective / INVALID) order = parse_solution(solver, manager, key_from_index, solution)[:-1] ordered_pairs = get_pairs(order) # + [(order[-1], order[0])] #cost = compute_element_distance(point_from_vertex, ordered_pairs) cost = sum(edge_weights[pair] for pair in ordered_pairs) print( 'Final solution | Invalid: {} | Objective: {:.3f} | Cost: {:.3f} | Duration: {:.3f}s' .format(invalid, objective, cost, elapsed_time(start_time))) sequence = extract_sequence(level_from_node, remaining, ordered_pairs) #print(compute_sequence_distance(node_points, sequence, start=initial_point, end=final_point)) #, total_distance+cost) #print(sequence) violations = 0 printed_nodes = compute_printed_nodes(ground_nodes, printed) for directed in sequence: if directed[0] not in printed_nodes: #print(directed) violations += 1 printed_nodes.update(directed) print('Violations:', violations) if visualize: # TODO: visualize by weight remove_all_debug() draw_model(printed, node_points, None, color=BLACK) draw_point(initial_point, color=BLACK) draw_point(final_point, color=GREEN) #tour_pairs = ordered_pairs + get_pairs(list(reversed(order))) #draw_model(extrusion_edges - set(tour_pairs), point_from_vertex, ground_nodes, color=BLACK) draw_ordered(ordered_pairs, point_from_vertex) wait_for_user() if sequence is None: return None, INF #print([cost_from_edge[edge] for edge in sequence]) return sequence, cost
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 3000, # vehicle maximum travel distance True, # start cumul to zero dimension_name) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) def demand_callback(from_index): """Returns the demand of the node.""" # Convert from routing variable Index to demands NodeIndex. from_node = manager.IndexToNode(from_index) return data['demands'][from_node] demand_callback_index = routing.RegisterUnaryTransitCallback( demand_callback) routing.AddDimensionWithVehicleCapacity( demand_callback_index, 0, # null capacity slack data['vehicle_capacities'], # vehicle maximum capacities True, # start cumul to zero 'Capacity') # 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)
def main(): """Solve the VRP with time windows.""" # Instantiate the data problem. data = create_data_model() # Create the routing index manager. manager = pywrapcp.RoutingIndexManager(len(data['time_matrix']), data['num_vehicles'], data['depot']) # Create Routing Model. routing = pywrapcp.RoutingModel(manager) # Create and register a transit callback. def time_callback(from_index, to_index): """Returns the travel time between the two nodes.""" # Convert from routing variable Index to time matrix NodeIndex. from_node = manager.IndexToNode(from_index) to_node = manager.IndexToNode(to_index) return data['time_matrix'][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(time_callback) # Define cost of each arc. routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) # Add Time Windows constraint. time = 'Time' routing.AddDimension( transit_callback_index, 15, # allow waiting time 600, # maximum time per vehicle True, # Don't force start cumul to zero. time) time_dimension = routing.GetDimensionOrDie(time) # Add time window constraints for each location except depot. for location_idx, time_window in enumerate(data['time_windows']): if location_idx == 0: continue index = manager.NodeToIndex(location_idx) time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1]) # Add time window constraints for each vehicle start node. for vehicle_id in range(data['num_vehicles']): index = routing.Start(vehicle_id) time_dimension.CumulVar(index).SetRange(data['time_windows'][0][0], data['time_windows'][0][1]) # Instantiate route start and end times to produce feasible times. for i in range(data['num_vehicles']): routing.AddVariableMinimizedByFinalizer( time_dimension.CumulVar(routing.Start(i))) routing.AddVariableMinimizedByFinalizer( time_dimension.CumulVar(routing.End(i))) # 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)
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['starts'], data['ends']) # Create Routing Model. routing = pywrapcp.RoutingModel(manager) '''Create and register a transit callback. The distance matrix records the direct distances between the nodes. The distance callback can do some extra manipulations on top of what's recorded in the distance matrix''' def distance_callback(from_index, to_index): """Returns the distance between the two nodes. And also sets the cost of traveling between nodes (by routing.SetArcCostEvaluatorOfAllVehicles). and passes the cost to the solver""" # 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(edge) in the graph using the distance callback routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) dimension_name2 = 'Stops' car_capacity_callback_index = routing.RegisterUnaryTransitCallback( lambda index: 1) '''AddDimension applies dimension to all vehicles, AddDimensionWithVehicleCapacity can take a vector of capacities and apply them to corresponding vehicles)''' routing.AddDimension( car_capacity_callback_index, 0, # null capacity slack 3, # vehicle maximum number of stops True, # start cumul to zero 'Stops') # allow to drop nodes penalty = 15000 for node in range(1, len(data['distance_matrix'])): routing.AddDisjunction([manager.NodeToIndex(node)], penalty) # Setting first solution heuristic. search_parameters = pywrapcp.DefaultRoutingSearchParameters( ) # search strategy search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # Solve the problem. solution = routing.SolveWithParameters(search_parameters) if not solution: print("No solution") # Print solution on console. if solution: route_dict = print_solution(data, manager, routing, solution) driver_map = firebase.route(route_dict) driver_map1 = firebase.stringify(driver_map) firebase.add_to_db(driver_map1) rider_map = firebase.create_rider_map(driver_map) firebase.add_to_db_rider(rider_map)
def main(): """Solve the CVRP problem.""" # Instantiate the data problem. data = create_data_model() # Create the routing index manager. manager = pywrapcp.RoutingIndexManager(len(data['tokens']), 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 10 transit_callback_index = routing.RegisterTransitCallback(distance_callback) routing.AddDimension( transit_callback_index, 0, # null slack 3000, # maximum distance per vehicle True, # start cumul to zero "distance") distance_dimension = routing.GetDimensionOrDie("distance") distance_dimension.SetGlobalSpanCostCoefficient(100) # Define cost of each arc. routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) # Add Token constraint. def token_callback(from_index): """Returns the number of token consumed by the node.""" # Convert from routing variable Index to tokens NodeIndex. from_node = manager.IndexToNode(from_index) return data['tokens'][from_node] token_callback_index = routing.RegisterUnaryTransitCallback(token_callback) routing.AddDimensionWithVehicleCapacity( token_callback_index, 0, # null capacity slack data['vehicle_tokens'], # vehicle maximum tokens False, # start cumul to zero 'Token') # Add constraint: special node can only be visited if token remaining is zero token_dimension = routing.GetDimensionOrDie('Token') for node in range(1, 6): index = manager.NodeToIndex(node) routing.solver().Add(token_dimension.CumulVar(index) == 0) # Setting first solution heuristic. search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) search_parameters.local_search_metaheuristic = ( routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) search_parameters.time_limit.FromSeconds(1) # Solve the problem. solution = routing.SolveWithParameters(search_parameters) # Print solution on console. if solution: print_solution(manager, routing, solution) else: print("No solution found !")
def main(): """Solve the CVRP problem.""" # Instantiate the data problem. data = create_data_model() time_matrix = compute_euclidean_distance_matrix(data['locations']) # Create the routing index manager. manager = pywrapcp.RoutingIndexManager(len(data['time_windows']), data['num_vehicles'], data['depot']) # Create Routing Model. routing = pywrapcp.RoutingModel(manager) # Create and register a transit callback. def time_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 time_matrix[from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(time_callback) # Define cost of each arc. routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) # Add Time Windows constraint. time = 'Time' routing.AddDimension( transit_callback_index, 10, # allow waiting time 100, # maximum time per vehicle False, # Don't force start cumul to zero. time) time_dimension = routing.GetDimensionOrDie(time) # Add time window constraints for each location except depot. for location_idx, time_window in enumerate(data['time_windows']): if location_idx == 0: continue index = manager.NodeToIndex(location_idx) time_dimension.CumulVar(index).SetRange(data['time_windows'][0][0], data['time_windows'][1][1]) # Add time window constraints for each vehicle start node. for vehicle_id in range(data['num_vehicles']): index = routing.Start(vehicle_id) time_dimension.CumulVar(index).SetRange(data['time_windows'][0][0], data['time_windows'][0][1]) # Instantiate route start and end times to produce feasible times. for i in range(data['num_vehicles']): routing.AddVariableMinimizedByFinalizer( time_dimension.CumulVar(routing.Start(i))) routing.AddVariableMinimizedByFinalizer( time_dimension.CumulVar(routing.End(i))) # Add Capacity constraint. def demand_callback(from_index): """Returns the demand of the node.""" # Convert from routing variable Index to demands NodeIndex. from_node = manager.IndexToNode(from_index) return data['demands'][from_node] demand_callback_index = routing.RegisterUnaryTransitCallback( demand_callback) routing.AddDimensionWithVehicleCapacity( demand_callback_index, 0, # null capacity slack data['vehicle_capacities'], # vehicle maximum capacities False, # start cumul to zero 'Capacity') # Setting first solution heuristic. search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.BEST_INSERTION) search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.local_search_metaheuristic = ( routing_enums_pb2.LocalSearchMetaheuristic.GREEDY_DESCENT) search_parameters.time_limit.FromSeconds(1) # Solve the problem. solution = routing.SolveWithParameters(search_parameters) # Print solution on console. if solution: solution_dict = print_solution(data, manager, routing, solution) coordinates = [ (35, 35), (41, 49), (35, 17), (55, 45), (55, 20), (15, 30), (25, 30), (20, 50), (10, 43), (55, 60), (30, 60), (20, 65), (50, 35), (30, 25), (15, 10), (30, 5), (10, 20), (5, 30), (20, 40), (15, 60), (45, 65), (45, 20), (45, 10), (55, 5), #23 (65, 35), (65, 20), (45, 30), (35, 40), (41, 37), (64, 42), (40, 60), (31, 52), (35, 69), (53, 52), (65, 55), (63, 65), (2, 60), (20, 20), (5, 5), (60, 12), (40, 25), (42, 7), (24, 12), (23, 3), #43 (11, 14), (6, 38), (2, 48), (8, 56), (13, 52), (6, 68), (47, 47), (49, 58), (27, 43), (37, 31), (57, 29), (63, 23), (53, 12), (32, 12), (36, 26), (21, 24), (17, 34), (12, 24), (24, 58), (27, 69), (15, 77), (62, 77), (49, 73), (67, 5), (56, 39), (37, 47), (37, 56), (57, 68), #71 (47, 16), (44, 17), (46, 13), (49, 11), (49, 42), (53, 43), (61, 52), (57, 48), (56, 37), (55, 54), (15, 47), (14, 37), (11, 31), (16, 22), (4, 18), (28, 18), (26, 52), (26, 35), (31, 67), (15, 19), (22, 22), (18, 24), (26, 27), (25, 24), (22, 27), (25, 21), (19, 21), (20, 26), (18, 18), #100 ] X = np.array([x[0] for x in coordinates]) Y = np.array([x[1] for x in coordinates]) f, ax = plt.subplots(figsize=[8, 6]) ax.plot(X, Y, 'ko', markersize=8) ax.plot(X[0], Y[0], 'gX', markersize=30) for i, txt in enumerate(coordinates): ax.text(X[i], Y[i], f"{i}") vehicle_colors = [ "g", "k", "r", "m", "c", "b", "y", "g", "k", "r", "m", "c", "b", "y", "g", "k", "r", "m", "c", "b", "y", "g", "k", "r", "m" ] #warna garis for vehicle in solution_dict: ax.plot(X[solution_dict[vehicle] + [0]], Y[solution_dict[vehicle] + [0]], f'{vehicle_colors[vehicle]}--') ax.set_title("Greedy descent - Best insertion") plt.show()
def main(): data = create_data_array() locations = data[0] demands = data[1] num_locations = len(locations) num_vehicles = 2 #Number of vehicles specified here. #Nodes are indexed from 0 to tsp_size - 1. The depot is the starting node of the route. depot = 0 #Create routing model if num_locations > 0: routing = pywrapcp.RoutingModel(num_locations, num_vehicles, depot) #Define search parameters for how the route will be found. search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() #Can modify search strategy here. #Create the distance callback, which takes two arguments (the from and to node indices) #and returns the distance between these nodes. dist_between_nodes = CreateDistanceCallback(locations) salary_dist_callback = dist_between_nodes.salary_distance special_dist_callback = dist_between_nodes.special_distance routing.SetArcCostEvaluatorOfVehicle(salary_dist_callback, 0) #Distance callback for vehicle 0 passed to solver. routing.SetArcCostEvaluatorOfVehicle(special_dist_callback, 1) #Distance callback for vehicle 1 passed to solver. #Create the demand callback demands_at_nodes = CreateDemandCallback(demands) demands_callback = demands_at_nodes.demand #Add Dimension for demand to routing model. slack_max = 0 vehicle_capacity = 100 fix_start_cumul_to_zero = True demand = "Demand" routing.AddDimension(demands_callback, slack_max, vehicle_capacity, fix_start_cumul_to_zero, demand) #Solve, returns a solution if any. assignment = routing.SolveWithParameters(search_parameters) if assignment: #If a solution was found. #Solution cost. print("Total distance: ", str(assignment.ObjectiveValue()), " units\n") for vehicle_nbr in range(num_vehicles): index = routing.Start(vehicle_nbr) #Sets index to be the index of the starting node of the route of the vehicle given by vehicle_nbr. index_next = assignment.Value(routing.NextVar(index)) route = '' route_length = 0 route_demand = 0 while not routing.IsEnd(index_next): #While there are still nodes left on this path. #Convert variable indices to node indices in the displayed route. node_index = routing.IndexToNode(index) node_index_next = routing.IndexToNode(index_next) route += str(node_index) + " -> " #Add route distance. route_length += locations[node_index][node_index_next][vehicle_nbr] #Add route demand. route_demand += demands[node_index_next] #Advance to the next node. index = index_next index_next = assignment.Value(routing.NextVar(index)) node_index = routing.IndexToNode(index) node_index_next = routing.IndexToNode(index_next) route += str(node_index) + " -> " + str(node_index_next) route_length += locations[node_index][node_index_next][vehicle_nbr] print("Vehicle number: ", vehicle_nbr) print("Vehicle demand: ", route_demand) print("Distance travelled: ", route_length) print("Route:\n\n", route) else: print("No solution found.") else: print("Specify an instance greater than 0.")
def CVRP(addresses, API_key, vehicle_capacities, demands, starts, ends, depot, distance_type='Manhattan', use_1st_solu_strategy = False, scale=1): '''return optimal solution for a Capacity Vehicle Routing Problem (CVRP) that - each vehicle has limited capacity - allow dropped visits (but penalize_dropped visits) - allow setting different start and end locations for each vehicle Para ---- - addresses: a list of real addresses (str) or (x, y)-locations #no longer need...num_vehicles: how many vehicles are used to cover those addresses - vehicle_capacities: a list of capacity of each vehicle - starts: a list of start-location-indices, each element for a vehicle/route - ends: a list of end-location-indices, each element for a vehicle/route - depot: the index of start & end address/location in the case that starts, ends, depot are all None, meaning we allow arbitary start and end location, we need to pre-process distance matrix by adding 1st row & 1st col all 0. - distance_type: 'Euclidean' or 'Manhattan' - use_1st_solu_strategy (bool) - scale (int): since the solver requires the distance_matrix has integer entries, we up-scale distance (says by 100) and take its integer part in order to keep the internal computation accurate. ''' ###--------------------------------------------------------------------------<internal functions start> def create_data_model(distance_matrix, demands, vehicle_capacities, starts, ends, depot): '''create data model, a dictionary with following keys Para ---- distance_matrix(a list of lists of numbers):entry (i,j) represents the distance bw ith row address and jth col address num_vehicles (int): number of vehicles in the fleet depot (int): start & end point for the trip represented by the index of addresses ''' data = {} '''TBD if (starts is None) and (ends is None) and (depot == 0): # the case that allowing arbitary start and end location for each vehicle distance_matrix = [[0]*(len(distance_matrix)+1)] + [[0]+x for x in distance_matrix] demands = [0] + demands''' data['distance_matrix'] = distance_matrix data['demands'] = demands data['vehicle_capacities'] = vehicle_capacities data['num_vehicles'] = len(vehicle_capacities) data['starts'] = starts data['ends'] = ends data['depot'] = depot return data def print_solution(data, manager, routing, solution, scale): """Prints solution on console.""" # 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) # Display routes max_route_distance = 0 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 += ' {0} Load({1}) -> '.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 += ' {0} Load({1})\n'.format(manager.IndexToNode(index), route_load) plan_output += 'Distance of the route: {}m\n'.format(route_distance/scale) plan_output += 'Load of the route: {}\n'.format(route_load) print(plan_output) max_route_distance = max(route_distance, max_route_distance) total_distance += route_distance total_load += route_load print('Total Distance of all routes: {}m'.format(total_distance/scale)) print('Total Load of all routes: {}'.format(total_load)) print('Maximum of the route distances: {}m'.format(max_route_distance/scale)) def get_routes(manager, routing, solution): """Get vehicle routes from a solution and store them in an array (a list of lists).""" # Get vehicle routes and store them in a two dimensional array whose # i,j entry is the jth location visited by vehicle i along its route. routes = [] for route_nbr in range(routing.vehicles()): index = routing.Start(route_nbr) route = [manager.IndexToNode(index)] while not routing.IsEnd(index): index = solution.Value(routing.NextVar(index)) route.append(manager.IndexToNode(index)) routes.append(route) return routes def send_request(origin_addresses, dest_addresses, API_key): """ Build and send request for the given origin and destination addresses.""" def build_address_str(addresses): # Build a pipe-separated string of addresses address_str = '' for i in range(len(addresses) - 1): address_str += addresses[i] + '|' address_str += addresses[-1] return address_str request = 'https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial' origin_address_str = build_address_str(origin_addresses) dest_address_str = build_address_str(dest_addresses) request = request + '&origins=' + origin_address_str + '&destinations=' + \ dest_address_str + '&key=' + API_key #replace this one that only works in python 2: jsonResult = urllib.urlopen(request).read() import urllib.request with urllib.request.urlopen(request) as url: jsonResult = url.read() response = json.loads(jsonResult) return response def build_distance_matrix(response): distance_matrix = [] for row in response['rows']: row_list = [row['elements'][j]['distance']['value'] for j in range(len(row['elements']))] distance_matrix.append(row_list) return distance_matrix def addresses_to_distance_matrix(API_key, addresses): """turn addresses to distance matrix API_key: get one here https://developers.google.com/maps/documentation/distance-matrix/start#get-a-key addresses: a list of addresses """ # Distance Matrix API only accepts 100 elements per request, so get rows in multiple requests. max_elements = 100 num_addresses = len(addresses) # 16 in this example. # Maximum number of rows that can be computed per request (6 in this example). max_rows = max_elements // num_addresses # num_addresses = q * max_rows + r (q = 2 and r = 4 in this example). q, r = divmod(num_addresses, max_rows) dest_addresses = addresses distance_matrix = [] # Send q requests, returning max_rows rows per request. for i in range(q): origin_addresses = addresses[i * max_rows: (i + 1) * max_rows] response = send_request(origin_addresses, dest_addresses, API_key) distance_matrix += build_distance_matrix(response) # Get the remaining remaining r rows, if necessary. if r > 0: origin_addresses = addresses[q * max_rows: q * max_rows + r] response = send_request(origin_addresses, dest_addresses, API_key) distance_matrix += build_distance_matrix(response) return distance_matrix def locations_to_distance_matrix(locations, scale, distance_type='Euclidean'): '''return the distance matrix between locations''' #scale each element in locations locations = [(p[0]*scale, p[1]*scale) for p in locations] if distance_type == 'Euclidean': dist_mat = [[int(((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)**.5) for p2 in locations] for p1 in locations] if distance_type == 'Manhattan': dist_mat = [[abs(p1[0]-p2[0]) + abs(p1[1]-p2[1]) for p1 in locations] for p2 in locations] return dist_mat def preprocess_addresses(addresses): '''turn a string of separated words into a string of words connected by +''' return ['+'.join(re.sub("[^\w\s]", "", address).split()) for address in addresses] ###--------------------------------------------------------------------------<internal functions end> # create distance matrix if len(addresses[0])<3: # the case of (x, y) location distance_matrix = locations_to_distance_matrix(locations=addresses, scale=scale, distance_type=distance_type) else: # the case of address string addresses = preprocess_addresses(addresses) distance_matrix = addresses_to_distance_matrix(API_key, addresses) # create data data = create_data_model(distance_matrix, demands, vehicle_capacities, starts, ends, depot) # Create the routing index manager. #if (starts is not None) and (ends is not None): manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['starts'], data['ends']) """TBD else: 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 Capacity constraint. def demand_callback(from_index): """Returns the demand of the node.""" # Convert from routing variable Index to demands NodeIndex. from_node = manager.IndexToNode(from_index) return data['demands'][from_node] demand_callback_index = routing.RegisterUnaryTransitCallback( demand_callback) routing.AddDimensionWithVehicleCapacity( demand_callback_index, 0, # null capacity slack data['vehicle_capacities'], # vehicle maximum capacities True, # start cumul to zero 'Capacity') # Allow to drop nodes. penalty = int(sum(sum(np.array(data['distance_matrix'])))) for node in range(1, len(data['distance_matrix'])): routing.AddDisjunction([manager.NodeToIndex(node)], penalty) # Add Distance constraint. dimension_name = 'Distance' routing.AddDimension( transit_callback_index, 0, # no slack 30000000, # 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() if use_1st_solu_strategy: search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) else: search_parameters.local_search_metaheuristic = (routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) search_parameters.time_limit.seconds = 30 search_parameters.log_search = True # Solve the problem. solution = routing.SolveWithParameters(search_parameters) # Print solution on console. if solution: print_solution(data, manager, routing, solution, scale) routs = get_routes(manager, routing, solution) return routs
def resolverdorSat(): gmaps = False f = open("solucaoSAT.txt", "a+") # FUNCOES PARA MONTAGEM DA MATRIZ DE DISTANCIAS for x in range(0, 6): f.write("#################### Dia " + str(x) + " ####################\n") if gmaps: # Cria os dados. dados = getEnderecos(x) enderecos = dados['enderecos'] chave_API = dados['chave_API'] matrizDeDistancias = criaMatrizDeDistancias(dados) f.write("Matriz de distancias: \n" + str(matrizDeDistancias)) else: matrizDeDistancias = getMatrizDeDistancias(x) # FUNCOES PARA RESOLUCAO DO PROBLEMA DO CAIXEIRO VIAJANTE """Resolucao do problema de roteamento.""" # Instancia os dados do problema. dados = criaModeloDeDados(matrizDeDistancias) # Cria o gerenciador de indice do roteamento. gerenciador = pywrapcp.RoutingIndexManager( len(dados['matrizDeDistancias']), dados['numVeiculos'], dados['pontoDePartida']) # Cria o modelo do roteamento. roteamento = pywrapcp.RoutingModel(gerenciador) # Cria e registra callback de transito. def distance_callback(indiceOrigem, indiceDestino): """Retorna a distancia entre dois nos.""" # Converte de um indice da variavel roteamento para um indice da matriz de distancias. noOrigem = gerenciador.IndexToNode(indiceOrigem) noDestino = gerenciador.IndexToNode(indiceDestino) return dados['matrizDeDistancias'][noOrigem][noDestino] transit_callback_index = roteamento.RegisterTransitCallback( distance_callback) # Define o custo para cada arco. roteamento.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) # Adiciona restricao de distancia. nomeDimensao = 'Distance' roteamento.AddDimension( transit_callback_index, 0, # sem folga 400000000, # maior distancia percorrida por um veiculo True, # inicia acumulando do 0 nomeDimensao) dimensaoDistancia = roteamento.GetDimensionOrDie(nomeDimensao) dimensaoDistancia.SetGlobalSpanCostCoefficient(100) # Configura a heuristica para "primeira solucao". parametrosDeBusca = pywrapcp.DefaultRoutingSearchParameters() parametrosDeBusca.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # Resolve com os parametros. solucao = roteamento.SolveWithParameters(parametrosDeBusca) if solucao: f.flush() imprimeSolucao(dados, gerenciador, roteamento, solucao) f.write("\n") else: f.flush() f.write("\nSolucao nao encontrada\n") f.close()
def main(): """Entry point of the program.""" # Instantiate the data problem. # [START data] data = create_data_model() # [END data] # Create the routing index manager. # [START index_manager] manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), data['num_vehicles'], data['starts'], data['ends']) # [END index_manager] # Create Routing Model. # [START routing_model] routing = pywrapcp.RoutingModel(manager) # [END routing_model] # Create and register a transit callback. # [START 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) # [END transit_callback] # Define cost of each arc. # [START arc_cost] routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) # [END arc_cost] # Add Distance constraint. # [START distance_constraint] dimension_name = 'Distance' routing.AddDimension( transit_callback_index, 0, # no slack 2000, # vehicle maximum travel distance True, # start cumul to zero dimension_name) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) # [END distance_constraint] # Setting first solution heuristic. # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # [END parameters] # Solve the problem. # [START solve] solution = routing.SolveWithParameters(search_parameters) # [END solve] # Print solution on console. # [START print_solution] if solution: print_solution(data, manager, routing, solution)
lats=df.latitude.values, lons=df.longitude.values, unit='mi') vehicles = [26]*len(distances) demand = np.insert(df.pallets.values, 0, 0) # scripting ortools model construction & method. manager = pywrapcp.RoutingIndexManager(len(distances), len(vehicles), 0) def distance_callback(i:int, j:int): """index of from (i) and to (j)""" node_i = manager.IndexToNode(i) node_j = manager.Inde-xToNode(j) return distances[node_i][node_j] # model construction model = pywrapcp.RoutingModel(manager) model.SetArcCostEvaluatorOfAllVehicles( model.RegisterTransitCallback(distance_callback) ) def demand_callback(i:int): """capacity constraint""" node = manager.IndexToNode(i) return demand[node] model.AddDimensionWithVehicleCapacity( # function which return the load at each location (cf. cvrp.py example) model.RegisterUnaryTransitCallback(demand_callback), 0, # null capacity slack
def VRP(rides, no_vehicles, finish_time): rides.insert(0, Ride(-1, 0, 0, 0, 0, 0, 5)) time_matrix = [[0 for i in range(len(rides))] for i in range(len(rides))] for i in range(len(rides)): for j in range(len(rides)): time_matrix[i][j] = get_length(i, j, rides) times = [] for ride in rides: times.append((ride.s, ride.f)) depot = 0 manager = pywrapcp.RoutingIndexManager(len(time_matrix), no_vehicles, depot) routing = pywrapcp.RoutingModel(manager) def time_callback(from_index, to_index): from_node = manager.IndexToNode(from_index) to_node = manager.IndexToNode(to_index) return time_matrix[from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(time_callback) routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) routing.AddDimension(transit_callback_index, int(finish_time / 4), 2 * finish_time, False, "Time") # What do these mean? time_dimension = routing.GetDimensionOrDie("Time") for location_idx, time_window in enumerate(times): if location_idx == 0: continue index = manager.NodeToIndex(location_idx) time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1]) for vehicle_id in range(no_vehicles): index = routing.Start(vehicle_id) time_dimension.CumulVar(index).SetRange(times[0][0], times[0][1]) for i in range(no_vehicles): routing.AddVariableMinimizedByFinalizer( time_dimension.CumulVar(routing.Start(i))) routing.AddVariableMinimizedByFinalizer( time_dimension.CumulVar(routing.End(i))) search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) print("SOLVING") solution = routing.SolveWithParameters(search_parameters) if not solution: return False, [], 0 vehicles_routes = [[] for i in range(no_vehicles)] time_dimension = routing.GetDimensionOrDie('Time') max_time = 0 for vehicle_id, stops in enumerate(vehicles_routes): index = routing.Start(vehicle_id) while not routing.IsEnd(index): stops.append(manager.IndexToNode(index)) index = solution.Value(routing.NextVar(index)) max_time = max(max_time, solution.Min(time_dimension.CumulVar(index))) for i in range(len(vehicles_routes)): vehicles_routes[i] = vehicles_routes[i][1:] for j in range(len(vehicles_routes[i])): vehicles_routes[i][j] -= 1 print(vehicles_routes, max_time) return True, vehicles_routes, max_time # vehicles routes is shape (no. vehicles, no. stops for vehicle)
def main(): # Create the data. data = create_data_array() locations = data[0] demands = data[1] num_locations = len(locations) depot = 0 num_vehicles = 1 # Create routing model. if num_locations > 0: # The number of nodes of the TSP is num_locations. # Nodes are indexed from 0 to num_locations - 1. By default the start of # a route is node 0. routing = pywrapcp.RoutingModel(num_locations, num_vehicles) search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() # Setting first solution heuristic: the # method for finding a first solution to the problem. search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # The 'PATH_CHEAPEST_ARC' method does the following: # Starting from a route "start" node, connect it to the node which produces the # cheapest route segment, then extend the route by iterating on the last # node added to the route. # Put a callback to the distance function here. The callback takes two # arguments (the from and to node indices) and returns the distance between # these nodes. dist_between_locations = CreateDistanceCallback(locations) dist_callback = dist_between_locations.Distance routing.SetArcCostEvaluatorOfAllVehicles(dist_callback) # Put a callback to the demands. demands_at_locations = CreateDemandCallback(demands) demands_callback = demands_at_locations.Demand # Adding capacity dimension constraints. vehicle_capacity = 10000 null_capacity_slack = 0 fix_start_cumul_to_zero = True capacity = "Capacity" routing.AddDimension(demands_callback, null_capacity_slack, vehicle_capacity, fix_start_cumul_to_zero, capacity) routing.SetDepot(depot) # Solve, displays a solution if any. assignment = routing.SolveWithParameters(search_parameters) if assignment: # Display solution. for vehicle_nbr in range(num_vehicles): index = routing.Start(vehicle_nbr) index_next = assignment.Value(routing.NextVar(index)) route = '' route_dist = 0 route_demand = 0 while not routing.IsEnd(index_next): node_index = routing.IndexToNode(index) node_index_next = routing.IndexToNode(index_next) route += str(node_index) + " -> " # Add the distance to the next node. route_dist += dist_callback(node_index, node_index_next) # Add demand. route_demand += demands[node_index] index = index_next index_next = assignment.Value(routing.NextVar(index)) node_index = routing.IndexToNode(index) node_index_next = routing.IndexToNode(index_next) route += str(node_index) + " -> " + str(node_index_next) route_dist += dist_callback(node_index, node_index_next) print "Route for vehicle " + str( vehicle_nbr) + ":\n\n" + route + "\n" print "Distance of route " + str(vehicle_nbr) + ": " + str( route_dist) print "Demand met by vehicle " + str(vehicle_nbr) + ": " + str( route_demand) + "\n" else: print 'No solution found.' else: print 'Specify an instance greater than 0.'