def print_solution( data: dict, routing: RoutingModel, manager: RoutingIndexManager, assignment: Assignment, ) -> None: """ Print the solution. """ capacity_dimension = routing.GetDimensionOrDie('Capacity') time_dimension = routing.GetDimensionOrDie('Time') total_time = 0 for vehicle_id in range(data['num_vehicles']): index = routing.Start(vehicle_id) node_props = [] while not routing.IsEnd(index): props = node_properties(manager, assignment, capacity_dimension, time_dimension, index) node_props.append(props) index = assignment.Value(routing.NextVar(index)) props = node_properties(manager, assignment, capacity_dimension, time_dimension, index) node_props.append(props) route_time = assignment.Value(time_dimension.CumulVar(index)) route = "\n -> ".join(['[Node %2s: Load(%s) Time(%2s, %s)]' % prop for prop in node_props]) plan_output = (f'Route for vehicle {vehicle_id}:\n {route}\n' f'Load of the route: {props[1]}\nTime of the route: {route_time} min\n') print(plan_output) total_time += route_time print(f'Total time of all routes: {total_time} min')
def draw_route_graph( data: dict, routing: RoutingModel, manager: RoutingIndexManager, assignment: Assignment, filename: str = 'route.png', prog='sfdp', ) -> None: """ Draw a route graph based on the solution of the problem. """ weights = data['weights'] demands = data['demands'] time_windows = data['time_windows'] graph = pgv.AGraph(directed=True) def _node(index: int) -> str: if index == 0: return f'{index}\nDepot' return f'{index}\nDemand: {demands[index]}\nRange: {time_windows[index]}' for vehicle_id in range(data['num_vehicles']): index = routing.Start(vehicle_id) while not routing.IsEnd(index): node_index = manager.IndexToNode(index) next_index = assignment.Value(routing.NextVar(index)) next_node_index = manager.IndexToNode(next_index) weight = weights[node_index][next_node_index] graph.add_edge(_node(node_index), _node(next_node_index), weight=weight, label=weight) index = next_index graph.draw(filename, prog=prog) print(f'The route graph has been saved to {filename}.')
def print_solution(data: VehicleRoutingProblemInstance, manager: RoutingIndexManager, routing: RoutingModel, solution: Assignment): """Prints assignment on console.""" time_dimension = routing.GetDimensionOrDie('Duration') total_time = 0 for vehicle_id in range(data.num_plans_to_create): start_time = None index = routing.Start(vehicle_id) plan_output = 'Route for vehicle {}:\n'.format(vehicle_id) while not routing.IsEnd(index): time_var = time_dimension.CumulVar(index) if start_time is None: start_time = solution.Min(time_var) plan_output += '{0} Time({1},{2}) -> '.format( manager.IndexToNode(index), solution.Min(time_var), solution.Max(time_var)) index = solution.Value(routing.NextVar(index)) time_var = time_dimension.CumulVar(index) plan_output += '{0} Time({1},{2})\n'.format( manager.IndexToNode(index), solution.Min(time_var), solution.Max(time_var)) plan_output += f'Start of the route: {start_time}\n' plan_output += 'Time of the route: {} sec\n'.format( solution.Min(time_var) - start_time) print(plan_output) total_time += solution.Min(time_var) - start_time print('Total time of all routes: {} sec'.format(total_time))
def from_cvrp_solution(cls, data_model: DataModel, manager: pywrapcp.RoutingIndexManager, routing: pywrapcp.RoutingModel, assignment) -> 'Optional[List[VehicleRoute]]': if not assignment: return None res = [] # type: List[VehicleRoute] for vehicle_id in range(data_model.vehicle_number): index = routing.Start(vehicle_id) route_indices = [] # type: List[int] route_distance = 0 # float route_load = 0 # float while not routing.IsEnd(index): node_index = manager.IndexToNode(index) route_indices.append(node_index) route_load += data_model.demands[node_index] previous_index = index index = assignment.Value(routing.NextVar(index)) route_distance += routing.GetArcCostForVehicle( previous_index, index, vehicle_id) route_indices.append(0) # returns to depot res.append( cls(data_model, vehicle_id, route_indices, route_distance, route_load)) current_app.logger.debug('CVRP Solution:\n{res}') return res
def print_solution( data: dict, routing: RoutingModel, manager: RoutingIndexManager, assignment: Assignment, ) -> None: capacity_dimension = routing.GetDimensionOrDie('Capacity') time_dimension = None total_cost = 0 if 'time_windows' in data.keys(): time_dimension = routing.GetDimensionOrDie('Time') total_time = 0 for vehicle_id in range(data['num_vehicles']): index = routing.Start(vehicle_id) node_props = [] while not routing.IsEnd(index): props = node_properties(data, manager, assignment, capacity_dimension, time_dimension, index) node_props.append(props) index = assignment.Value(routing.NextVar(index)) props = node_properties(data, manager, assignment, capacity_dimension, time_dimension, index) node_props.append(props) # arc weight cost = 0 node_indexes = [prop[0] for prop in node_props] for i in range(len(node_indexes)-1): idx_from = node_indexes[i] idx_to = node_indexes[i+1] cost += data['dist_mat'][idx_from][idx_to] total_cost += cost if 'time_windows' in data.keys(): route_time = assignment.Value(time_dimension.CumulVar(index)) route = "\n -> ".join(['[Node %2s(%s)TW(%2s, %2s): Vehicle Load(%2s) and Arrived(%2s)]' % prop for prop in node_props]) plan_output = (f'Route for vehicle {vehicle_id}:\n {route}\n' f'Cost: {cost}\nLoad: {props[-1]}\nTime: {route_time} min\n') print(plan_output) total_time += route_time else: route = "\n -> ".join(['[Node %2s(%s): Vehicle Load(%2s)]' % prop for prop in node_props]) plan_output = (f'Route for vehicle {vehicle_id}:\n {route}\n' f'Cost: {cost}\nLoad: {props[-1]}\n') print(plan_output) print(f'Total cost of all routes: {total_cost}\n') return total_cost if 'time_windows' in data.keys(): print('*** format ***: \n[Node node_index(demand)TW(Time Window min, max): Vehicle Load(accumulated load) and Arrived(time)]') print(f'Total time of all routes: {total_time} min')
def print_solution(data: dict, routing: pywrapcp.RoutingModel, assignment: pywrapcp.Assignment): """ Print routes on console. """ capacity_dimension = routing.GetDimensionOrDie('Capacity') time_dimension = routing.GetDimensionOrDie('Time') total_time = 0 d = {} r = [] for vehicle_id in range(data['num_vehicles']): index = routing.Start(vehicle_id) node_props = [] while not routing.IsEnd(index): props = node_properties(routing, assignment, capacity_dimension, time_dimension, index) node_props.append(props) index = assignment.Value(routing.NextVar(index)) props = node_properties(routing, assignment, capacity_dimension, time_dimension, index) node_props.append(props) route_time = assignment.Value(time_dimension.CumulVar(index)) route = "\n -> ".join(['[Node %2s: Load(%s) Time(%2s, %s)]' % prop \ for prop in node_props]) plan_output = f'Route for vehicle {vehicle_id}:\n {route}\n' + \ f'Load of the route: {props[1]}\nTime of the route: {route_time} min\n' # print(plan_output) #convert to dict ddd = [] for node in node_props: dd = {"node": node[0], "load": node[1], "time": [node[2], node[3]]} ddd.append(dd) r.append({ "vehicle_id": vehicle_id, "route": ddd, "total_time": route_time, "load": len(ddd) - 2 }) total_time += route_time d['solver'] = r d['total_time'] = total_time # print(f'Total time of all routes: {total_time} min') return d
def _extract_solution(self, assignment: Assignment, vrp_instance: VehicleRoutingProblemInstance, manager: RoutingIndexManager, routing: RoutingModel) \ -> VehicleRoutingProblemSolution: routes = [] etas = [] etds = [] time_dimension = routing.GetDimensionOrDie( self.DURATION_DIMENSION_NAME) for vehicle_id in range(vrp_instance.num_plans_to_create): index = routing.Start(vehicle_id) route = [] route_etas = [] route_etds = [] while not routing.IsEnd(index): node = manager.IndexToNode(index) if node in vrp_instance.pickup_nodes: this_event_time = vrp_instance.pickup_service_time elif node in vrp_instance.drop_nodes: this_event_time = vrp_instance.drop_service_time else: this_event_time = 0 time_var = time_dimension.CumulVar(index) eta = assignment.Min(time_var) etd = assignment.Max(time_var) + this_event_time route.append(node) route_etas.append(eta) route_etds.append(etd) index = assignment.Value(routing.NextVar(index)) routes.append(route) etas.append(route_etas) etds.append(route_etds) ret = VehicleRoutingProblemSolution(plans=routes, etas=etas, etds=etds) return ret
def _extract_solution(self, manager: RoutingIndexManager, routing: RoutingModel, assignment: Assignment, indices_to_visit: List[int]) -> Dict[str, Any]: """Transform results to a usable format Parameters ---------- manager : RoutingIndexManager OR-tools' object to manage conversion between NodeIndex and variable index routing : RoutingModel OR-tools' object for route solving assignment : Assignment OR-tools' object for mapping from variable to domains indices_to_visit : List[int] The list of indices corresponding to the desired facilities to visit Returns ------- Dict[str, Any] With keys: - 'objective', set to objective value (minified distance) - 'order', instructions for the order of facilities to visit """ sln = {"objective": assignment.ObjectiveValue()} stop_indices = [] index = routing.Start(0) while not routing.IsEnd(index): relative_index = manager.IndexToNode(index) stop_indices.append(indices_to_visit[relative_index]) previous_index = index index = assignment.Value(routing.NextVar(index)) relative_index = manager.IndexToNode(index) stop_indices.append(indices_to_visit[relative_index]) sln["order"] = stop_indices return sln