diff --git a/ortools/constraint_solver/samples/cp_is_fun_cp.py b/ortools/constraint_solver/samples/cp_is_fun_cp.py index 73c6b279e9f..eaf3166a524 100755 --- a/ortools/constraint_solver/samples/cp_is_fun_cp.py +++ b/ortools/constraint_solver/samples/cp_is_fun_cp.py @@ -28,7 +28,7 @@ def main(): # Constraint programming engine # [START solver] - solver = pywrapcp.Solver('CP is fun!') + solver = pywrapcp.Solver("CP is fun!") # [END solver] # [START variables] @@ -37,16 +37,16 @@ def main(): # Decision variables. digits = list(range(0, base)) digits_without_zero = list(range(1, base)) - c = solver.IntVar(digits_without_zero, 'C') - p = solver.IntVar(digits, 'P') - i = solver.IntVar(digits_without_zero, 'I') - s = solver.IntVar(digits, 'S') - f = solver.IntVar(digits_without_zero, 'F') - u = solver.IntVar(digits, 'U') - n = solver.IntVar(digits, 'N') - t = solver.IntVar(digits_without_zero, 'T') - r = solver.IntVar(digits, 'R') - e = solver.IntVar(digits, 'E') + c = solver.IntVar(digits_without_zero, "C") + p = solver.IntVar(digits, "P") + i = solver.IntVar(digits_without_zero, "I") + s = solver.IntVar(digits, "S") + f = solver.IntVar(digits_without_zero, "F") + u = solver.IntVar(digits, "U") + n = solver.IntVar(digits, "N") + t = solver.IntVar(digits_without_zero, "T") + r = solver.IntVar(digits, "R") + e = solver.IntVar(digits, "E") # We need to group variables in a list to use the constraint AllDifferent. letters = [c, p, i, s, f, u, n, t, r, e] @@ -60,8 +60,10 @@ def main(): solver.Add(solver.AllDifferent(letters)) # CP + IS + FUN = TRUE - solver.Add(p + s + n + base * (c + i + u) + base * base * f == e + - base * u + base * base * r + base * base * base * t) + solver.Add( + p + s + n + base * (c + i + u) + base * base * f + == e + base * u + base * base * r + base * base * base * t + ) # [END constraints] # [START solve] @@ -71,16 +73,25 @@ def main(): while solver.NextSolution(): print(letters) # Is CP + IS + FUN = TRUE? - assert (base * c.Value() + p.Value() + base * i.Value() + s.Value() + - base * base * f.Value() + base * u.Value() + - n.Value() == base * base * base * t.Value() + - base * base * r.Value() + base * u.Value() + e.Value()) + assert ( + base * c.Value() + + p.Value() + + base * i.Value() + + s.Value() + + base * base * f.Value() + + base * u.Value() + + n.Value() + == base * base * base * t.Value() + + base * base * r.Value() + + base * u.Value() + + e.Value() + ) solution_count += 1 solver.EndSearch() - print(f'Number of solutions found: {solution_count}') + print(f"Number of solutions found: {solution_count}") # [END solve] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/cvrptw_break.py b/ortools/constraint_solver/samples/cvrptw_break.py index 0429eba09c0..c08dc8ddaf5 100755 --- a/ortools/constraint_solver/samples/cvrptw_break.py +++ b/ortools/constraint_solver/samples/cvrptw_break.py @@ -35,82 +35,92 @@ def create_data_model(): """Stores the data for the problem.""" data = {} # Locations in block unit - locations_ = \ - [(4, 4), # depot - (2, 0), (8, 0), # locations to visit - (0, 1), (1, 1), - (5, 2), (7, 2), - (3, 3), (6, 3), - (5, 5), (8, 5), - (1, 6), (2, 6), - (3, 7), (6, 7), - (0, 8), (7, 8)] + locations_ = [ + # fmt: off + (4, 4), # depot + (2, 0), (8, 0), # locations to visit + (0, 1), (1, 1), + (5, 2), (7, 2), + (3, 3), (6, 3), + (5, 5), (8, 5), + (1, 6), (2, 6), + (3, 7), (6, 7), + (0, 8), (7, 8), + # fmt: on + ] # Compute locations in meters using the block dimension defined as follow # Manhattan average block: 750ft x 264ft -> 228m x 80m # here we use: 114m x 80m city block # src: https://nyti.ms/2GDoRIe "NY Times: Know Your distance" - data['locations'] = [(l[0] * 114, l[1] * 80) for l in locations_] - data['numlocations_'] = len(data['locations']) - data['time_windows'] = \ - [(0, 0), - (75, 85), (75, 85), # 1, 2 - (60, 70), (45, 55), # 3, 4 - (0, 8), (50, 60), # 5, 6 - (0, 10), (10, 20), # 7, 8 - (0, 10), (75, 85), # 9, 10 - (85, 95), (5, 15), # 11, 12 - (15, 25), (10, 20), # 13, 14 - (45, 55), (30, 40)] # 15, 16 - data['demands'] = \ - [0, # depot - 1, 1, # 1, 2 - 2, 4, # 3, 4 - 2, 4, # 5, 6 - 8, 8, # 7, 8 - 1, 2, # 9,10 - 1, 2, # 11,12 - 4, 4, # 13, 14 - 8, 8] # 15, 16 - data['time_per_demand_unit'] = 5 # 5 minutes/unit - data['num_vehicles'] = 4 - data['breaks'] = [(2, False), (2, False), (2, False), (2, False)] - data['vehicle_capacity'] = 15 - data['vehicle_speed'] = 83 # Travel speed: 5km/h converted in m/min - data['depot'] = 0 + data["locations"] = [(l[0] * 114, l[1] * 80) for l in locations_] + data["numlocations_"] = len(data["locations"]) + data["time_windows"] = [ + # fmt: off + (0, 0), # depot + (75, 85), (75, 85), # 1, 2 + (60, 70), (45, 55), # 3, 4 + (0, 8), (50, 60), # 5, 6 + (0, 10), (10, 20), # 7, 8 + (0, 10), (75, 85), # 9, 10 + (85, 95), (5, 15), # 11, 12 + (15, 25), (10, 20), # 13, 14 + (45, 55), (30, 40), + # 15, 16 + # fmt: on + ] + data["demands"] = [ + # fmt: off + 0, # depot + 1, 1, # 1, 2 + 2, 4, # 3, 4 + 2, 4, # 5, 6 + 8, 8, # 7, 8 + 1, 2, # 9, 10 + 1, 2, # 11, 12 + 4, 4, # 13, 14 + 8, 8, + # 15, 16 + # fmt: on + ] + data["time_per_demand_unit"] = 5 # 5 minutes/unit + data["num_vehicles"] = 4 + data["breaks"] = [(2, False), (2, False), (2, False), (2, False)] + data["vehicle_capacity"] = 15 + data["vehicle_speed"] = 83 # Travel speed: 5km/h converted in m/min + data["depot"] = 0 return data # [END data_model] def manhattan_distance(position_1, position_2): """Computes the Manhattan distance between two points.""" - return (abs(position_1[0] - position_2[0]) + - abs(position_1[1] - position_2[1])) + return abs(position_1[0] - position_2[0]) + abs(position_1[1] - position_2[1]) def create_distance_evaluator(data): """Creates callback to return distance between points.""" distances_ = {} # precompute distance between location to have distance callback in O(1) - for from_node in range(data['numlocations_']): + for from_node in range(data["numlocations_"]): distances_[from_node] = {} - for to_node in range(data['numlocations_']): + for to_node in range(data["numlocations_"]): if from_node == to_node: distances_[from_node][to_node] = 0 else: - distances_[from_node][to_node] = (manhattan_distance( - data['locations'][from_node], data['locations'][to_node])) + distances_[from_node][to_node] = manhattan_distance( + data["locations"][from_node], data["locations"][to_node] + ) def distance_evaluator(manager, from_node, to_node): """Returns the manhattan distance between the two nodes.""" - return distances_[manager.IndexToNode(from_node)][manager.IndexToNode( - to_node)] + return distances_[manager.IndexToNode(from_node)][manager.IndexToNode(to_node)] return distance_evaluator def create_demand_evaluator(data): """Creates callback to get demands at each location.""" - demands_ = data['demands'] + demands_ = data["demands"] def demand_evaluator(manager, node): """Returns the demand of the current node.""" @@ -121,13 +131,14 @@ def demand_evaluator(manager, node): def add_capacity_constraints(routing, data, demand_evaluator_index): """Adds capacity constraint.""" - capacity = 'Capacity' + capacity = "Capacity" routing.AddDimension( demand_evaluator_index, 0, # null capacity slack - data['vehicle_capacity'], + data["vehicle_capacity"], True, # start cumul to zero - capacity) + capacity, + ) def create_time_evaluator(data): @@ -135,63 +146,68 @@ def create_time_evaluator(data): def service_time(data, node): """Gets the service time for the specified location.""" - return data['demands'][node] * data['time_per_demand_unit'] + return data["demands"][node] * data["time_per_demand_unit"] def travel_time(data, from_node, to_node): """Gets the travel times between two locations.""" if from_node == to_node: travel_time = 0 else: - travel_time = manhattan_distance( - data['locations'][from_node], - data['locations'][to_node]) / data['vehicle_speed'] + travel_time = ( + manhattan_distance( + data["locations"][from_node], data["locations"][to_node] + ) + / data["vehicle_speed"] + ) return travel_time total_time_ = {} # precompute total time to have time callback in O(1) - for from_node in range(data['numlocations_']): + for from_node in range(data["numlocations_"]): total_time_[from_node] = {} - for to_node in range(data['numlocations_']): + for to_node in range(data["numlocations_"]): if from_node == to_node: total_time_[from_node][to_node] = 0 else: total_time_[from_node][to_node] = int( - service_time(data, from_node) + - travel_time(data, from_node, to_node)) + service_time(data, from_node) + + travel_time(data, from_node, to_node) + ) def time_evaluator(manager, from_node, to_node): """Returns the total time between the two nodes.""" - return total_time_[manager.IndexToNode(from_node)][manager.IndexToNode( - to_node)] + return total_time_[manager.IndexToNode(from_node)][manager.IndexToNode(to_node)] return time_evaluator def add_time_window_constraints(routing, manager, data, time_evaluator_index): """Add Global Span constraint.""" - time = 'Time' + time = "Time" horizon = 120 routing.AddDimension( time_evaluator_index, horizon, # allow waiting time horizon, # maximum time per vehicle False, # don't force start cumul to zero - time) + time, + ) time_dimension = routing.GetDimensionOrDie(time) # Add time window constraints for each location except depot # and 'copy' the slack var in the solution object (aka Assignment) to print it - for location_idx, time_window in enumerate(data['time_windows']): - if location_idx == data['depot']: + for location_idx, time_window in enumerate(data["time_windows"]): + if location_idx == data["depot"]: continue index = manager.NodeToIndex(location_idx) time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1]) routing.AddToAssignment(time_dimension.SlackVar(index)) # Add time window constraints for each vehicle start node # and 'copy' the slack var in the solution object (aka Assignment) to print it - for vehicle_id in range(data['num_vehicles']): + 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]) + time_dimension.CumulVar(index).SetRange( + data["time_windows"][0][0], data["time_windows"][0][1] + ) routing.AddToAssignment(time_dimension.SlackVar(index)) # The time window at the end node was impliclty set in the time dimension # definition to be [0, horizon]. @@ -200,28 +216,32 @@ def add_time_window_constraints(routing, manager, data, time_evaluator_index): # [START solution_printer] -def print_solution(data, manager, routing, assignment): # pylint:disable=too-many-locals +def print_solution( + data, manager, routing, assignment +): # pylint:disable=too-many-locals """Prints assignment on console.""" - print(f'Objective: {assignment.ObjectiveValue()}') + print(f"Objective: {assignment.ObjectiveValue()}") - print('Breaks:') + print("Breaks:") intervals = assignment.IntervalVarContainer() for i in range(intervals.Size()): brk = intervals.Element(i) if brk.PerformedValue() == 1: - print(f'{brk.Var().Name()}:' - f' Start({brk.StartValue()}) Duration({brk.DurationValue()})') + print( + f"{brk.Var().Name()}:" + f" Start({brk.StartValue()}) Duration({brk.DurationValue()})" + ) else: - print(f'{brk.Var().Name()}: Unperformed') + print(f"{brk.Var().Name()}: Unperformed") total_distance = 0 total_load = 0 total_time = 0 - capacity_dimension = routing.GetDimensionOrDie('Capacity') - time_dimension = routing.GetDimensionOrDie('Time') - for vehicle_id in range(data['num_vehicles']): + capacity_dimension = routing.GetDimensionOrDie("Capacity") + time_dimension = routing.GetDimensionOrDie("Time") + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" distance = 0 while not routing.IsEnd(index): load_var = capacity_dimension.CumulVar(index) @@ -229,32 +249,33 @@ def print_solution(data, manager, routing, assignment): # pylint:disable=too-ma slack_var = time_dimension.SlackVar(index) node = manager.IndexToNode(index) plan_output += ( - f' {node}' - f' Load({assignment.Value(load_var)})' - f' Time({assignment.Min(time_var)}, {assignment.Max(time_var)})' - f' Slack({assignment.Min(slack_var)}, {assignment.Max(slack_var)})' - ' ->') + f" {node}" + f" Load({assignment.Value(load_var)})" + f" Time({assignment.Min(time_var)}, {assignment.Max(time_var)})" + f" Slack({assignment.Min(slack_var)}, {assignment.Max(slack_var)})" + " ->" + ) previous_index = index index = assignment.Value(routing.NextVar(index)) - distance += routing.GetArcCostForVehicle(previous_index, index, - vehicle_id) + distance += routing.GetArcCostForVehicle(previous_index, index, vehicle_id) load_var = capacity_dimension.CumulVar(index) time_var = time_dimension.CumulVar(index) node = manager.IndexToNode(index) plan_output += ( - f' {node}' - f' Load({assignment.Value(load_var)})' - f' Time({assignment.Min(time_var)}, {assignment.Max(time_var)})\n') - plan_output += f'Distance of the route: {distance}m\n' - plan_output += f'Load of the route: {assignment.Value(load_var)}\n' - plan_output += f'Time of the route: {assignment.Value(time_var)}\n' + f" {node}" + f" Load({assignment.Value(load_var)})" + f" Time({assignment.Min(time_var)}, {assignment.Max(time_var)})\n" + ) + plan_output += f"Distance of the route: {distance}m\n" + plan_output += f"Load of the route: {assignment.Value(load_var)}\n" + plan_output += f"Time of the route: {assignment.Value(time_var)}\n" print(plan_output) total_distance += distance total_load += assignment.Value(load_var) total_time += assignment.Value(time_var) - print(f'Total Distance of all routes: {total_distance}m') - print(f'Total Load of all routes: {total_load}') - print(f'Total Time of all routes: {total_time}min') + print(f"Total Distance of all routes: {total_distance}m") + print(f"Total Load of all routes: {total_load}") + print(f"Total Time of all routes: {total_time}min") # [END solution_printer] @@ -266,51 +287,58 @@ def main(): # [END data] # Create the routing index manager - manager = pywrapcp.RoutingIndexManager(data['numlocations_'], - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + data["numlocations_"], data["num_vehicles"], data["depot"] + ) # Create Routing Model routing = pywrapcp.RoutingModel(manager) # Define weight of each edge distance_evaluator_index = routing.RegisterTransitCallback( - functools.partial(create_distance_evaluator(data), manager)) + functools.partial(create_distance_evaluator(data), manager) + ) routing.SetArcCostEvaluatorOfAllVehicles(distance_evaluator_index) # Add Capacity constraint demand_evaluator_index = routing.RegisterUnaryTransitCallback( - functools.partial(create_demand_evaluator(data), manager)) + functools.partial(create_demand_evaluator(data), manager) + ) add_capacity_constraints(routing, data, demand_evaluator_index) # Add Time Window constraint time_evaluator_index = routing.RegisterTransitCallback( - functools.partial(create_time_evaluator(data), manager)) + functools.partial(create_time_evaluator(data), manager) + ) add_time_window_constraints(routing, manager, data, time_evaluator_index) # Add breaks - time_dimension = routing.GetDimensionOrDie('Time') + time_dimension = routing.GetDimensionOrDie("Time") node_visit_transit = {} for index in range(routing.Size()): node = manager.IndexToNode(index) - node_visit_transit[index] = int(data['demands'][node] * - data['time_per_demand_unit']) + node_visit_transit[index] = int( + data["demands"][node] * data["time_per_demand_unit"] + ) break_intervals = {} - for v in range(data['num_vehicles']): - vehicle_break = data['breaks'][v] + for v in range(data["num_vehicles"]): + vehicle_break = data["breaks"][v] break_intervals[v] = [ - routing.solver().FixedDurationIntervalVar(15, 100, vehicle_break[0], - vehicle_break[1], - f'Break for vehicle {v}') + routing.solver().FixedDurationIntervalVar( + 15, 100, vehicle_break[0], vehicle_break[1], f"Break for vehicle {v}" + ) ] - time_dimension.SetBreakIntervalsOfVehicle(break_intervals[v], v, - node_visit_transit.values()) + time_dimension.SetBreakIntervalsOfVehicle( + break_intervals[v], v, node_visit_transit.values() + ) # Setting first solution heuristic (cheapest addition). # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # pylint: disable=no-member + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # pylint: disable=no-member # [END parameters] # Solve the problem. @@ -323,10 +351,10 @@ def main(): if assignment: print_solution(data, manager, routing, assignment) else: - print('No solution found!') + print("No solution found!") # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/nqueens_cp.py b/ortools/constraint_solver/samples/nqueens_cp.py index 6191e657ba7..59585f1d6de 100755 --- a/ortools/constraint_solver/samples/nqueens_cp.py +++ b/ortools/constraint_solver/samples/nqueens_cp.py @@ -23,15 +23,13 @@ def main(board_size): # Creates the solver. # [START solver] - solver = pywrapcp.Solver('n-queens') + solver = pywrapcp.Solver("n-queens") # [END solver] # Creates the variables. # [START variables] # The array index is the column, and the value is the row. - queens = [ - solver.IntVar(0, board_size - 1, f'x{i}') for i in range(board_size) - ] + queens = [solver.IntVar(0, board_size - 1, f"x{i}") for i in range(board_size)] # [END variables] # Creates the constraints. @@ -45,8 +43,7 @@ def main(board_size): # [END constraints] # [START db] - db = solver.Phase(queens, solver.CHOOSE_FIRST_UNBOUND, - solver.ASSIGN_MIN_VALUE) + db = solver.Phase(queens, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) # [END db] # [START solve] @@ -59,9 +56,9 @@ def main(board_size): for j in range(board_size): if queens[j].Value() == i: # There is a queen in column j, row i. - print('Q', end=' ') + print("Q", end=" ") else: - print('_', end=' ') + print("_", end=" ") print() print() num_solutions += 1 @@ -70,15 +67,15 @@ def main(board_size): # Statistics. # [START statistics] - print('\nStatistics') - print(f' failures: {solver.Failures()}') - print(f' branches: {solver.Branches()}') - print(f' wall time: {solver.WallTime()} ms') - print(f' Solutions found: {num_solutions}') + print("\nStatistics") + print(f" failures: {solver.Failures()}") + print(f" branches: {solver.Branches()}") + print(f" wall time: {solver.WallTime()} ms") + print(f" Solutions found: {num_solutions}") # [END statistics] -if __name__ == '__main__': +if __name__ == "__main__": # By default, solve the 8x8 problem. size = 8 if len(sys.argv) > 1: diff --git a/ortools/constraint_solver/samples/simple_cp_program.py b/ortools/constraint_solver/samples/simple_cp_program.py index ac402bdfbd7..7a4bb9aa390 100755 --- a/ortools/constraint_solver/samples/simple_cp_program.py +++ b/ortools/constraint_solver/samples/simple_cp_program.py @@ -24,27 +24,28 @@ def main(): """Entry point of the program.""" # Instantiate the solver. # [START solver] - solver = pywrapcp.Solver('CPSimple') + solver = pywrapcp.Solver("CPSimple") # [END solver] # Create the variables. # [START variables] num_vals = 3 - x = solver.IntVar(0, num_vals - 1, 'x') - y = solver.IntVar(0, num_vals - 1, 'y') - z = solver.IntVar(0, num_vals - 1, 'z') + x = solver.IntVar(0, num_vals - 1, "x") + y = solver.IntVar(0, num_vals - 1, "y") + z = solver.IntVar(0, num_vals - 1, "z") # [END variables] # Constraint 0: x != y. # [START constraints] solver.Add(x != y) - print('Number of constraints: ', solver.Constraints()) + print("Number of constraints: ", solver.Constraints()) # [END constraints] # Solve the problem. # [START solve] - decision_builder = solver.Phase([x, y, z], solver.CHOOSE_FIRST_UNBOUND, - solver.ASSIGN_MIN_VALUE) + decision_builder = solver.Phase( + [x, y, z], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE + ) # [END solve] # Print solution on console. @@ -53,21 +54,21 @@ def main(): solver.NewSearch(decision_builder) while solver.NextSolution(): count += 1 - solution = f'Solution {count}:\n' + solution = f"Solution {count}:\n" for var in [x, y, z]: - solution += f' {var.Name()} = {var.Value()}' + solution += f" {var.Name()} = {var.Value()}" print(solution) solver.EndSearch() - print(f'Number of solutions found: {count}') + print(f"Number of solutions found: {count}") # [END print_solution] # [START advanced] - print('Advanced usage:') - print(f'Problem solved in {solver.WallTime()}ms') - print(f'Memory usage: {pywrapcp.Solver.MemoryUsage()}bytes') + print("Advanced usage:") + print(f"Problem solved in {solver.WallTime()}ms") + print(f"Memory usage: {pywrapcp.Solver.MemoryUsage()}bytes") # [END advanced] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/simple_routing_program.py b/ortools/constraint_solver/samples/simple_routing_program.py index a3259dec11a..ffef94e179c 100755 --- a/ortools/constraint_solver/samples/simple_routing_program.py +++ b/ortools/constraint_solver/samples/simple_routing_program.py @@ -38,7 +38,6 @@ def main(): # Create Routing Model. # [START routing_model] routing = pywrapcp.RoutingModel(manager) - # [END routing_model] # Create and register a transit callback. @@ -62,7 +61,8 @@ def distance_callback(from_index, to_index): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) # pylint: disable=no-member + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # pylint: disable=no-member # [END parameters] # Solve the problem. @@ -72,21 +72,21 @@ def distance_callback(from_index, to_index): # Print solution on console. # [START print_solution] - print(f'Objective: {assignment.ObjectiveValue()}') + print(f"Objective: {assignment.ObjectiveValue()}") index = routing.Start(0) - plan_output = 'Route for vehicle 0:\n' + plan_output = "Route for vehicle 0:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f'{manager.IndexToNode(index)} -> ' + plan_output += f"{manager.IndexToNode(index)} -> " previous_index = index index = assignment.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle(previous_index, index, 0) - plan_output += f'{manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + plan_output += f"{manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/tsp.py b/ortools/constraint_solver/samples/tsp.py index ee2e14c4144..09c5294404c 100755 --- a/ortools/constraint_solver/samples/tsp.py +++ b/ortools/constraint_solver/samples/tsp.py @@ -30,20 +30,23 @@ def create_data_model(): """Stores the data for the problem.""" data = {} # Locations in block units - locations = \ - [(4, 4), # depot - (2, 0), (8, 0), # locations to visit - (0, 1), (1, 1), - (5, 2), (7, 2), - (3, 3), (6, 3), - (5, 5), (8, 5), - (1, 6), (2, 6), - (3, 7), (6, 7), - (0, 8), (7, 8),] + locations = [ + # fmt:off + (4, 4), # depot + (2, 0), (8, 0), # locations to visit + (0, 1), (1, 1), + (5, 2), (7, 2), + (3, 3), (6, 3), + (5, 5), (8, 5), + (1, 6), (2, 6), + (3, 7), (6, 7), + (0, 8), (7, 8) + # fmt:on + ] # Convert locations in meters using a city block dimension of 114m x 80m. - data['locations'] = [(l[0] * 114, l[1] * 80) for l in locations] - data['num_vehicles'] = 1 - data['depot'] = 0 + data["locations"] = [(l[0] * 114, l[1] * 80) for l in locations] + data["num_vehicles"] = 1 + data["depot"] = 0 return data # [END data_model] @@ -54,15 +57,15 @@ def create_distance_callback(data, manager): distances_ = {} index_manager_ = manager # precompute distance between location to have distance callback in O(1) - for from_counter, from_node in enumerate(data['locations']): + for from_counter, from_node in enumerate(data["locations"]): distances_[from_counter] = {} - for to_counter, to_node in enumerate(data['locations']): + for to_counter, to_node in enumerate(data["locations"]): if from_counter == to_counter: distances_[from_counter][to_counter] = 0 else: - distances_[from_counter][to_counter] = ( - abs(from_node[0] - to_node[0]) + - abs(from_node[1] - to_node[1])) + distances_[from_counter][to_counter] = abs( + from_node[0] - to_node[0] + ) + abs(from_node[1] - to_node[1]) def distance_callback(from_index, to_index): """Returns the manhattan distance between the two nodes.""" @@ -78,17 +81,17 @@ def distance_callback(from_index, to_index): # [START solution_printer] def print_solution(manager, routing, assignment): """Prints assignment on console.""" - print(f'Objective: {assignment.ObjectiveValue()}') + print(f"Objective: {assignment.ObjectiveValue()}") index = routing.Start(0) - plan_output = 'Route for vehicle 0:\n' + plan_output = "Route for vehicle 0:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} ->' + plan_output += f" {manager.IndexToNode(index)} ->" previous_index = index index = assignment.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle(previous_index, index, 0) - plan_output += f' {manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + plan_output += f" {manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) # [END solution_printer] @@ -102,8 +105,9 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['locations']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["locations"]), data["num_vehicles"], data["depot"] + ) # [END index_manager] # Create Routing Model. @@ -126,7 +130,8 @@ def main(): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # [END parameters] # Solve the problem. @@ -141,6 +146,6 @@ def main(): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/tsp_circuit_board.py b/ortools/constraint_solver/samples/tsp_circuit_board.py index d6079900dac..1e753056d18 100755 --- a/ortools/constraint_solver/samples/tsp_circuit_board.py +++ b/ortools/constraint_solver/samples/tsp_circuit_board.py @@ -27,57 +27,59 @@ def create_data_model(): """Stores the data for the problem.""" data = {} # Locations in block units - data['locations'] = [ - (288, 149), (288, 129), (270, 133), (256, 141), (256, 157), (246, 157), - (236, 169), (228, 169), (228, 161), (220, 169), (212, 169), (204, 169), - (196, 169), (188, 169), (196, 161), (188, 145), (172, 145), (164, 145), - (156, 145), (148, 145), (140, 145), (148, 169), (164, 169), (172, 169), - (156, 169), (140, 169), (132, 169), (124, 169), (116, 161), (104, 153), - (104, 161), (104, 169), (90, 165), (80, 157), (64, 157), (64, 165), - (56, 169), (56, 161), (56, 153), (56, 145), (56, 137), (56, 129), - (56, 121), (40, 121), (40, 129), (40, 137), (40, 145), (40, 153), - (40, 161), (40, 169), (32, 169), (32, 161), (32, 153), (32, 145), - (32, 137), (32, 129), (32, 121), (32, 113), (40, 113), (56, 113), - (56, 105), (48, 99), (40, 99), (32, 97), (32, 89), (24, 89), - (16, 97), (16, 109), (8, 109), (8, 97), (8, 89), (8, 81), - (8, 73), (8, 65), (8, 57), (16, 57), (8, 49), (8, 41), - (24, 45), (32, 41), (32, 49), (32, 57), (32, 65), (32, 73), - (32, 81), (40, 83), (40, 73), (40, 63), (40, 51), (44, 43), - (44, 35), (44, 27), (32, 25), (24, 25), (16, 25), (16, 17), - (24, 17), (32, 17), (44, 11), (56, 9), (56, 17), (56, 25), - (56, 33), (56, 41), (64, 41), (72, 41), (72, 49), (56, 49), - (48, 51), (56, 57), (56, 65), (48, 63), (48, 73), (56, 73), - (56, 81), (48, 83), (56, 89), (56, 97), (104, 97), (104, 105), - (104, 113), (104, 121), (104, 129), (104, 137), (104, 145), (116, 145), - (124, 145), (132, 145), (132, 137), (140, 137), (148, 137), (156, 137), - (164, 137), (172, 125), (172, 117), (172, 109), (172, 101), (172, 93), - (172, 85), (180, 85), (180, 77), (180, 69), (180, 61), (180, 53), - (172, 53), (172, 61), (172, 69), (172, 77), (164, 81), (148, 85), - (124, 85), (124, 93), (124, 109), (124, 125), (124, 117), (124, 101), - (104, 89), (104, 81), (104, 73), (104, 65), (104, 49), (104, 41), - (104, 33), (104, 25), (104, 17), (92, 9), (80, 9), (72, 9), - (64, 21), (72, 25), (80, 25), (80, 25), (80, 41), (88, 49), - (104, 57), (124, 69), (124, 77), (132, 81), (140, 65), (132, 61), - (124, 61), (124, 53), (124, 45), (124, 37), (124, 29), (132, 21), - (124, 21), (120, 9), (128, 9), (136, 9), (148, 9), (162, 9), - (156, 25), (172, 21), (180, 21), (180, 29), (172, 29), (172, 37), - (172, 45), (180, 45), (180, 37), (188, 41), (196, 49), (204, 57), - (212, 65), (220, 73), (228, 69), (228, 77), (236, 77), (236, 69), - (236, 61), (228, 61), (228, 53), (236, 53), (236, 45), (228, 45), - (228, 37), (236, 37), (236, 29), (228, 29), (228, 21), (236, 21), - (252, 21), (260, 29), (260, 37), (260, 45), (260, 53), (260, 61), - (260, 69), (260, 77), (276, 77), (276, 69), (276, 61), (276, 53), - (284, 53), (284, 61), (284, 69), (284, 77), (284, 85), (284, 93), - (284, 101), (288, 109), (280, 109), (276, 101), (276, 93), (276, 85), - (268, 97), (260, 109), (252, 101), (260, 93), (260, 85), (236, 85), - (228, 85), (228, 93), (236, 93), (236, 101), (228, 101), (228, 109), - (228, 117), (228, 125), (220, 125), (212, 117), (204, 109), (196, 101), - (188, 93), (180, 93), (180, 101), (180, 109), (180, 117), (180, 125), - (196, 145), (204, 145), (212, 145), (220, 145), (228, 145), (236, 145), - (246, 141), (252, 125), (260, 129), (280, 133) - ] # yapf: disable - data['num_vehicles'] = 1 - data['depot'] = 0 + data["locations"] = [ + # fmt: off + (288, 149), (288, 129), (270, 133), (256, 141), (256, 157), (246, 157), + (236, 169), (228, 169), (228, 161), (220, 169), (212, 169), (204, 169), + (196, 169), (188, 169), (196, 161), (188, 145), (172, 145), (164, 145), + (156, 145), (148, 145), (140, 145), (148, 169), (164, 169), (172, 169), + (156, 169), (140, 169), (132, 169), (124, 169), (116, 161), (104, 153), + (104, 161), (104, 169), (90, 165), (80, 157), (64, 157), (64, 165), + (56, 169), (56, 161), (56, 153), (56, 145), (56, 137), (56, 129), + (56, 121), (40, 121), (40, 129), (40, 137), (40, 145), (40, 153), + (40, 161), (40, 169), (32, 169), (32, 161), (32, 153), (32, 145), + (32, 137), (32, 129), (32, 121), (32, 113), (40, 113), (56, 113), + (56, 105), (48, 99), (40, 99), (32, 97), (32, 89), (24, 89), + (16, 97), (16, 109), (8, 109), (8, 97), (8, 89), (8, 81), + (8, 73), (8, 65), (8, 57), (16, 57), (8, 49), (8, 41), + (24, 45), (32, 41), (32, 49), (32, 57), (32, 65), (32, 73), + (32, 81), (40, 83), (40, 73), (40, 63), (40, 51), (44, 43), + (44, 35), (44, 27), (32, 25), (24, 25), (16, 25), (16, 17), + (24, 17), (32, 17), (44, 11), (56, 9), (56, 17), (56, 25), + (56, 33), (56, 41), (64, 41), (72, 41), (72, 49), (56, 49), + (48, 51), (56, 57), (56, 65), (48, 63), (48, 73), (56, 73), + (56, 81), (48, 83), (56, 89), (56, 97), (104, 97), (104, 105), + (104, 113), (104, 121), (104, 129), (104, 137), (104, 145), (116, 145), + (124, 145), (132, 145), (132, 137), (140, 137), (148, 137), (156, 137), + (164, 137), (172, 125), (172, 117), (172, 109), (172, 101), (172, 93), + (172, 85), (180, 85), (180, 77), (180, 69), (180, 61), (180, 53), + (172, 53), (172, 61), (172, 69), (172, 77), (164, 81), (148, 85), + (124, 85), (124, 93), (124, 109), (124, 125), (124, 117), (124, 101), + (104, 89), (104, 81), (104, 73), (104, 65), (104, 49), (104, 41), + (104, 33), (104, 25), (104, 17), (92, 9), (80, 9), (72, 9), + (64, 21), (72, 25), (80, 25), (80, 25), (80, 41), (88, 49), + (104, 57), (124, 69), (124, 77), (132, 81), (140, 65), (132, 61), + (124, 61), (124, 53), (124, 45), (124, 37), (124, 29), (132, 21), + (124, 21), (120, 9), (128, 9), (136, 9), (148, 9), (162, 9), + (156, 25), (172, 21), (180, 21), (180, 29), (172, 29), (172, 37), + (172, 45), (180, 45), (180, 37), (188, 41), (196, 49), (204, 57), + (212, 65), (220, 73), (228, 69), (228, 77), (236, 77), (236, 69), + (236, 61), (228, 61), (228, 53), (236, 53), (236, 45), (228, 45), + (228, 37), (236, 37), (236, 29), (228, 29), (228, 21), (236, 21), + (252, 21), (260, 29), (260, 37), (260, 45), (260, 53), (260, 61), + (260, 69), (260, 77), (276, 77), (276, 69), (276, 61), (276, 53), + (284, 53), (284, 61), (284, 69), (284, 77), (284, 85), (284, 93), + (284, 101), (288, 109), (280, 109), (276, 101), (276, 93), (276, 85), + (268, 97), (260, 109), (252, 101), (260, 93), (260, 85), (236, 85), + (228, 85), (228, 93), (236, 93), (236, 101), (228, 101), (228, 109), + (228, 117), (228, 125), (220, 125), (212, 117), (204, 109), (196, 101), + (188, 93), (180, 93), (180, 101), (180, 109), (180, 117), (180, 125), + (196, 145), (204, 145), (212, 145), (220, 145), (228, 145), (236, 145), + (246, 141), (252, 125), (260, 129), (280, 133) + # fmt: on + ] + data["num_vehicles"] = 1 + data["depot"] = 0 return data # [END data_model] @@ -93,9 +95,9 @@ def compute_euclidean_distance_matrix(locations): distances[from_counter][to_counter] = 0 else: # Euclidean distance - distances[from_counter][to_counter] = (int( - math.hypot((from_node[0] - to_node[0]), - (from_node[1] - to_node[1])))) + distances[from_counter][to_counter] = int( + math.hypot((from_node[0] - to_node[0]), (from_node[1] - to_node[1])) + ) return distances # [END distance_callback] @@ -103,18 +105,18 @@ def compute_euclidean_distance_matrix(locations): # [START solution_printer] def print_solution(manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') + print(f"Objective: {solution.ObjectiveValue()}") index = routing.Start(0) - plan_output = 'Route:\n' + plan_output = "Route:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} ->' + plan_output += f" {manager.IndexToNode(index)} ->" previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle(previous_index, index, 0) - plan_output += f' {manager.IndexToNode(index)}\n' + plan_output += f" {manager.IndexToNode(index)}\n" print(plan_output) - plan_output += f'Objective: {route_distance}m\n' + plan_output += f"Objective: {route_distance}m\n" # [END solution_printer] @@ -127,8 +129,9 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['locations']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["locations"]), data["num_vehicles"], data["depot"] + ) # [END index_manager] # Create Routing Model. @@ -137,7 +140,7 @@ def main(): # [END routing_model] # [START transit_callback] - distance_matrix = compute_euclidean_distance_matrix(data['locations']) + distance_matrix = compute_euclidean_distance_matrix(data["locations"]) def distance_callback(from_index, to_index): """Returns the distance between the two nodes.""" @@ -158,7 +161,8 @@ def distance_callback(from_index, to_index): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # [END parameters] # Solve the problem. @@ -173,6 +177,6 @@ def distance_callback(from_index, to_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/tsp_cities.py b/ortools/constraint_solver/samples/tsp_cities.py index 4d5273a459b..967f694e724 100755 --- a/ortools/constraint_solver/samples/tsp_cities.py +++ b/ortools/constraint_solver/samples/tsp_cities.py @@ -25,7 +25,7 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ + data["distance_matrix"] = [ [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972], [2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579], [713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260], @@ -39,9 +39,9 @@ def create_data_model(): [1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200], [2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504], [1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0], - ] # yapf: disable - data['num_vehicles'] = 1 - data['depot'] = 0 + ] + data["num_vehicles"] = 1 + data["depot"] = 0 return data # [END data_model] @@ -49,18 +49,18 @@ def create_data_model(): # [START solution_printer] def print_solution(manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()} miles') + print(f"Objective: {solution.ObjectiveValue()} miles") index = routing.Start(0) - plan_output = 'Route for vehicle 0:\n' + plan_output = "Route for vehicle 0:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} ->' + plan_output += f" {manager.IndexToNode(index)} ->" previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle(previous_index, index, 0) - plan_output += f' {manager.IndexToNode(index)}\n' + plan_output += f" {manager.IndexToNode(index)}\n" print(plan_output) - plan_output += f'Route distance: {route_distance}miles\n' + plan_output += f"Route distance: {route_distance}miles\n" # [END solution_printer] @@ -73,8 +73,9 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["distance_matrix"]), data["num_vehicles"], data["depot"] + ) # [END index_manager] # Create Routing Model. @@ -89,7 +90,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) # [END transit_callback] @@ -103,7 +104,8 @@ def distance_callback(from_index, to_index): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # [END parameters] # Solve the problem. @@ -118,6 +120,6 @@ def distance_callback(from_index, to_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/tsp_distance_matrix.py b/ortools/constraint_solver/samples/tsp_distance_matrix.py index e5876cc3231..3efcae29f4d 100755 --- a/ortools/constraint_solver/samples/tsp_distance_matrix.py +++ b/ortools/constraint_solver/samples/tsp_distance_matrix.py @@ -25,78 +25,29 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] - data['num_vehicles'] = 1 - data['depot'] = 0 + data["num_vehicles"] = 1 + data["depot"] = 0 return data # [END data_model] @@ -104,17 +55,17 @@ def create_data_model(): # [START solution_printer] def print_solution(manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') + print(f"Objective: {solution.ObjectiveValue()}") index = routing.Start(0) - plan_output = 'Route for vehicle 0:\n' + plan_output = "Route for vehicle 0:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} ->' + plan_output += f" {manager.IndexToNode(index)} ->" previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle(previous_index, index, 0) - plan_output += f' {manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + plan_output += f" {manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) # [END solution_printer] @@ -128,14 +79,14 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['depot']) + 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. @@ -145,7 +96,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) # [END transit_callback] @@ -159,7 +110,8 @@ def distance_callback(from_index, to_index): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # [END parameters] # Solve the problem. @@ -174,6 +126,6 @@ def distance_callback(from_index, to_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp.py b/ortools/constraint_solver/samples/vrp.py index 04d0570f142..3805d4c72ee 100755 --- a/ortools/constraint_solver/samples/vrp.py +++ b/ortools/constraint_solver/samples/vrp.py @@ -33,78 +33,29 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -112,23 +63,24 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') + print(f"Objective: {solution.ObjectiveValue()}") total_distance = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} ->' + plan_output += f" {manager.IndexToNode(index)} ->" previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f' {manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + previous_index, index, vehicle_id + ) + plan_output += f" {manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) total_distance += route_distance - print(f'Total Distance of all routes: {total_distance}m') + print(f"Total Distance of all routes: {total_distance}m") # [END solution_printer] @@ -142,14 +94,14 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['depot']) + 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. @@ -159,7 +111,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) # [END transit_callback] @@ -173,7 +125,8 @@ def distance_callback(from_index, to_index): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # [END parameters] # Solve the problem. @@ -186,10 +139,10 @@ def distance_callback(from_index, to_index): if solution: print_solution(data, manager, routing, solution) else: - print('No solution found !') + print("No solution found !") # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_breaks.py b/ortools/constraint_solver/samples/vrp_breaks.py index fb2335ff5c8..7a5d00d125d 100755 --- a/ortools/constraint_solver/samples/vrp_breaks.py +++ b/ortools/constraint_solver/samples/vrp_breaks.py @@ -33,9 +33,9 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['num_vehicles'] = 4 - data['depot'] = 0 - data['time_matrix'] = [ + data["num_vehicles"] = 4 + data["depot"] = 0 + data["time_matrix"] = [ [0, 27, 38, 34, 29, 13, 25, 9, 15, 9, 26, 25, 19, 17, 23, 38, 33], [27, 0, 34, 15, 9, 25, 36, 17, 34, 37, 54, 29, 24, 33, 50, 43, 60], [38, 34, 0, 49, 43, 25, 13, 40, 23, 37, 20, 63, 58, 56, 39, 77, 37], @@ -55,9 +55,9 @@ def create_data_model(): [33, 60, 37, 67, 62, 35, 24, 42, 25, 23, 17, 42, 36, 26, 9, 39, 0], ] # 15 min of service time - data['service_time'] = [15] * len(data['time_matrix']) - data['service_time'][data['depot']] = 0 - assert len(data['time_matrix']) == len(data['service_time']) + data["service_time"] = [15] * len(data["time_matrix"]) + data["service_time"][data["depot"]] = 0 + assert len(data["time_matrix"]) == len(data["service_time"]) return data # [END data_model] @@ -65,35 +65,37 @@ def create_data_model(): # [START solution_printer] def print_solution(manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') + print(f"Objective: {solution.ObjectiveValue()}") - print('Breaks:') + print("Breaks:") intervals = solution.IntervalVarContainer() for i in range(intervals.Size()): brk = intervals.Element(i) if brk.PerformedValue(): - print(f'{brk.Var().Name()}: ' + - f'Start({brk.StartValue()}) Duration({brk.DurationValue()})') + print( + f"{brk.Var().Name()}: " + + f"Start({brk.StartValue()}) Duration({brk.DurationValue()})" + ) else: - print(f'{brk.Var().Name()}: Unperformed') + print(f"{brk.Var().Name()}: Unperformed") - time_dimension = routing.GetDimensionOrDie('Time') + time_dimension = routing.GetDimensionOrDie("Time") total_time = 0 for vehicle_id in range(manager.GetNumberOfVehicles()): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" while not routing.IsEnd(index): time_var = time_dimension.CumulVar(index) - plan_output += f'{manager.IndexToNode(index)} ' - plan_output += f'Time({solution.Value(time_var)}) -> ' + plan_output += f"{manager.IndexToNode(index)} " + plan_output += f"Time({solution.Value(time_var)}) -> " index = solution.Value(routing.NextVar(index)) time_var = time_dimension.CumulVar(index) - plan_output += f'{manager.IndexToNode(index)} ' - plan_output += f'Time({solution.Value(time_var)})\n' - plan_output += f'Time of the route: {solution.Value(time_var)}min\n' + plan_output += f"{manager.IndexToNode(index)} " + plan_output += f"Time({solution.Value(time_var)})\n" + plan_output += f"Time of the route: {solution.Value(time_var)}min\n" print(plan_output) total_time += solution.Value(time_var) - print(f'Total time of all routes: {total_time}min') + print(f"Total time of all routes: {total_time}min") # [END solution_printer] @@ -106,14 +108,14 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['time_matrix']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["time_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. @@ -123,8 +125,7 @@ def time_callback(from_index, to_index): # 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] + data['service_time'][ - from_node] + return data["time_matrix"][from_node][to_node] + data["service_time"][from_node] transit_callback_index = routing.RegisterTransitCallback(time_callback) # [END transit_callback] @@ -135,13 +136,14 @@ def time_callback(from_index, to_index): # [END arc_cost] # Add Time Windows constraint. - time = 'Time' + time = "Time" routing.AddDimension( transit_callback_index, 10, # needed optional waiting time to place break 180, # maximum time per vehicle True, # Force start cumul to zero. - time) + time, + ) time_dimension = routing.GetDimensionOrDie(time) time_dimension.SetGlobalSpanCostCoefficient(10) @@ -151,7 +153,7 @@ def time_callback(from_index, to_index): node_visit_transit = [0] * routing.Size() for index in range(routing.Size()): node = manager.IndexToNode(index) - node_visit_transit[index] = data['service_time'][node] + node_visit_transit[index] = data["service_time"][node] break_intervals = {} for v in range(manager.GetNumberOfVehicles()): @@ -161,21 +163,23 @@ def time_callback(from_index, to_index): 60, # start max 10, # duration: 10 min False, # optional: no - f'Break for vehicle {v}') + f"Break for vehicle {v}", + ) ] time_dimension.SetBreakIntervalsOfVehicle( - break_intervals[v], # breaks - v, # vehicle index - node_visit_transit) + break_intervals[v], v, node_visit_transit # breaks # vehicle index + ) # [END break_constraint] # Setting first solution heuristic. # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) search_parameters.local_search_metaheuristic = ( - routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) + routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH + ) # search_parameters.log_search = True search_parameters.time_limit.FromSeconds(2) # [END parameters] @@ -190,10 +194,10 @@ def time_callback(from_index, to_index): if solution: print_solution(manager, routing, solution) else: - print('No solution found !') + print("No solution found !") # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_capacity.py b/ortools/constraint_solver/samples/vrp_capacity.py index a8aaa59bec6..c092ed02c77 100755 --- a/ortools/constraint_solver/samples/vrp_capacity.py +++ b/ortools/constraint_solver/samples/vrp_capacity.py @@ -25,82 +25,33 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] # [START demands_capacities] - data['demands'] = [0, 1, 1, 2, 4, 2, 4, 8, 8, 1, 2, 1, 2, 4, 4, 8, 8] - data['vehicle_capacities'] = [15, 15, 15, 15] + data["demands"] = [0, 1, 1, 2, 4, 2, 4, 8, 8, 1, 2, 1, 2, 4, 4, 8, 8] + data["vehicle_capacities"] = [15, 15, 15, 15] # [END demands_capacities] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -108,30 +59,31 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') + print(f"Objective: {solution.ObjectiveValue()}") total_distance = 0 total_load = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 route_load = 0 while not routing.IsEnd(index): node_index = manager.IndexToNode(index) - route_load += data['demands'][node_index] - plan_output += f' {node_index} Load({route_load}) -> ' + route_load += data["demands"][node_index] + plan_output += f" {node_index} Load({route_load}) -> " previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f' {manager.IndexToNode(index)} Load({route_load})\n' - plan_output += f'Distance of the route: {route_distance}m\n' - plan_output += f'Load of the route: {route_load}\n' + previous_index, index, vehicle_id + ) + plan_output += f" {manager.IndexToNode(index)} Load({route_load})\n" + plan_output += f"Distance of the route: {route_distance}m\n" + plan_output += f"Load of the route: {route_load}\n" print(plan_output) total_distance += route_distance total_load += route_load - print(f'Total distance of all routes: {total_distance}m') - print(f'Total load of all routes: {total_load}') + print(f"Total distance of all routes: {total_distance}m") + print(f"Total load of all routes: {total_load}") # [END solution_printer] @@ -144,14 +96,14 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['depot']) + 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. @@ -161,7 +113,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) # [END transit_callback] @@ -169,7 +121,6 @@ def distance_callback(from_index, to_index): # Define cost of each arc. # [START arc_cost] routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) - # [END arc_cost] # Add Capacity constraint. @@ -178,25 +129,27 @@ 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] + return data["demands"][from_node] - demand_callback_index = routing.RegisterUnaryTransitCallback( - demand_callback) + demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback) routing.AddDimensionWithVehicleCapacity( demand_callback_index, 0, # null capacity slack - data['vehicle_capacities'], # vehicle maximum capacities + data["vehicle_capacities"], # vehicle maximum capacities True, # start cumul to zero - 'Capacity') + "Capacity", + ) # [END capacity_constraint] # Setting first solution heuristic. # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) search_parameters.local_search_metaheuristic = ( - routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) + routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH + ) search_parameters.time_limit.FromSeconds(1) # [END parameters] @@ -212,6 +165,6 @@ def demand_callback(from_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_drop_nodes.py b/ortools/constraint_solver/samples/vrp_drop_nodes.py index db9dd6d6c01..77bb46983b1 100755 --- a/ortools/constraint_solver/samples/vrp_drop_nodes.py +++ b/ortools/constraint_solver/samples/vrp_drop_nodes.py @@ -25,82 +25,33 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] # [START demands_capacities] - data['demands'] = [0, 1, 1, 3, 6, 3, 6, 8, 8, 1, 2, 1, 2, 6, 6, 8, 8] - data['vehicle_capacities'] = [15, 15, 15, 15] + data["demands"] = [0, 1, 1, 3, 6, 3, 6, 8, 8, 1, 2, 1, 2, 6, 6, 8, 8] + data["vehicle_capacities"] = [15, 15, 15, 15] # [END demands_capacities] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -108,39 +59,40 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, assignment): """Prints assignment on console.""" - print(f'Objective: {assignment.ObjectiveValue()}') + print(f"Objective: {assignment.ObjectiveValue()}") # Display dropped nodes. - dropped_nodes = 'Dropped nodes:' + dropped_nodes = "Dropped nodes:" for node in range(routing.Size()): if routing.IsStart(node) or routing.IsEnd(node): continue if assignment.Value(routing.NextVar(node)) == node: - dropped_nodes += f' {manager.IndexToNode(node)}' + dropped_nodes += f" {manager.IndexToNode(node)}" print(dropped_nodes) # Display routes total_distance = 0 total_load = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 route_load = 0 while not routing.IsEnd(index): node_index = manager.IndexToNode(index) - route_load += data['demands'][node_index] - plan_output += f' {node_index} Load({route_load}) -> ' + route_load += data["demands"][node_index] + plan_output += f" {node_index} Load({route_load}) -> " previous_index = index index = assignment.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f' {manager.IndexToNode(index)} Load({route_load})\n' - plan_output += f'Distance of the route: {route_distance}m\n' - plan_output += f'Load of the route: {route_load}\n' + previous_index, index, vehicle_id + ) + plan_output += f" {manager.IndexToNode(index)} Load({route_load})\n" + plan_output += f"Distance of the route: {route_distance}m\n" + plan_output += f"Load of the route: {route_load}\n" print(plan_output) total_distance += route_distance total_load += route_load - print(f'Total Distance of all routes: {total_distance}m') - print(f'Total Load of all routes: {total_load}') + print(f"Total Distance of all routes: {total_distance}m") + print(f"Total Load of all routes: {total_load}") # [END solution_printer] @@ -153,14 +105,14 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['depot']) + 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. @@ -170,7 +122,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) # [END transit_callback] @@ -178,7 +130,6 @@ def distance_callback(from_index, to_index): # Define cost of each arc. # [START arc_cost] routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) - # [END arc_cost] # Add Capacity constraint. @@ -187,19 +138,19 @@ 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] + return data["demands"][from_node] - demand_callback_index = routing.RegisterUnaryTransitCallback( - demand_callback) + demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback) routing.AddDimensionWithVehicleCapacity( demand_callback_index, 0, # null capacity slack - data['vehicle_capacities'], # vehicle maximum capacities + data["vehicle_capacities"], # vehicle maximum capacities True, # start cumul to zero - 'Capacity') + "Capacity", + ) # Allow to drop nodes. penalty = 1000 - for node in range(1, len(data['distance_matrix'])): + for node in range(1, len(data["distance_matrix"])): routing.AddDisjunction([manager.NodeToIndex(node)], penalty) # [END capacity_constraint] @@ -207,9 +158,11 @@ def demand_callback(from_index): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) search_parameters.local_search_metaheuristic = ( - routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) + routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH + ) search_parameters.time_limit.FromSeconds(1) # [END parameters] @@ -225,6 +178,6 @@ def demand_callback(from_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_global_span.py b/ortools/constraint_solver/samples/vrp_global_span.py index c8f821ed889..f9d5b6777d4 100755 --- a/ortools/constraint_solver/samples/vrp_global_span.py +++ b/ortools/constraint_solver/samples/vrp_global_span.py @@ -33,78 +33,29 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -112,23 +63,24 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') + print(f"Objective: {solution.ObjectiveValue()}") max_route_distance = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} -> ' + plan_output += f" {manager.IndexToNode(index)} -> " previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f'{manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + previous_index, index, vehicle_id + ) + plan_output += f"{manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) max_route_distance = max(route_distance, max_route_distance) - print(f'Maximum of the route distances: {max_route_distance}m') + print(f"Maximum of the route distances: {max_route_distance}m") # [END solution_printer] @@ -142,14 +94,14 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['depot']) + 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. @@ -159,7 +111,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) # [END transit_callback] @@ -171,13 +123,14 @@ def distance_callback(from_index, to_index): # Add Distance constraint. # [START distance_constraint] - dimension_name = 'Distance' + dimension_name = "Distance" routing.AddDimension( transit_callback_index, 0, # no slack 3000, # vehicle maximum travel distance True, # start cumul to zero - dimension_name) + dimension_name, + ) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) # [END distance_constraint] @@ -186,7 +139,8 @@ def distance_callback(from_index, to_index): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # [END parameters] # Solve the problem. @@ -199,10 +153,10 @@ def distance_callback(from_index, to_index): if solution: print_solution(data, manager, routing, solution) else: - print('No solution found !') + print("No solution found !") # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_initial_routes.py b/ortools/constraint_solver/samples/vrp_initial_routes.py index 4f52e078ac3..065bc9e1d86 100755 --- a/ortools/constraint_solver/samples/vrp_initial_routes.py +++ b/ortools/constraint_solver/samples/vrp_initial_routes.py @@ -25,86 +25,37 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] # [START initial_routes] - data['initial_routes'] = [ + data["initial_routes"] = [ [8, 16, 14, 13, 12, 11], [3, 4, 9, 10], [15, 1], [7, 5, 2, 6], ] # [END initial_routes] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -112,23 +63,24 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') + print(f"Objective: {solution.ObjectiveValue()}") max_route_distance = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} -> ' + plan_output += f" {manager.IndexToNode(index)} -> " previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f'{manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + previous_index, index, vehicle_id + ) + plan_output += f"{manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) max_route_distance = max(route_distance, max_route_distance) - print(f'Maximum of the route distances: {max_route_distance}m') + print(f"Maximum of the route distances: {max_route_distance}m") # [END solution_printer] @@ -142,14 +94,14 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['depot']) + 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. @@ -159,7 +111,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) # [END transit_callback] @@ -171,13 +123,14 @@ def distance_callback(from_index, to_index): # Add Distance constraint. # [START distance_constraint] - dimension_name = 'Distance' + dimension_name = "Distance" routing.AddDimension( transit_callback_index, 0, # no slack 3000, # vehicle maximum travel distance True, # start cumul to zero - dimension_name) + dimension_name, + ) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) # [END distance_constraint] @@ -197,26 +150,26 @@ def distance_callback(from_index, to_index): # Get initial solution from routes after closing the model. # [START print_initial_solution] - initial_solution = routing.ReadAssignmentFromRoutes(data['initial_routes'], - True) - 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] # Solve the problem. # [START solve] solution = routing.SolveFromAssignmentWithParameters( - initial_solution, search_parameters) + initial_solution, search_parameters + ) # [END solve] # Print solution on console. # [START print_solution] if solution: - print('Solution after search:') + print("Solution after search:") print_solution(data, manager, routing, solution) # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_node_max.py b/ortools/constraint_solver/samples/vrp_node_max.py index 7176e7f09a6..190f9ec9d44 100755 --- a/ortools/constraint_solver/samples/vrp_node_max.py +++ b/ortools/constraint_solver/samples/vrp_node_max.py @@ -29,77 +29,28 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] - data['value'] = [ + data["value"] = [ 0, # depot 42, # 1 42, # 2 @@ -118,9 +69,9 @@ def create_data_model(): 42, # 15 42, # 16 ] - assert len(data['distance_matrix']) == len(data['value']) - data['num_vehicles'] = 4 - data['depot'] = 0 + assert len(data["distance_matrix"]) == len(data["value"]) + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -129,14 +80,14 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') + print(f"Objective: {solution.ObjectiveValue()}") max_route_distance = 0 - dim_one = routing.GetDimensionOrDie('One') - dim_two = routing.GetDimensionOrDie('Two') + dim_one = routing.GetDimensionOrDie("One") + dim_two = routing.GetDimensionOrDie("Two") - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 while not routing.IsEnd(index): one_var = dim_one.CumulVar(index) @@ -144,23 +95,27 @@ def print_solution(data, manager, routing, solution): two_var = dim_two.CumulVar(index) two_slack_var = dim_two.SlackVar(index) plan_output += ( - f' N:{manager.IndexToNode(index)}' - f' one:({solution.Value(one_var)}, {solution.Value(one_slack_var)})' - f' two:({solution.Value(two_var)}, {solution.Value(two_slack_var)})' - ' -> ') + f" N:{manager.IndexToNode(index)}" + f" one:({solution.Value(one_var)}, {solution.Value(one_slack_var)})" + f" two:({solution.Value(two_var)}, {solution.Value(two_slack_var)})" + " -> " + ) previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) + previous_index, index, vehicle_id + ) one_var = dim_one.CumulVar(index) two_var = dim_two.CumulVar(index) - plan_output += (f'N:{manager.IndexToNode(index)}' - f' one:{solution.Value(one_var)}' - f' two:{solution.Value(two_var)}\n') - plan_output += f'Distance of the route: {route_distance}m\n' + plan_output += ( + f"N:{manager.IndexToNode(index)}" + f" one:{solution.Value(one_var)}" + f" two:{solution.Value(two_var)}\n" + ) + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) max_route_distance = max(route_distance, max_route_distance) - print(f'Maximum of the route distances: {max_route_distance}m') + print(f"Maximum of the route distances: {max_route_distance}m") # [END solution_printer] @@ -174,8 +129,9 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["distance_matrix"]), data["num_vehicles"], data["depot"] + ) # [END index_manager] # Create Routing Model. @@ -191,7 +147,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) # [END transit_callback] @@ -203,13 +159,14 @@ def distance_callback(from_index, to_index): # Add Distance constraint. # [START distance_constraint] - dimension_name = 'Distance' + dimension_name = "Distance" routing.AddDimension( transit_callback_index, 0, # no slack 3_000, # vehicle maximum travel distance True, # start cumul to zero - dimension_name) + dimension_name, + ) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(10) # [END distance_constraint] @@ -222,8 +179,9 @@ def distance_callback(from_index, to_index): 42 * 16, # capacity: be able to store PEAK*ROUTE_LENGTH in worst case 42, # slack_max: to be able to store peak in slack True, # Fix StartCumulToZero not really matter here - 'One') - dim_one = routing.GetDimensionOrDie('One') + "One", + ) + dim_one = routing.GetDimensionOrDie("One") # Dimension Two will be used to store the max node value in the route end node # CumulVar so we can use it as an objective cost. @@ -232,16 +190,17 @@ def distance_callback(from_index, to_index): 42 * 16, # capacity: be able to have PEAK value in CumulVar(End) 42, # slack_max: to be able to store peak in slack True, # Fix StartCumulToZero YES here - 'Two') - dim_two = routing.GetDimensionOrDie('Two') + "Two", + ) + dim_two = routing.GetDimensionOrDie("Two") # force depot Slack to be value since we don't have any predecessor... for v in range(manager.GetNumberOfVehicles()): start = routing.Start(v) - dim_one.SlackVar(start).SetValue(data['value'][0]) + dim_one.SlackVar(start).SetValue(data["value"][0]) routing.AddToAssignment(dim_one.SlackVar(start)) - dim_two.SlackVar(start).SetValue(data['value'][0]) + dim_two.SlackVar(start).SetValue(data["value"][0]) routing.AddToAssignment(dim_two.SlackVar(start)) # Step by step relation @@ -255,14 +214,12 @@ def distance_callback(from_index, to_index): for v in range(manager.GetNumberOfVehicles()): previous_index = routing.Start(v) cond = routing.NextVar(previous_index) == index - value = solver.Max(dim_one.SlackVar(previous_index), - data['value'][node]) + value = solver.Max(dim_one.SlackVar(previous_index), data["value"][node]) test.append((cond * value).Var()) for previous in range(1, 17): previous_index = manager.NodeToIndex(previous) cond = routing.NextVar(previous_index) == index - value = solver.Max(dim_one.SlackVar(previous_index), - data['value'][node]) + value = solver.Max(dim_one.SlackVar(previous_index), data["value"][node]) test.append((cond * value).Var()) solver.Add(solver.Sum(test) == dim_one.SlackVar(index)) @@ -286,9 +243,11 @@ def distance_callback(from_index, to_index): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) search_parameters.local_search_metaheuristic = ( - routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) + routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH + ) # search_parameters.log_search = True search_parameters.time_limit.FromSeconds(5) # [END parameters] @@ -303,10 +262,10 @@ def distance_callback(from_index, to_index): if solution: print_solution(data, manager, routing, solution) else: - print('No solution found !') + print("No solution found !") # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_pickup_delivery.py b/ortools/constraint_solver/samples/vrp_pickup_delivery.py index 0dd3c9ce56c..9257f0bea01 100755 --- a/ortools/constraint_solver/samples/vrp_pickup_delivery.py +++ b/ortools/constraint_solver/samples/vrp_pickup_delivery.py @@ -25,78 +25,29 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] # [START pickups_deliveries] - data['pickups_deliveries'] = [ + data["pickups_deliveries"] = [ [1, 6], [2, 10], [4, 3], @@ -107,8 +58,8 @@ def create_data_model(): [16, 14], ] # [END pickups_deliveries] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -116,23 +67,24 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') + print(f"Objective: {solution.ObjectiveValue()}") total_distance = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} -> ' + plan_output += f" {manager.IndexToNode(index)} -> " previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f'{manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + previous_index, index, vehicle_id + ) + plan_output += f"{manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) total_distance += route_distance - print(f'Total Distance of all routes: {total_distance}m') + print(f"Total Distance of all routes: {total_distance}m") # [END solution_printer] @@ -145,8 +97,9 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["distance_matrix"]), data["num_vehicles"], data["depot"] + ) # [END index_manager] # Create Routing Model. @@ -162,7 +115,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) @@ -170,36 +123,39 @@ def distance_callback(from_index, to_index): # Add Distance constraint. # [START distance_constraint] - dimension_name = 'Distance' + dimension_name = "Distance" routing.AddDimension( transit_callback_index, 0, # no slack 3000, # vehicle maximum travel distance True, # start cumul to zero - dimension_name) + 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']: + 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.VehicleVar(pickup_index) == routing.VehicleVar(delivery_index) + ) routing.solver().Add( - distance_dimension.CumulVar(pickup_index) <= - distance_dimension.CumulVar(delivery_index)) + distance_dimension.CumulVar(pickup_index) + <= distance_dimension.CumulVar(delivery_index) + ) # [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) + routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION + ) # [END parameters] # Solve the problem. @@ -214,6 +170,6 @@ def distance_callback(from_index, to_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_pickup_delivery_fifo.py b/ortools/constraint_solver/samples/vrp_pickup_delivery_fifo.py index 7ec0ade93cf..e3161a407c1 100755 --- a/ortools/constraint_solver/samples/vrp_pickup_delivery_fifo.py +++ b/ortools/constraint_solver/samples/vrp_pickup_delivery_fifo.py @@ -25,78 +25,29 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] # [START pickups_deliveries] - data['pickups_deliveries'] = [ + data["pickups_deliveries"] = [ [1, 6], [2, 10], [4, 3], @@ -107,8 +58,8 @@ def create_data_model(): [16, 14], ] # [END pickups_deliveries] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -116,23 +67,24 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, assignment): """Prints assignment on console.""" - print(f'Objective: {assignment.ObjectiveValue()}') + print(f"Objective: {assignment.ObjectiveValue()}") total_distance = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} -> ' + plan_output += f" {manager.IndexToNode(index)} -> " previous_index = index index = assignment.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f'{manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + previous_index, index, vehicle_id + ) + plan_output += f"{manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) total_distance += route_distance - print(f'Total Distance of all routes: {total_distance}m') + print(f"Total Distance of all routes: {total_distance}m") # [END solution_printer] @@ -145,8 +97,9 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["distance_matrix"]), data["num_vehicles"], data["depot"] + ) # [END index_manager] # Create Routing Model. @@ -162,7 +115,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) @@ -170,38 +123,42 @@ def distance_callback(from_index, to_index): # Add Distance constraint. # [START distance_constraint] - dimension_name = 'Distance' + dimension_name = "Distance" routing.AddDimension( transit_callback_index, 0, # no slack 3000, # vehicle maximum travel distance True, # start cumul to zero - dimension_name) + 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']: + 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.VehicleVar(pickup_index) == routing.VehicleVar(delivery_index) + ) routing.solver().Add( - distance_dimension.CumulVar(pickup_index) <= - distance_dimension.CumulVar(delivery_index)) + distance_dimension.CumulVar(pickup_index) + <= distance_dimension.CumulVar(delivery_index) + ) routing.SetPickupAndDeliveryPolicyOfAllVehicles( - pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_FIFO) + pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_FIFO + ) # [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) + routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION + ) # [END parameters] # Solve the problem. @@ -216,6 +173,6 @@ def distance_callback(from_index, to_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_pickup_delivery_lifo.py b/ortools/constraint_solver/samples/vrp_pickup_delivery_lifo.py index bf04dba1582..b7420d676ef 100755 --- a/ortools/constraint_solver/samples/vrp_pickup_delivery_lifo.py +++ b/ortools/constraint_solver/samples/vrp_pickup_delivery_lifo.py @@ -25,78 +25,29 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] # [START pickups_deliveries] - data['pickups_deliveries'] = [ + data["pickups_deliveries"] = [ [1, 6], [2, 10], [4, 3], @@ -107,8 +58,8 @@ def create_data_model(): [16, 14], ] # [END pickups_deliveries] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -116,23 +67,24 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, assignment): """Prints assignment on console.""" - print(f'Objective: {assignment.ObjectiveValue()}') + print(f"Objective: {assignment.ObjectiveValue()}") total_distance = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} -> ' + plan_output += f" {manager.IndexToNode(index)} -> " previous_index = index index = assignment.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f'{manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + previous_index, index, vehicle_id + ) + plan_output += f"{manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) total_distance += route_distance - print(f'Total Distance of all routes: {total_distance}m') + print(f"Total Distance of all routes: {total_distance}m") # [END solution_printer] @@ -145,8 +97,9 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["distance_matrix"]), data["num_vehicles"], data["depot"] + ) # [END index_manager] # Create Routing Model. @@ -162,7 +115,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) @@ -170,38 +123,42 @@ def distance_callback(from_index, to_index): # Add Distance constraint. # [START distance_constraint] - dimension_name = 'Distance' + dimension_name = "Distance" routing.AddDimension( transit_callback_index, 0, # no slack 3000, # vehicle maximum travel distance True, # start cumul to zero - dimension_name) + 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']: + 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.VehicleVar(pickup_index) == routing.VehicleVar(delivery_index) + ) routing.solver().Add( - distance_dimension.CumulVar(pickup_index) <= - distance_dimension.CumulVar(delivery_index)) + distance_dimension.CumulVar(pickup_index) + <= distance_dimension.CumulVar(delivery_index) + ) routing.SetPickupAndDeliveryPolicyOfAllVehicles( - pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_LIFO) + 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) + routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION + ) # [END parameters] # Solve the problem. @@ -216,6 +173,6 @@ def distance_callback(from_index, to_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_resources.py b/ortools/constraint_solver/samples/vrp_resources.py index 3bfc6c6169c..3ad160814fc 100755 --- a/ortools/constraint_solver/samples/vrp_resources.py +++ b/ortools/constraint_solver/samples/vrp_resources.py @@ -25,7 +25,7 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['time_matrix'] = [ + data["time_matrix"] = [ [0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7], [6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14], [9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9], @@ -44,7 +44,7 @@ def create_data_model(): [9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9], [7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0], ] - data['time_windows'] = [ + data["time_windows"] = [ (0, 5), # depot (7, 12), # 1 (10, 15), # 2 @@ -63,13 +63,13 @@ def create_data_model(): (10, 15), # 15 (5, 15), # 16 ] - data['num_vehicles'] = 4 + data["num_vehicles"] = 4 # [START resources_data] - data['vehicle_load_time'] = 5 - data['vehicle_unload_time'] = 5 - data['depot_capacity'] = 2 + data["vehicle_load_time"] = 5 + data["vehicle_unload_time"] = 5 + data["depot_capacity"] = 2 # [END resources_data] - data['depot'] = 0 + data["depot"] = 0 return data # [END data_model] @@ -77,27 +77,29 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') - time_dimension = routing.GetDimensionOrDie('Time') + print(f"Objective: {solution.ObjectiveValue()}") + time_dimension = routing.GetDimensionOrDie("Time") total_time = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" while not routing.IsEnd(index): time_var = time_dimension.CumulVar(index) plan_output += ( - f'{manager.IndexToNode(index)}' - f' Time({solution.Min(time_var)}, {solution.Max(time_var)})' - ' -> ') + f"{manager.IndexToNode(index)}" + f" Time({solution.Min(time_var)}, {solution.Max(time_var)})" + " -> " + ) index = solution.Value(routing.NextVar(index)) time_var = time_dimension.CumulVar(index) plan_output += ( - f'{manager.IndexToNode(index)}' - f' Time({solution.Min(time_var)},{solution.Max(time_var)})\n') - plan_output += f'Time of the route: {solution.Min(time_var)}min\n' + f"{manager.IndexToNode(index)}" + f" Time({solution.Min(time_var)},{solution.Max(time_var)})\n" + ) + plan_output += f"Time of the route: {solution.Min(time_var)}min\n" print(plan_output) total_time += solution.Min(time_var) - print(f'Total time of all routes: {total_time}min') + print(f"Total time of all routes: {total_time}min") # [END solution_printer] @@ -110,14 +112,14 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['time_matrix']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["time_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. @@ -127,7 +129,7 @@ def time_callback(from_index, to_index): # 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] + return data["time_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(time_callback) # [END transit_callback] @@ -139,65 +141,74 @@ def time_callback(from_index, to_index): # Add Time Windows constraint. # [START time_windows_constraint] - time = 'Time' + time = "Time" routing.AddDimension( transit_callback_index, 60, # allow waiting time 60, # maximum time per vehicle False, # Don't force start cumul to zero. - time) + 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']): + 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']): + 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]) + time_dimension.CumulVar(index).SetRange( + data["time_windows"][0][0], data["time_windows"][0][1] + ) # [END time_windows_constraint] # Add resource constraints at the depot. # [START depot_load_time] solver = routing.solver() intervals = [] - for i in range(data['num_vehicles']): + for i in range(data["num_vehicles"]): # Add time windows at start of routes intervals.append( solver.FixedDurationIntervalVar( time_dimension.CumulVar(routing.Start(i)), - data['vehicle_load_time'], 'depot_interval')) + data["vehicle_load_time"], + "depot_interval", + ) + ) # Add time windows at end of routes. intervals.append( solver.FixedDurationIntervalVar( time_dimension.CumulVar(routing.End(i)), - data['vehicle_unload_time'], 'depot_interval')) + data["vehicle_unload_time"], + "depot_interval", + ) + ) # [END depot_load_time] # [START depot_capacity] depot_usage = [1 for i in range(len(intervals))] solver.Add( - solver.Cumulative(intervals, depot_usage, data['depot_capacity'], - 'depot')) + solver.Cumulative(intervals, depot_usage, data["depot_capacity"], "depot") + ) # [END depot_capacity] # Instantiate route start and end times to produce feasible times. # [START depot_start_end_times] - for i in range(data['num_vehicles']): - routing.AddVariableMinimizedByFinalizer( - time_dimension.CumulVar(routing.Start(i))) + for i in range(data["num_vehicles"]): routing.AddVariableMinimizedByFinalizer( - time_dimension.CumulVar(routing.End(i))) + time_dimension.CumulVar(routing.Start(i)) + ) + routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(routing.End(i))) # [END depot_start_end_times] # Setting first solution heuristic. # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # [END parameters] # Solve the problem. @@ -211,9 +222,9 @@ def time_callback(from_index, to_index): print_solution(data, manager, routing, solution) # [END print_solution] else: - print('No solution found !') + print("No solution found !") -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_solution_callback.py b/ortools/constraint_solver/samples/vrp_solution_callback.py index bcd5a09370a..c42274e74b1 100755 --- a/ortools/constraint_solver/samples/vrp_solution_callback.py +++ b/ortools/constraint_solver/samples/vrp_solution_callback.py @@ -33,104 +33,57 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] # [START solution_callback_printer] -def print_solution(routing_manager: pywrapcp.RoutingIndexManager, - routing_model: pywrapcp.RoutingModel): +def print_solution( + routing_manager: pywrapcp.RoutingIndexManager, routing_model: pywrapcp.RoutingModel +): """Prints solution on console.""" - print('################') - print(f'Solution objective: {routing_model.CostVar().Value()}') + print("################") + print(f"Solution objective: {routing_model.CostVar().Value()}") total_distance = 0 for vehicle_id in range(routing_manager.GetNumberOfVehicles()): index = routing_model.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 while not routing_model.IsEnd(index): - plan_output += f' {routing_manager.IndexToNode(index)} ->' + plan_output += f" {routing_manager.IndexToNode(index)} ->" previous_index = index index = routing_model.NextVar(index).Value() route_distance += routing_model.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f' {routing_manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + previous_index, index, vehicle_id + ) + plan_output += f" {routing_manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) total_distance += route_distance - print(f'Total Distance of all routes: {total_distance}m') + print(f"Total Distance of all routes: {total_distance}m") # [END solution_callback_printer] @@ -138,8 +91,12 @@ def print_solution(routing_manager: pywrapcp.RoutingIndexManager, class SolutionCallback: """Create a solution callback.""" - def __init__(self, manager: pywrapcp.RoutingIndexManager, - model: pywrapcp.RoutingModel, limit: int): + def __init__( + self, + manager: pywrapcp.RoutingIndexManager, + model: pywrapcp.RoutingModel, + limit: int, + ): self._routing_manager = manager self._routing_model = model self._counter = 0 @@ -166,9 +123,9 @@ def main(): # Create the routing index manager. # [START index_manager] - routing_manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], - data['depot']) + routing_manager = pywrapcp.RoutingIndexManager( + len(data["distance_matrix"]), data["num_vehicles"], data["depot"] + ) # [END index_manager] # Create Routing Model. @@ -184,10 +141,9 @@ def distance_callback(from_index, to_index): # Convert from routing variable Index to distance matrix NodeIndex. from_node = routing_manager.IndexToNode(from_index) to_node = routing_manager.IndexToNode(to_index) - return data['distance_matrix'][from_node][to_node] + return data["distance_matrix"][from_node][to_node] - transit_callback_index = routing_model.RegisterTransitCallback( - distance_callback) + transit_callback_index = routing_model.RegisterTransitCallback(distance_callback) # [END transit_callback] # Define cost of each arc. @@ -197,13 +153,14 @@ def distance_callback(from_index, to_index): # Add Distance constraint. # [START distance_constraint] - dimension_name = 'Distance' + dimension_name = "Distance" routing_model.AddDimension( transit_callback_index, 0, # no slack 3000, # vehicle maximum travel distance True, # start cumul to zero - dimension_name) + dimension_name, + ) distance_dimension = routing_model.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) # [END distance_constraint] @@ -218,9 +175,11 @@ def distance_callback(from_index, to_index): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) search_parameters.local_search_metaheuristic = ( - routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) + routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH + ) search_parameters.time_limit.FromSeconds(5) # [END parameters] @@ -232,12 +191,12 @@ def distance_callback(from_index, to_index): # Print solution on console. # [START print_solution] if solution: - print(f'Best objective: {solution_callback.objectives[-1]}') + print(f"Best objective: {solution_callback.objectives[-1]}") else: - print('No solution found !') + print("No solution found !") # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_starts_ends.py b/ortools/constraint_solver/samples/vrp_starts_ends.py index f4c9855df57..89001716006 100755 --- a/ortools/constraint_solver/samples/vrp_starts_ends.py +++ b/ortools/constraint_solver/samples/vrp_starts_ends.py @@ -25,80 +25,31 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['distance_matrix'] = [ - [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, - 468, 776, 662 - ], - [ - 548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, - 1016, 868, 1210 - ], - [ - 776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, - 1130, 788, 1552, 754 - ], - [ - 696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, - 1164, 560, 1358 - ], - [ - 582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, - 1050, 674, 1244 - ], - [ - 274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, - 514, 1050, 708 - ], - [ - 502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, - 514, 1278, 480 - ], - [ - 194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, - 662, 742, 856 - ], - [ - 308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, - 320, 1084, 514 - ], - [ - 194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, - 274, 810, 468 - ], - [ - 536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, - 730, 388, 1152, 354 - ], - [ - 502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, - 308, 650, 274, 844 - ], - [ - 388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, - 536, 388, 730 - ], - [ - 354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, - 342, 422, 536 - ], - [ - 468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, - 342, 0, 764, 194 - ], - [ - 776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, - 388, 422, 764, 0, 798 - ], - [ - 662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, - 536, 194, 798, 0 - ], + data["distance_matrix"] = [ + # fmt: off + [0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, 354, 468, 776, 662], + [548, 0, 684, 308, 194, 502, 730, 354, 696, 742, 1084, 594, 480, 674, 1016, 868, 1210], + [776, 684, 0, 992, 878, 502, 274, 810, 468, 742, 400, 1278, 1164, 1130, 788, 1552, 754], + [696, 308, 992, 0, 114, 650, 878, 502, 844, 890, 1232, 514, 628, 822, 1164, 560, 1358], + [582, 194, 878, 114, 0, 536, 764, 388, 730, 776, 1118, 400, 514, 708, 1050, 674, 1244], + [274, 502, 502, 650, 536, 0, 228, 308, 194, 240, 582, 776, 662, 628, 514, 1050, 708], + [502, 730, 274, 878, 764, 228, 0, 536, 194, 468, 354, 1004, 890, 856, 514, 1278, 480], + [194, 354, 810, 502, 388, 308, 536, 0, 342, 388, 730, 468, 354, 320, 662, 742, 856], + [308, 696, 468, 844, 730, 194, 194, 342, 0, 274, 388, 810, 696, 662, 320, 1084, 514], + [194, 742, 742, 890, 776, 240, 468, 388, 274, 0, 342, 536, 422, 388, 274, 810, 468], + [536, 1084, 400, 1232, 1118, 582, 354, 730, 388, 342, 0, 878, 764, 730, 388, 1152, 354], + [502, 594, 1278, 514, 400, 776, 1004, 468, 810, 536, 878, 0, 114, 308, 650, 274, 844], + [388, 480, 1164, 628, 514, 662, 890, 354, 696, 422, 764, 114, 0, 194, 536, 388, 730], + [354, 674, 1130, 822, 708, 628, 856, 320, 662, 388, 730, 308, 194, 0, 342, 422, 536], + [468, 1016, 788, 1164, 1050, 514, 514, 662, 320, 274, 388, 650, 536, 342, 0, 764, 194], + [776, 868, 1552, 560, 674, 1050, 1278, 742, 1084, 810, 1152, 274, 388, 422, 764, 0, 798], + [662, 1210, 754, 1358, 1244, 708, 480, 856, 514, 468, 354, 844, 730, 536, 194, 798, 0], + # fmt: on ] - data['num_vehicles'] = 4 + data["num_vehicles"] = 4 # [START starts_ends] - data['starts'] = [1, 2, 15, 16] - data['ends'] = [0, 0, 0, 0] + data["starts"] = [1, 2, 15, 16] + data["ends"] = [0, 0, 0, 0] # [END starts_ends] return data # [END data_model] @@ -107,23 +58,24 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') + print(f"Objective: {solution.ObjectiveValue()}") max_route_distance = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} -> ' + plan_output += f" {manager.IndexToNode(index)} -> " previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f'{manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + previous_index, index, vehicle_id + ) + plan_output += f"{manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) max_route_distance = max(route_distance, max_route_distance) - print(f'Maximum of the route distances: {max_route_distance}m') + print(f"Maximum of the route distances: {max_route_distance}m") # [END solution_printer] @@ -136,15 +88,14 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']), - data['num_vehicles'], data['starts'], - data['ends']) + 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. @@ -154,7 +105,7 @@ def distance_callback(from_index, to_index): # 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] + return data["distance_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(distance_callback) # [END transit_callback] @@ -166,13 +117,14 @@ def distance_callback(from_index, to_index): # Add Distance constraint. # [START distance_constraint] - dimension_name = 'Distance' + dimension_name = "Distance" routing.AddDimension( transit_callback_index, 0, # no slack 2000, # vehicle maximum travel distance True, # start cumul to zero - dimension_name) + dimension_name, + ) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) # [END distance_constraint] @@ -181,7 +133,8 @@ def distance_callback(from_index, to_index): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # [END parameters] # Solve the problem. @@ -196,6 +149,6 @@ def distance_callback(from_index, to_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_time_windows.py b/ortools/constraint_solver/samples/vrp_time_windows.py index 342025e19a6..8d0fe007537 100755 --- a/ortools/constraint_solver/samples/vrp_time_windows.py +++ b/ortools/constraint_solver/samples/vrp_time_windows.py @@ -25,7 +25,7 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['time_matrix'] = [ + data["time_matrix"] = [ [0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7], [6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14], [9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9], @@ -44,7 +44,7 @@ def create_data_model(): [9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9], [7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0], ] - data['time_windows'] = [ + data["time_windows"] = [ (0, 5), # depot (7, 12), # 1 (10, 15), # 2 @@ -63,8 +63,8 @@ def create_data_model(): (10, 15), # 15 (11, 15), # 16 ] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -72,27 +72,29 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') - time_dimension = routing.GetDimensionOrDie('Time') + print(f"Objective: {solution.ObjectiveValue()}") + time_dimension = routing.GetDimensionOrDie("Time") total_time = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" while not routing.IsEnd(index): time_var = time_dimension.CumulVar(index) plan_output += ( - f'{manager.IndexToNode(index)}' - f' Time({solution.Min(time_var)},{solution.Max(time_var)})' - ' -> ') + f"{manager.IndexToNode(index)}" + f" Time({solution.Min(time_var)},{solution.Max(time_var)})" + " -> " + ) index = solution.Value(routing.NextVar(index)) time_var = time_dimension.CumulVar(index) plan_output += ( - f'{manager.IndexToNode(index)}' - f' Time({solution.Min(time_var)},{solution.Max(time_var)})\n') - plan_output += f'Time of the route: {solution.Min(time_var)}min\n' + f"{manager.IndexToNode(index)}" + f" Time({solution.Min(time_var)},{solution.Max(time_var)})\n" + ) + plan_output += f"Time of the route: {solution.Min(time_var)}min\n" print(plan_output) total_time += solution.Min(time_var) - print(f'Total time of all routes: {total_time}min') + print(f"Total time of all routes: {total_time}min") # [END solution_printer] @@ -105,14 +107,14 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['time_matrix']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["time_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. @@ -122,7 +124,7 @@ def time_callback(from_index, to_index): # 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] + return data["time_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(time_callback) # [END transit_callback] @@ -134,43 +136,45 @@ def time_callback(from_index, to_index): # Add Time Windows constraint. # [START time_windows_constraint] - time = 'Time' + time = "Time" routing.AddDimension( transit_callback_index, 30, # allow waiting time 30, # maximum time per vehicle False, # Don't force start cumul to zero. - time) + 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 == data['depot']: + for location_idx, time_window in enumerate(data["time_windows"]): + if location_idx == data["depot"]: 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. - depot_idx = data['depot'] - for vehicle_id in range(data['num_vehicles']): + depot_idx = data["depot"] + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) time_dimension.CumulVar(index).SetRange( - data['time_windows'][depot_idx][0], - data['time_windows'][depot_idx][1]) + data["time_windows"][depot_idx][0], data["time_windows"][depot_idx][1] + ) # [END time_windows_constraint] # Instantiate route start and end times to produce feasible times. # [START depot_start_end_times] - for i in range(data['num_vehicles']): - routing.AddVariableMinimizedByFinalizer( - time_dimension.CumulVar(routing.Start(i))) + for i in range(data["num_vehicles"]): routing.AddVariableMinimizedByFinalizer( - time_dimension.CumulVar(routing.End(i))) + time_dimension.CumulVar(routing.Start(i)) + ) + routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(routing.End(i))) # [END depot_start_end_times] # Setting first solution heuristic. # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # [END parameters] # Solve the problem. @@ -185,6 +189,6 @@ def time_callback(from_index, to_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrp_tokens.py b/ortools/constraint_solver/samples/vrp_tokens.py index faa7daf5417..d98b3d88cee 100755 --- a/ortools/constraint_solver/samples/vrp_tokens.py +++ b/ortools/constraint_solver/samples/vrp_tokens.py @@ -11,6 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + """Simple VRP with special locations which need to be visited at end of the route.""" # [START import] @@ -23,7 +24,7 @@ def create_data_model(): """Stores the data for the problem.""" data = {} # Special location don't consume token, while regular one consume one - data['tokens'] = [ + data["tokens"] = [ 0, # 0 depot 0, # 1 special node 0, # 2 special node @@ -45,20 +46,20 @@ def create_data_model(): -1, # 18 ] # just need to be big enough, not a limiting factor - data['vehicle_tokens'] = [20, 20, 20, 20] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["vehicle_tokens"] = [20, 20, 20, 20] + data["num_vehicles"] = 4 + data["depot"] = 0 return data def print_solution(manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') - token_dimension = routing.GetDimensionOrDie('Token') + print(f"Objective: {solution.ObjectiveValue()}") + token_dimension = routing.GetDimensionOrDie("Token") total_distance = 0 total_token = 0 for vehicle_id in range(manager.GetNumberOfVehicles()): - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" index = routing.Start(vehicle_id) total_token += solution.Value(token_dimension.CumulVar(index)) route_distance = 0 @@ -67,20 +68,21 @@ def print_solution(manager, routing, solution): node_index = manager.IndexToNode(index) token_var = token_dimension.CumulVar(index) route_token = solution.Value(token_var) - plan_output += f' {node_index} Token({route_token}) -> ' + plan_output += f" {node_index} Token({route_token}) -> " previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) + previous_index, index, vehicle_id + ) node_index = manager.IndexToNode(index) token_var = token_dimension.CumulVar(index) route_token = solution.Value(token_var) - plan_output += f' {node_index} Token({route_token})\n' - plan_output += f'Distance of the route: {route_distance}m\n' + plan_output += f" {node_index} Token({route_token})\n" + plan_output += f"Distance of the route: {route_distance}m\n" total_distance += route_distance print(plan_output) - print(f'Total distance of all routes: {total_distance}m') - print(f'Total token of all routes: {total_token}') + print(f"Total distance of all routes: {total_distance}m") + print(f"Total token of all routes: {total_token}") def main(): @@ -89,8 +91,9 @@ def main(): data = create_data_model() # Create the routing index manager. - manager = pywrapcp.RoutingIndexManager(len(data['tokens']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["tokens"]), data["num_vehicles"], data["depot"] + ) # Create Routing Model. routing = pywrapcp.RoutingModel(manager) @@ -109,8 +112,9 @@ def distance_callback(from_index, to_index): 0, # null slack 3000, # maximum distance per vehicle True, # start cumul to zero - 'distance') - distance_dimension = routing.GetDimensionOrDie('distance') + "distance", + ) + distance_dimension = routing.GetDimensionOrDie("distance") distance_dimension.SetGlobalSpanCostCoefficient(100) # Define cost of each arc. @@ -121,17 +125,18 @@ 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] + 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 + data["vehicle_tokens"], # vehicle maximum tokens False, # start cumul to zero - 'Token') + "Token", + ) # Add constraint: special node can only be visited if token remaining is zero - token_dimension = routing.GetDimensionOrDie('Token') + token_dimension = routing.GetDimensionOrDie("Token") for node in range(1, 6): index = manager.NodeToIndex(node) routing.solver().Add(token_dimension.CumulVar(index) == 0) @@ -140,17 +145,21 @@ def token_callback(from_index): # [START depot_start_end_times] for i in range(manager.GetNumberOfVehicles()): routing.AddVariableMinimizedByFinalizer( - token_dimension.CumulVar(routing.Start(i))) + token_dimension.CumulVar(routing.Start(i)) + ) routing.AddVariableMinimizedByFinalizer( - token_dimension.CumulVar(routing.End(i))) + token_dimension.CumulVar(routing.End(i)) + ) # [END depot_start_end_times] # Setting first solution heuristic. search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) search_parameters.local_search_metaheuristic = ( - routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) + routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH + ) search_parameters.time_limit.FromSeconds(1) # Solve the problem. @@ -161,9 +170,9 @@ def token_callback(from_index): if solution: print_solution(manager, routing, solution) else: - print('No solution found !') + print("No solution found !") # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/ortools/constraint_solver/samples/vrp_with_time_limit.py b/ortools/constraint_solver/samples/vrp_with_time_limit.py index 15af244c5b1..7720bd490d2 100755 --- a/ortools/constraint_solver/samples/vrp_with_time_limit.py +++ b/ortools/constraint_solver/samples/vrp_with_time_limit.py @@ -24,23 +24,24 @@ # [START solution_printer] def print_solution(manager, routing, solution): """Prints solution on console.""" - print(f'Objective: {solution.ObjectiveValue()}') + print(f"Objective: {solution.ObjectiveValue()}") max_route_distance = 0 for vehicle_id in range(manager.GetNumberOfVehicles()): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} -> ' + plan_output += f" {manager.IndexToNode(index)} -> " previous_index = index index = solution.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f'{manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + previous_index, index, vehicle_id + ) + plan_output += f"{manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) max_route_distance = max(route_distance, max_route_distance) - print(f'Maximum of the route distances: {max_route_distance}m') + print(f"Maximum of the route distances: {max_route_distance}m") # [END solution_printer] @@ -81,13 +82,14 @@ def distance_callback(from_index, to_index): # Add Distance constraint. # [START distance_constraint] - dimension_name = 'Distance' + dimension_name = "Distance" routing.AddDimension( transit_callback_index, 0, # no slack 3000, # vehicle maximum travel distance True, # start cumul to zero - dimension_name) + dimension_name, + ) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) # [END distance_constraint] @@ -96,9 +98,11 @@ def distance_callback(from_index, to_index): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) search_parameters.local_search_metaheuristic = ( - routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) + routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH + ) search_parameters.log_search = True search_parameters.time_limit.FromSeconds(5) # [END parameters] @@ -115,6 +119,6 @@ def distance_callback(from_index, to_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrpgs.py b/ortools/constraint_solver/samples/vrpgs.py index b6207e2ce81..83d94d04764 100755 --- a/ortools/constraint_solver/samples/vrpgs.py +++ b/ortools/constraint_solver/samples/vrpgs.py @@ -37,32 +37,26 @@ def create_data_model(): data = {} # Locations in block unit locations_ = [ - (4, 4), # depot - (2, 0), - (8, 0), # locations to visit - (0, 1), - (1, 1), - (5, 2), - (7, 2), - (3, 3), - (6, 3), - (5, 5), - (8, 5), - (1, 6), - (2, 6), - (3, 7), - (6, 7), - (0, 8), - (7, 8), + # fmt: off + (4, 4), # depot + (2, 0), (8, 0), # locations to visit + (0, 1), (1, 1), + (5, 2), (7, 2), + (3, 3), (6, 3), + (5, 5), (8, 5), + (1, 6), (2, 6), + (3, 7), (6, 7), + (0, 8), (7, 8), + # fmt: on ] # Compute locations in meters using the block dimension defined as follow # Manhattan average block: 750ft x 264ft -> 228m x 80m # here we use: 114m x 80m city block # src: https://nyti.ms/2GDoRIe 'NY Times: Know Your distance' - data['locations'] = [(l[0] * 114, l[1] * 80) for l in locations_] - data['num_locations'] = len(data['locations']) - data['num_vehicles'] = 4 - data['depot'] = 0 + data["locations"] = [(l[0] * 114, l[1] * 80) for l in locations_] + data["num_locations"] = len(data["locations"]) + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -71,23 +65,24 @@ def create_data_model(): # [START solution_printer] def print_solution(data, manager, routing, assignment): """Prints solution on console.""" - print(f'Objective: {assignment.ObjectiveValue()}') + print(f"Objective: {assignment.ObjectiveValue()}") total_distance = 0 - for vehicle_id in range(data['num_vehicles']): + for vehicle_id in range(data["num_vehicles"]): index = routing.Start(vehicle_id) - plan_output = f'Route for vehicle {vehicle_id}:\n' + plan_output = f"Route for vehicle {vehicle_id}:\n" route_distance = 0 while not routing.IsEnd(index): - plan_output += f' {manager.IndexToNode(index)} ->' + plan_output += f" {manager.IndexToNode(index)} ->" previous_index = index index = assignment.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( - previous_index, index, vehicle_id) - plan_output += f' {manager.IndexToNode(index)}\n' - plan_output += f'Distance of the route: {route_distance}m\n' + previous_index, index, vehicle_id + ) + plan_output += f" {manager.IndexToNode(index)}\n" + plan_output += f"Distance of the route: {route_distance}m\n" print(plan_output) total_distance += route_distance - print(f'Total Distance of all routes: {total_distance}m') + print(f"Total Distance of all routes: {total_distance}m") # [END solution_printer] @@ -97,22 +92,22 @@ def print_solution(data, manager, routing, assignment): ####################### def manhattan_distance(position_1, position_2): """Computes the Manhattan distance between two points.""" - return (abs(position_1[0] - position_2[0]) + - abs(position_1[1] - position_2[1])) + return abs(position_1[0] - position_2[0]) + abs(position_1[1] - position_2[1]) def create_distance_evaluator(data): """Creates callback to return distance between points.""" distances_ = {} # precompute distance between location to have distance callback in O(1) - for from_node in range(data['num_locations']): + for from_node in range(data["num_locations"]): distances_[from_node] = {} - for to_node in range(data['num_locations']): + for to_node in range(data["num_locations"]): if from_node == to_node: distances_[from_node][to_node] = 0 else: - distances_[from_node][to_node] = (manhattan_distance( - data['locations'][from_node], data['locations'][to_node])) + distances_[from_node][to_node] = manhattan_distance( + data["locations"][from_node], data["locations"][to_node] + ) def distance_evaluator(manager, from_index, to_index): """Returns the manhattan distance between the two nodes.""" @@ -126,13 +121,14 @@ def distance_evaluator(manager, from_index, to_index): def add_distance_dimension(routing, distance_evaluator_index): """Add Global Span constraint.""" - distance = 'Distance' + distance = "Distance" routing.AddDimension( distance_evaluator_index, 0, # null slack 3000, # maximum distance per vehicle True, # start cumul to zero - distance) + distance, + ) distance_dimension = routing.GetDimensionOrDie(distance) # Try to minimize the max distance among vehicles. # /!\ It doesn't mean the standard deviation is minimized @@ -148,8 +144,9 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(data['num_locations'], - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + data["num_locations"], data["num_vehicles"], data["depot"] + ) # [END index_manager] # Create Routing Model. @@ -160,7 +157,8 @@ def main(): # Define weight of each edge # [START transit_callback] distance_evaluator_index = routing.RegisterTransitCallback( - functools.partial(create_distance_evaluator(data), manager)) + functools.partial(create_distance_evaluator(data), manager) + ) # [END transit_callback] # Define cost of each arc. @@ -177,7 +175,8 @@ def main(): # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # [END parameters] # Solve the problem. @@ -190,10 +189,10 @@ def main(): if solution: print_solution(data, manager, routing, solution) else: - print('No solution found !') + print("No solution found !") # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program] diff --git a/ortools/constraint_solver/samples/vrptw_store_solution_data.py b/ortools/constraint_solver/samples/vrptw_store_solution_data.py index 09892e73ab8..b932405c669 100755 --- a/ortools/constraint_solver/samples/vrptw_store_solution_data.py +++ b/ortools/constraint_solver/samples/vrptw_store_solution_data.py @@ -26,7 +26,7 @@ def create_data_model(): """Stores the data for the problem.""" data = {} - data['time_matrix'] = [ + data["time_matrix"] = [ [0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7], [6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14], [9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9], @@ -45,7 +45,7 @@ def create_data_model(): [9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9], [7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0], ] - data['time_windows'] = [ + data["time_windows"] = [ (0, 5), # depot (7, 12), # 1 (10, 15), # 2 @@ -64,8 +64,8 @@ def create_data_model(): (10, 15), # 15 (11, 15), # 16 ] - data['num_vehicles'] = 4 - data['depot'] = 0 + data["num_vehicles"] = 4 + data["depot"] = 0 return data # [END data_model] @@ -75,21 +75,35 @@ def create_data_model(): def print_solution(routes, cumul_data): """Print the solution.""" total_time = 0 - route_str = '' + route_str = "" for i, route in enumerate(routes): - route_str += 'Route ' + str(i) + ':\n' + route_str += "Route " + str(i) + ":\n" start_time = cumul_data[i][0][0] end_time = cumul_data[i][0][1] - route_str += ' ' + str(route[0]) + \ - ' Time(' + str(start_time) + ', ' + str(end_time) + ')' + route_str += ( + " " + + str(route[0]) + + " Time(" + + str(start_time) + + ", " + + str(end_time) + + ")" + ) for j in range(1, len(route)): start_time = cumul_data[i][j][0] end_time = cumul_data[i][j][1] - route_str += ' -> ' + str(route[j]) + \ - ' Time(' + str(start_time) + ', ' + str(end_time) + ')' - route_str += f'\n Route time: {start_time}min\n\n' + route_str += ( + " -> " + + str(route[j]) + + " Time(" + + str(start_time) + + ", " + + str(end_time) + + ")" + ) + route_str += f"\n Route time: {start_time}min\n\n" total_time += cumul_data[i][len(route) - 1][0] - route_str += f'Total time: {total_time}min' + route_str += f"Total time: {total_time}min" print(route_str) # [END solution_printer] @@ -146,14 +160,14 @@ def main(): # Create the routing index manager. # [START index_manager] - manager = pywrapcp.RoutingIndexManager(len(data['time_matrix']), - data['num_vehicles'], data['depot']) + manager = pywrapcp.RoutingIndexManager( + len(data["time_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. @@ -163,7 +177,7 @@ def time_callback(from_index, to_index): # 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] + return data["time_matrix"][from_node][to_node] transit_callback_index = routing.RegisterTransitCallback(time_callback) # [END transit_callback] @@ -175,42 +189,45 @@ def time_callback(from_index, to_index): # Add Time Windows constraint. # [START time_windows_constraint] - time = 'Time' + time = "Time" routing.AddDimension( transit_callback_index, 30, # allow waiting time 30, # maximum time per vehicle False, # Don't force cumulative time to be 0 at start of routes. - time) + 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']): + 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']): + 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]) + time_dimension.CumulVar(index).SetRange( + data["time_windows"][0][0], data["time_windows"][0][1] + ) # [END time_windows_constraint] # Instantiate route start and end times to produce feasible times. # [START depot_start_end_times] - for i in range(data['num_vehicles']): - routing.AddVariableMinimizedByFinalizer( - time_dimension.CumulVar(routing.Start(i))) + for i in range(data["num_vehicles"]): routing.AddVariableMinimizedByFinalizer( - time_dimension.CumulVar(routing.End(i))) + time_dimension.CumulVar(routing.Start(i)) + ) + routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(routing.End(i))) # [END depot_start_end_times] # Setting first solution heuristic. # [START parameters] search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) # [END parameters] # Solve the problem. @@ -227,7 +244,7 @@ def time_callback(from_index, to_index): # [END print_solution] -if __name__ == '__main__': +if __name__ == "__main__": main() # [END program_part1] # [END program]