diff --git a/ortools/constraint_solver/docs/routing_svg.py b/ortools/constraint_solver/docs/routing_svg.py index f052240539..d918431d9a 100755 --- a/ortools/constraint_solver/docs/routing_svg.py +++ b/ortools/constraint_solver/docs/routing_svg.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. + """Generate SVG for a Routing problem.""" # [START import] @@ -49,72 +50,327 @@ class DataModel(object): # pylint: disable=too-many-instance-attributes self._locations = [(l[0] * 114, l[1] * 80) for l in locations] self._distance_matrix = [ [ - 0, 548, 776, 696, 582, 274, 502, 194, 308, 194, 536, 502, 388, - 354, 468, 776, 662 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 662, + 1210, + 754, + 1358, + 1244, + 708, + 480, + 856, + 514, + 468, + 354, + 844, + 730, + 536, + 194, + 798, + 0, ], ] self._time_matrix = [ @@ -155,7 +411,7 @@ class DataModel(object): # pylint: disable=too-many-instance-attributes (10, 15), # 15 (5, 15), # 16 ] - if args['drop_nodes']: + if args["drop_nodes"]: self._demands = [0, 1, 1, 3, 6, 3, 6, 8, 8, 1, 2, 1, 2, 6, 6, 8, 8] else: self._demands = [0, 1, 1, 2, 4, 2, 4, 8, 8, 1, 2, 1, 2, 4, 4, 8, 8] @@ -170,13 +426,13 @@ class DataModel(object): # pylint: disable=too-many-instance-attributes [16, 14], ] - if args['tsp']: + if args["tsp"]: self._num_vehicles = 1 else: self._num_vehicles = 4 self._vehicle_capacities = [15, 15, 15, 15] - if args['resources']: + if args["resources"]: self._vehicle_load_time = 5 self._vehicle_unload_time = 5 @@ -266,9 +522,14 @@ class GoogleColorPalette(object): def __init__(self): """Initialize Google ColorPalette.""" - self._colors = [('blue', r'#4285F4'), ('red', r'#EA4335'), - ('yellow', r'#FBBC05'), ('green', r'#34A853'), - ('black', r'#101010'), ('white', r'#FFFFFF')] + self._colors = [ + ("blue", r"#4285F4"), + ("red", r"#EA4335"), + ("yellow", r"#FBBC05"), + ("green", r"#34A853"), + ("black", r"#101010"), + ("white", r"#FFFFFF"), + ] def __getitem__(self, key): """Gets color name from idx.""" @@ -302,85 +563,101 @@ class SVG(object): @staticmethod def header(size, margin): """Writes header.""" - print(r''.format( - width=size[0] + 2 * margin, - height=size[1] + 2 * margin, - margin=margin)) + print( + r''.format( + width=size[0] + 2 * margin, height=size[1] + 2 * margin, margin=margin + ) + ) @staticmethod def definitions(colors): """Writes definitions.""" - print(r'') - print(r'') + print( + r"" + ) + print(r"") for color in colors: print( r' '.format(colorname=color[0])) + 'orient="auto">'.format(colorname=color[0]) + ) print( - r' ' - .format(color=color[1])) - print(r' ') - print(r'') + r' '.format( + color=color[1] + ) + ) + print(r" ") + print(r"") @staticmethod def footer(): """Writes svg footer.""" - print(r'') + print(r"") @staticmethod def draw_line(position_1, position_2, size, fg_color): """Draws a line.""" - line_style = ( - r'style="stroke-width:{sz};stroke:{fg};fill:none"').format( - sz=size, fg=fg_color) - print(r''.format( - x1=position_1[0], - y1=position_1[1], - x2=position_2[0], - y2=position_2[1], - style=line_style)) + line_style = (r'style="stroke-width:{sz};stroke:{fg};fill:none"').format( + sz=size, fg=fg_color + ) + print( + r''.format( + x1=position_1[0], + y1=position_1[1], + x2=position_2[0], + y2=position_2[1], + style=line_style, + ) + ) @staticmethod def draw_polyline(position_1, position_2, size, fg_color, colorname): """Draws a line with arrow maker in the middle.""" - polyline_style = (r'style="stroke-width:{sz};stroke:{fg};fill:none;' - 'marker-mid:url(#arrow_{colorname})"').format( - sz=size, fg=fg_color, colorname=colorname) - print(r''. - format(x1=position_1[0], - y1=position_1[1], - x2=(position_1[0] + position_2[0]) / 2, - y2=(position_1[1] + position_2[1]) / 2, - x3=position_2[0], - y3=position_2[1], - style=polyline_style)) + polyline_style = ( + r'style="stroke-width:{sz};stroke:{fg};fill:none;' + 'marker-mid:url(#arrow_{colorname})"' + ).format(sz=size, fg=fg_color, colorname=colorname) + print( + r''.format( + x1=position_1[0], + y1=position_1[1], + x2=(position_1[0] + position_2[0]) / 2, + y2=(position_1[1] + position_2[1]) / 2, + x3=position_2[0], + y3=position_2[1], + style=polyline_style, + ) + ) @staticmethod - def draw_circle(position, radius, size, fg_color, bg_color='white'): + def draw_circle(position, radius, size, fg_color, bg_color="white"): """Print a circle.""" - circle_style = ( - r'style="stroke-width:{sz};stroke:{fg};fill:{bg}"').format( - sz=size, fg=fg_color, bg=bg_color) - print(r''.format( - cx=position[0], cy=position[1], r=radius, style=circle_style)) + circle_style = (r'style="stroke-width:{sz};stroke:{fg};fill:{bg}"').format( + sz=size, fg=fg_color, bg=bg_color + ) + print( + r''.format( + cx=position[0], cy=position[1], r=radius, style=circle_style + ) + ) @staticmethod - def draw_text(text, position, size, fg_color='none', bg_color='black'): + def draw_text(text, position, size, fg_color="none", bg_color="black"): """Print a middle centred text.""" - text_style = (r'style="text-anchor:middle;font-weight:bold;' - 'font-size:{sz};stroke:{fg};fill:{bg}"').format( - sz=size, fg=fg_color, bg=bg_color) - print(r'{txt}'.format( - x=position[0], - y=position[1], - dy=size / 3, - style=text_style, - txt=text)) + text_style = ( + r'style="text-anchor:middle;font-weight:bold;' + 'font-size:{sz};stroke:{fg};fill:{bg}"' + ).format(sz=size, fg=fg_color, bg=bg_color) + print( + r'{txt}'.format( + x=position[0], y=position[1], dy=size / 3, style=text_style, txt=text + ) + ) class SVGPrinter(object): # pylint: disable=too-many-instance-attributes @@ -433,8 +710,8 @@ class SVGPrinter(object): # pylint: disable=too-many-instance-attributes def draw_grid(self): """Draws the city grid.""" - print(r'') - color = '#969696' + print(r"") + color = "#969696" # Horizontal streets for i in range(9): p_1 = [0, i * 80] @@ -448,101 +725,106 @@ class SVGPrinter(object): # pylint: disable=too-many-instance-attributes def draw_depot(self): """Draws the depot.""" - print(r'') - color = self._color_palette.value_from_name('black') + print(r"") + color = self._color_palette.value_from_name("black") loc = self._data.locations[self._data.depot] - self._svg.draw_circle(loc, self._radius, self._stroke_width, color, - 'white') - self._svg.draw_text(self._data.depot, loc, self._radius, 'none', color) + self._svg.draw_circle(loc, self._radius, self._stroke_width, color, "white") + self._svg.draw_text(self._data.depot, loc, self._radius, "none", color) def draw_depots(self): """Draws the depot.""" - print(r'') + print(r"") # print starts for vehicle_idx, start in enumerate(self._data.starts): del vehicle_idx - color = self._color_palette.value_from_name('black') + color = self._color_palette.value_from_name("black") # color = self._color_palette.value(vehicle_idx) loc = self._data.locations[start] - self._svg.draw_circle(loc, self._radius, self._stroke_width, color, - 'white') - self._svg.draw_text(start, loc, self._radius, 'none', color) + self._svg.draw_circle(loc, self._radius, self._stroke_width, color, "white") + self._svg.draw_text(start, loc, self._radius, "none", color) # print end - color = self._color_palette.value_from_name('black') + color = self._color_palette.value_from_name("black") loc = self._data.locations[0] - self._svg.draw_circle(loc, self._radius, self._stroke_width, color, - 'white') - self._svg.draw_text(0, loc, self._radius, 'none', color) + self._svg.draw_circle(loc, self._radius, self._stroke_width, color, "white") + self._svg.draw_text(0, loc, self._radius, "none", color) def draw_locations(self): """Draws all the locations but the depot.""" - print(r'') - color = self._color_palette.value_from_name('blue') - if not self._args['starts_ends']: + print(r"") + color = self._color_palette.value_from_name("blue") + if not self._args["starts_ends"]: for idx, loc in enumerate(self._data.locations): if idx == self._data.depot: continue - self._svg.draw_circle(loc, self._radius, self._stroke_width, - color, 'white') - self._svg.draw_text(idx, loc, self._radius, 'none', color) + self._svg.draw_circle( + loc, self._radius, self._stroke_width, color, "white" + ) + self._svg.draw_text(idx, loc, self._radius, "none", color) else: for idx, loc in enumerate(self._data.locations): if idx in self._data.starts + self._data.ends: continue - self._svg.draw_circle(loc, self._radius, self._stroke_width, - color, 'white') - self._svg.draw_text(idx, loc, self._radius, 'none', color) + self._svg.draw_circle( + loc, self._radius, self._stroke_width, color, "white" + ) + self._svg.draw_text(idx, loc, self._radius, "none", color) def draw_demands(self): """Draws all the demands.""" - print(r'') + print(r"") for idx, loc in enumerate(self._data.locations): if idx == self._data.depot: continue demand = self._data.demands[idx] position = [ - x + y - for x, y in zip(loc, [self._radius * 1.2, self._radius * 1.1]) + x + y for x, y in zip(loc, [self._radius * 1.2, self._radius * 1.1]) ] - color = self._color_palette.value_from_name('red') + color = self._color_palette.value_from_name("red") # color = self._color_palette.value(int(math.log(demand, 2))) - self._svg.draw_text(demand, position, self._radius, 'none', color) + self._svg.draw_text(demand, position, self._radius, "none", color) def draw_pickups_deliveries(self): """Draws all pickups deliveries.""" - print(r'') - colorname = 'red' + print(r"") + colorname = "red" color = self._color_palette.value_from_name(colorname) for pickup_delivery in self._data.pickups_deliveries: - self._svg.draw_polyline(self._data.locations[pickup_delivery[0]], - self._data.locations[pickup_delivery[1]], - self._stroke_width, color, colorname) + self._svg.draw_polyline( + self._data.locations[pickup_delivery[0]], + self._data.locations[pickup_delivery[1]], + self._stroke_width, + color, + colorname, + ) def draw_time_windows(self): """Draws all the time windows.""" - print(r'') + print(r"") for idx, loc in enumerate(self._data.locations): if idx == self._data.depot: continue time_window = self._data.time_windows[idx] position = [ - x + y - for x, y in zip(loc, [self._radius * 0, -self._radius * 1.6]) + x + y for x, y in zip(loc, [self._radius * 0, -self._radius * 1.6]) ] - color = self._color_palette.value_from_name('red') + color = self._color_palette.value_from_name("red") self._svg.draw_text( - '[{t1},{t2}]'.format(t1=time_window[0], t2=time_window[1]), - position, self._radius * 0.75, 'white', color) + "[{t1},{t2}]".format(t1=time_window[0], t2=time_window[1]), + position, + self._radius * 0.75, + "white", + color, + ) -############## -## ROUTES ## -############## + ############## + ## ROUTES ## + ############## def draw_drop_nodes(self): """Draws the dropped nodes.""" - print(r'') + print(r"") if self._assignment is None: - print('') + print("") # Display dropped nodes. dropped_nodes = [] for node in range(self._routing.Size()): @@ -550,17 +832,16 @@ class SVGPrinter(object): # pylint: disable=too-many-instance-attributes continue if self._assignment.Value(self._routing.NextVar(node)) == node: dropped_nodes.append(self._manager.IndexToNode(node)) - color = self._color_palette.value_from_name('black') + color = self._color_palette.value_from_name("black") for node_idx in dropped_nodes: loc = self._data.locations[node_idx] - self._svg.draw_circle(loc, self._radius, self._stroke_width, color, - 'white') - self._svg.draw_text(node_idx, loc, self._radius, 'none', color) + self._svg.draw_circle(loc, self._radius, self._stroke_width, color, "white") + self._svg.draw_text(node_idx, loc, self._radius, "none", color) def routes(self): """Creates the route list from the assignment.""" if self._assignment is None: - print('') + print("") return [] routes = [] for vehicle_id in range(self._data.num_vehicles): @@ -581,23 +862,28 @@ class SVGPrinter(object): # pylint: disable=too-many-instance-attributes previous_loc_idx = None for loc_idx in route: if previous_loc_idx is not None and previous_loc_idx != loc_idx: - self._svg.draw_polyline(self._data.locations[previous_loc_idx], - self._data.locations[loc_idx], - self._stroke_width, color, colorname) + self._svg.draw_polyline( + self._data.locations[previous_loc_idx], + self._data.locations[loc_idx], + self._stroke_width, + color, + colorname, + ) previous_loc_idx = loc_idx # Then print location along the route for loc_idx in route: if loc_idx != self._data.depot: loc = self._data.locations[loc_idx] - self._svg.draw_circle(loc, self._radius, self._stroke_width, - color, 'white') - self._svg.draw_text(loc_idx, loc, self._radius, 'none', color) + self._svg.draw_circle( + loc, self._radius, self._stroke_width, color, "white" + ) + self._svg.draw_text(loc_idx, loc, self._radius, "none", color) def draw_routes(self): """Draws the routes.""" - print(r'') + print(r"") for route_idx, route in enumerate(self.routes()): - print(r''.format(idx=route_idx)) + print(r"".format(idx=route_idx)) color = self._color_palette.value(route_idx) colorname = self._color_palette.name(route_idx) self.draw_route(route, color, colorname) @@ -605,9 +891,9 @@ class SVGPrinter(object): # pylint: disable=too-many-instance-attributes def tw_routes(self): """Creates the route time window list from the assignment.""" if self._assignment is None: - print('') + print("") return [] - time_dimension = self._routing.GetDimensionOrDie('Time') + time_dimension = self._routing.GetDimensionOrDie("Time") loc_routes = [] tw_routes = [] for vehicle_id in range(self._data.num_vehicles): @@ -636,25 +922,29 @@ class SVGPrinter(object): # pylint: disable=too-many-instance-attributes loc = self._data.locations[loc_idx] if loc_idx == 0: # special case for depot position = [ - x + y for x, y in zip(loc, [ - self._radius * is_start, self._radius * - (1.8 + route_idx) - ]) + x + y + for x, y in zip( + loc, [self._radius * is_start, self._radius * (1.8 + route_idx)] + ) ] is_start = 1 else: position = [ - x + y - for x, y in zip(loc, [self._radius * 0, self._radius * 1.8]) + x + y for x, y in zip(loc, [self._radius * 0, self._radius * 1.8]) ] - self._svg.draw_text('[{t_min}]'.format(t_min=time_window[0]), - position, self._radius * 0.75, 'white', color) + self._svg.draw_text( + "[{t_min}]".format(t_min=time_window[0]), + position, + self._radius * 0.75, + "white", + color, + ) def draw_tw_routes(self): """Draws the time window routes.""" - print(r'') + print(r"") for route_idx, loc_tw in enumerate(self.tw_routes()): - print(r''.format(route_idx)) + print(r"".format(route_idx)) color = self._color_palette.value(route_idx) self.draw_tw_route(route_idx, loc_tw[0], loc_tw[1], color) @@ -665,25 +955,26 @@ class SVGPrinter(object): # pylint: disable=too-many-instance-attributes self._svg.header(size, margin) self._svg.definitions(self._color_palette.colors) self.draw_grid() - if not self._args['solution']: - if self._args['pickup_delivery']: + if not self._args["solution"]: + if self._args["pickup_delivery"]: self.draw_pickups_deliveries() self.draw_locations() else: self.draw_routes() self.draw_drop_nodes() - if self._args['starts_ends']: + if self._args["starts_ends"]: self.draw_depots() else: self.draw_depot() - if self._args['capacity']: + if self._args["capacity"]: self.draw_demands() - if self._args['drop_nodes']: + if self._args["drop_nodes"]: self.draw_demands() - if self._args['time_windows'] or self._args['resources']: + if self._args["time_windows"] or self._args["resources"]: self.draw_time_windows() - if ((self._args['time_windows'] or self._args['resources']) and - self._args['solution']): + if (self._args["time_windows"] or self._args["resources"]) and self._args[ + "solution" + ]: self.draw_tw_routes() self._svg.footer() @@ -693,55 +984,43 @@ class SVGPrinter(object): # pylint: disable=too-many-instance-attributes ######## def main(): # pylint: disable=too-many-locals,too-many-branches """Entry point of the program.""" - parser = argparse.ArgumentParser(description='Output VRP as svg image.') - parser.add_argument('-tsp', - '--tsp', - action='store_true', - help='use 1 vehicle') - parser.add_argument('-vrp', - '--vrp', - action='store_true', - help='use 4 vehicle') - parser.add_argument('-gs', - '--global-span', - action='store_true', - help='use global span constraints') - parser.add_argument('-c', - '--capacity', - action='store_true', - help='use capacity constraints') - parser.add_argument('-r', - '--resources', - action='store_true', - help='use resources constraints') - parser.add_argument('-dn', - '--drop-nodes', - action='store_true', - help='allow drop nodes (disjuntion constraints)') - parser.add_argument('-tw', - '--time-windows', - action='store_true', - help='use time-window constraints') - parser.add_argument('-se', - '--starts-ends', - action='store_true', - help='use multiple starts & ends') - parser.add_argument('-pd', - '--pickup-delivery', - action='store_true', - help='use pickup & delivery constraints') - parser.add_argument('-fifo', - '--fifo', - action='store_true', - help='use pickup & delivery FIFO Policy') - parser.add_argument('-lifo', - '--lifo', - action='store_true', - help='use pickup & delivery LIFO Policy') - parser.add_argument('-s', - '--solution', - action='store_true', - help='print solution') + parser = argparse.ArgumentParser(description="Output VRP as svg image.") + parser.add_argument("-tsp", "--tsp", action="store_true", help="use 1 vehicle") + parser.add_argument("-vrp", "--vrp", action="store_true", help="use 4 vehicle") + parser.add_argument( + "-gs", "--global-span", action="store_true", help="use global span constraints" + ) + parser.add_argument( + "-c", "--capacity", action="store_true", help="use capacity constraints" + ) + parser.add_argument( + "-r", "--resources", action="store_true", help="use resources constraints" + ) + parser.add_argument( + "-dn", + "--drop-nodes", + action="store_true", + help="allow drop nodes (disjuntion constraints)", + ) + parser.add_argument( + "-tw", "--time-windows", action="store_true", help="use time-window constraints" + ) + parser.add_argument( + "-se", "--starts-ends", action="store_true", help="use multiple starts & ends" + ) + parser.add_argument( + "-pd", + "--pickup-delivery", + action="store_true", + help="use pickup & delivery constraints", + ) + parser.add_argument( + "-fifo", "--fifo", action="store_true", help="use pickup & delivery FIFO Policy" + ) + parser.add_argument( + "-lifo", "--lifo", action="store_true", help="use pickup & delivery LIFO Policy" + ) + parser.add_argument("-s", "--solution", action="store_true", help="print solution") args = vars(parser.parse_args()) # Instantiate the data problem. @@ -749,7 +1028,7 @@ def main(): # pylint: disable=too-many-locals,too-many-branches data = DataModel(args) # [END data] - if not args['solution']: + if not args["solution"]: # Print svg on cout printer = SVGPrinter(args, data) printer.print_to_console() @@ -757,13 +1036,14 @@ def main(): # pylint: disable=too-many-locals,too-many-branches # Create the routing index manager. # [START index_manager] - if args['starts_ends']: - manager = pywrapcp.RoutingIndexManager(len(data.locations), - data.num_vehicles, data.starts, - data.ends) + if args["starts_ends"]: + manager = pywrapcp.RoutingIndexManager( + len(data.locations), data.num_vehicles, data.starts, data.ends + ) else: - 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. @@ -799,36 +1079,33 @@ def main(): # pylint: disable=too-many-locals,too-many-branches from_node = manager.IndexToNode(from_index) return data.demands[from_node] - demand_callback_index = routing.RegisterUnaryTransitCallback( - demand_callback) + demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback) - if args['time_windows'] or args['resources']: + if args["time_windows"] or args["resources"]: routing.SetArcCostEvaluatorOfAllVehicles(time_callback_index) else: routing.SetArcCostEvaluatorOfAllVehicles(distance_callback_index) - if args['global_span'] or args['pickup_delivery']: - dimension_name = 'Distance' - routing.AddDimension(distance_callback_index, 0, 3000, True, - dimension_name) + if args["global_span"] or args["pickup_delivery"]: + dimension_name = "Distance" + routing.AddDimension(distance_callback_index, 0, 3000, True, dimension_name) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) - if args['capacity'] or args['drop_nodes']: - routing.AddDimensionWithVehicleCapacity(demand_callback_index, 0, - data.vehicle_capacities, True, - 'Capacity') + if args["capacity"] or args["drop_nodes"]: + routing.AddDimensionWithVehicleCapacity( + demand_callback_index, 0, data.vehicle_capacities, True, "Capacity" + ) - if args['drop_nodes']: + if args["drop_nodes"]: # Allow to drop nodes. penalty = 1000 for node in range(1, len(data.locations)): routing.AddDisjunction([manager.NodeToIndex(node)], penalty) - if args['pickup_delivery']: - dimension_name = 'Distance' - routing.AddDimension(distance_callback_index, 0, 3000, True, - dimension_name) + if args["pickup_delivery"]: + dimension_name = "Distance" + routing.AddDimension(distance_callback_index, 0, 3000, True, dimension_name) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) for request in data.pickups_deliveries: @@ -836,27 +1113,29 @@ def main(): # pylint: disable=too-many-locals,too-many-branches 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)) - if args['fifo']: + distance_dimension.CumulVar(pickup_index) + <= distance_dimension.CumulVar(delivery_index) + ) + if args["fifo"]: routing.SetPickupAndDeliveryPolicyOfAllVehicles( - pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_FIFO) - if args['lifo']: + pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_FIFO + ) + if args["lifo"]: routing.SetPickupAndDeliveryPolicyOfAllVehicles( - pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_LIFO) + pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_LIFO + ) - if args['starts_ends']: - dimension_name = 'Distance' - routing.AddDimension(distance_callback_index, 0, 2000, True, - dimension_name) + if args["starts_ends"]: + dimension_name = "Distance" + routing.AddDimension(distance_callback_index, 0, 2000, True, dimension_name) distance_dimension = routing.GetDimensionOrDie(dimension_name) distance_dimension.SetGlobalSpanCostCoefficient(100) - time = 'Time' - if args['time_windows'] or args['resources']: + time = "Time" + if args["time_windows"] or args["resources"]: routing.AddDimension(time_callback_index, 30, 30, False, time) time_dimension = routing.GetDimensionOrDie(time) # Add time window constraints for each location except depot and 'copy' the @@ -865,26 +1144,26 @@ def main(): # pylint: disable=too-many-locals,too-many-branches if location_idx == 0: continue index = manager.NodeToIndex(location_idx) - time_dimension.CumulVar(index).SetRange(time_window[0], - time_window[1]) + 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): index = routing.Start(vehicle_id) time_window = data.time_windows[0] - time_dimension.CumulVar(index).SetRange(time_window[0], - time_window[1]) + time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1]) routing.AddToAssignment(time_dimension.SlackVar(index)) # Instantiate route start and end times to produce feasible times. for vehicle_id in range(data.num_vehicles): routing.AddVariableMinimizedByFinalizer( - time_dimension.CumulVar(routing.End(vehicle_id))) + time_dimension.CumulVar(routing.End(vehicle_id)) + ) routing.AddVariableMinimizedByFinalizer( - time_dimension.CumulVar(routing.Start(vehicle_id))) + time_dimension.CumulVar(routing.Start(vehicle_id)) + ) - if args['resources']: + if args["resources"]: # Add resource constraints at the depot. time_dimension = routing.GetDimensionOrDie(time) solver = routing.solver() @@ -894,30 +1173,39 @@ def main(): # pylint: disable=too-many-locals,too-many-branches intervals.append( solver.FixedDurationIntervalVar( time_dimension.CumulVar(routing.Start(i)), - data.vehicle_load_time, 'depot_interval')) + data.vehicle_load_time, + "depot_interval", + ) + ) # Add unloading time 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 ", + ) + ) depot_usage = [1 for i in range(data.num_vehicles * 2)] solver.AddConstraint( - solver.Cumulative(intervals, depot_usage, data.depot_capacity, - 'depot')) + solver.Cumulative(intervals, depot_usage, data.depot_capacity, "depot") + ) # Setting first solution heuristic (cheapest addition). search_parameters = pywrapcp.DefaultRoutingSearchParameters() # pylint: disable=no-member - if not args['pickup_delivery']: + if not args["pickup_delivery"]: search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) else: search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION) + routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION + ) search_parameters.local_search_metaheuristic = ( - routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) + routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH + ) search_parameters.time_limit.FromSeconds(2) # Solve the problem. @@ -928,5 +1216,5 @@ def main(): # pylint: disable=too-many-locals,too-many-branches return 0 -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/ortools/constraint_solver/python/pywrapcp_test.py b/ortools/constraint_solver/python/pywrapcp_test.py index 2f6d1506d6..f2fd44ed4d 100755 --- a/ortools/constraint_solver/python/pywrapcp_test.py +++ b/ortools/constraint_solver/python/pywrapcp_test.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. + """Unit tests for python/constraint_solver.i. Not exhaustive.""" import sys @@ -20,7 +21,6 @@ from ortools.constraint_solver import pywrapcp class SearchMonitorTest(pywrapcp.SearchMonitor): - def __init__(self, solver, nexts): pywrapcp.SearchMonitor.__init__(self, solver) self._nexts = nexts @@ -33,38 +33,35 @@ class SearchMonitorTest(pywrapcp.SearchMonitor): class DemonTest(pywrapcp.PyDemon): - def __init__(self, x): pywrapcp.PyDemon.__init__(self) self._x = x - print('Demon built') + print("Demon built") def Run(self, solver): - print('in Run(), saw ' + str(self._x)) + print("in Run(), saw " + str(self._x)) class ConstraintTest(pywrapcp.PyConstraint): - def __init__(self, solver, x): pywrapcp.Constraint.__init__(self, solver) self._x = x - print('Constraint built') + print("Constraint built") def Post(self): - print('in Post()') + print("in Post()") self._demon = DemonTest(self._x) self._x.WhenBound(self._demon) - print('out of Post()') + print("out of Post()") def InitialPropagate(self): - print('in InitialPropagate()') + print("in InitialPropagate()") self._x.SetMin(5) print(self._x) - print('out of InitialPropagate()') + print("out of InitialPropagate()") class InitialPropagateDemon(pywrapcp.PyDemon): - def __init__(self, ct): pywrapcp.Demon.__init__(self) self._ct = ct @@ -74,7 +71,6 @@ class InitialPropagateDemon(pywrapcp.PyDemon): class DumbGreaterOrEqualToFive(pywrapcp.PyConstraint): - def __init__(self, solver, x): pywrapcp.Constraint.__init__(self, solver) self._x = x @@ -86,25 +82,23 @@ class DumbGreaterOrEqualToFive(pywrapcp.PyConstraint): def InitialPropagate(self): if self._x.Bound(): if self._x.Value() < 5: - print('Reject %d' % self._x.Value()) + print("Reject %d" % self._x.Value()) self.solver().Fail() else: - print('Accept %d' % self._x.Value()) + print("Accept %d" % self._x.Value()) class WatchDomain(pywrapcp.PyDemon): - def __init__(self, x): pywrapcp.Demon.__init__(self) self._x = x def Run(self, solver): for i in self._x.HoleIterator(): - print('Removed %d' % i) + print("Removed %d" % i) class HoleConstraintTest(pywrapcp.PyConstraint): - def __init__(self, solver, x): pywrapcp.Constraint.__init__(self, solver) self._x = x @@ -118,7 +112,6 @@ class HoleConstraintTest(pywrapcp.PyConstraint): class BinarySum(pywrapcp.PyConstraint): - def __init__(self, solver, x, y, z): pywrapcp.Constraint.__init__(self, solver) self._x = x @@ -132,39 +125,35 @@ class BinarySum(pywrapcp.PyConstraint): self._z.WhenRange(self._demon) def InitialPropagate(self): - self._z.SetRange(self._x.Min() + self._y.Min(), - self._x.Max() + self._y.Max()) - self._x.SetRange(self._z.Min() - self._y.Max(), - self._z.Max() - self._y.Min()) - self._y.SetRange(self._z.Min() - self._x.Max(), - self._z.Max() - self._x.Min()) + self._z.SetRange(self._x.Min() + self._y.Min(), self._x.Max() + self._y.Max()) + self._x.SetRange(self._z.Min() - self._y.Max(), self._z.Max() - self._y.Min()) + self._y.SetRange(self._z.Min() - self._x.Max(), self._z.Max() - self._x.Min()) class PyWrapCp(unittest.TestCase): - def test_member(self): - print('test_member') - solver = pywrapcp.Solver('test member') - x = solver.IntVar(1, 10, 'x') + print("test_member") + solver = pywrapcp.Solver("test member") + x = solver.IntVar(1, 10, "x") ct = x.Member([1, 2, 3, 5]) print(ct) def test_sparse_var(self): - print('test_sparse_var') - solver = pywrapcp.Solver('test_sparse_var') - x = solver.IntVar([1, 3, 5], 'x') + print("test_sparse_var") + solver = pywrapcp.Solver("test_sparse_var") + x = solver.IntVar([1, 3, 5], "x") print(x) def test_modulo(self): - print('test_modulo') - solver = pywrapcp.Solver('test_modulo') - x = solver.IntVar(0, 10, 'x') - y = solver.IntVar(2, 4, 'y') + print("test_modulo") + solver = pywrapcp.Solver("test_modulo") + x = solver.IntVar(0, 10, "x") + y = solver.IntVar(2, 4, "y") print(x % 3) print(x % y) def test_limit(self): - solver = pywrapcp.Solver('test_limit') + solver = pywrapcp.Solver("test_limit") # TODO(user): expose the proto-based MakeLimit() API in or-tools and test it # here. time = 10000 # ms @@ -173,80 +162,78 @@ class PyWrapCp(unittest.TestCase): solutions = sys.maxsize smart_time_check = True cumulative = False - limit = solver.Limit(time, branches, failures, solutions, - smart_time_check, cumulative) + limit = solver.Limit( + time, branches, failures, solutions, smart_time_check, cumulative + ) print(limit) def test_search_monitor(self): - print('test_search_monitor') - solver = pywrapcp.Solver('test search_monitor') - x = solver.IntVar(1, 10, 'x') - ct = (x == 3) + print("test_search_monitor") + solver = pywrapcp.Solver("test search_monitor") + x = solver.IntVar(1, 10, "x") + ct = x == 3 solver.Add(ct) - db = solver.Phase([x], solver.CHOOSE_FIRST_UNBOUND, - solver.ASSIGN_MIN_VALUE) + db = solver.Phase([x], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) monitor = SearchMonitorTest(solver, x) solver.Solve(db, monitor) def test_demon(self): - print('test_demon') - solver = pywrapcp.Solver('test_demon') - x = solver.IntVar(1, 10, 'x') + print("test_demon") + solver = pywrapcp.Solver("test_demon") + x = solver.IntVar(1, 10, "x") demon = DemonTest(x) demon.Run(solver) def test_constraint(self): - print('test_constraint') - solver = pywrapcp.Solver('test_constraint') - x = solver.IntVar(1, 10, 'x') + print("test_constraint") + solver = pywrapcp.Solver("test_constraint") + x = solver.IntVar(1, 10, "x") myct = ConstraintTest(solver, x) solver.Add(myct) - db = solver.Phase([x], solver.CHOOSE_FIRST_UNBOUND, - solver.ASSIGN_MIN_VALUE) + db = solver.Phase([x], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) solver.Solve(db) def test_failing_constraint(self): - print('test_failing_constraint') - solver = pywrapcp.Solver('test failing constraint') - x = solver.IntVar(1, 10, 'x') + print("test_failing_constraint") + solver = pywrapcp.Solver("test failing constraint") + x = solver.IntVar(1, 10, "x") myct = DumbGreaterOrEqualToFive(solver, x) solver.Add(myct) - db = solver.Phase([x], solver.CHOOSE_FIRST_UNBOUND, - solver.ASSIGN_MIN_VALUE) + db = solver.Phase([x], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) solver.Solve(db) def test_domain_iterator(self): - print('test_domain_iterator') - solver = pywrapcp.Solver('test_domain_iterator') - x = solver.IntVar([1, 2, 4, 6], 'x') + print("test_domain_iterator") + solver = pywrapcp.Solver("test_domain_iterator") + x = solver.IntVar([1, 2, 4, 6], "x") for i in x.DomainIterator(): print(i) def test_hole_iterator(self): - print('test_hole_iterator') - solver = pywrapcp.Solver('test_hole_iterator') - x = solver.IntVar(1, 10, 'x') + print("test_hole_iterator") + solver = pywrapcp.Solver("test_hole_iterator") + x = solver.IntVar(1, 10, "x") myct = HoleConstraintTest(solver, x) solver.Add(myct) - db = solver.Phase([x], solver.CHOOSE_FIRST_UNBOUND, - solver.ASSIGN_MIN_VALUE) + db = solver.Phase([x], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE) solver.Solve(db) def test_sum_constraint(self): - print('test_sum_constraint') - solver = pywrapcp.Solver('test_sum_constraint') - x = solver.IntVar(1, 5, 'x') - y = solver.IntVar(1, 5, 'y') - z = solver.IntVar(1, 5, 'z') + print("test_sum_constraint") + solver = pywrapcp.Solver("test_sum_constraint") + x = solver.IntVar(1, 5, "x") + y = solver.IntVar(1, 5, "y") + z = solver.IntVar(1, 5, "z") binary_sum = BinarySum(solver, x, y, z) solver.Add(binary_sum) - db = solver.Phase([x, y, z], solver.CHOOSE_FIRST_UNBOUND, - solver.ASSIGN_MIN_VALUE) + db = solver.Phase( + [x, y, z], solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_MIN_VALUE + ) solver.NewSearch(db) while solver.NextSolution(): - print('%d + %d == %d' % (x.Value(), y.Value(), z.Value())) + print("%d + %d == %d" % (x.Value(), y.Value(), z.Value())) solver.EndSearch() -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/ortools/constraint_solver/python/pywraprouting_test.py b/ortools/constraint_solver/python/pywraprouting_test.py index 2d29fc24e8..ef1c464876 100755 --- a/ortools/constraint_solver/python/pywraprouting_test.py +++ b/ortools/constraint_solver/python/pywraprouting_test.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. + """Test routing API.""" from functools import partial @@ -46,7 +47,6 @@ def Three(unused_i, unused_j): class Callback(object): - def __init__(self, model): self.model = model self.costs = [] @@ -56,12 +56,11 @@ class Callback(object): class TestRoutingIndexManager(unittest.TestCase): - def testCtor(self): manager = pywrapcp.RoutingIndexManager(42, 3, 7) self.assertIsNotNone(manager) if __debug__: - print(f'class RoutingIndexManager: {dir(manager)}') + print(f"class RoutingIndexManager: {dir(manager)}") self.assertEqual(42, manager.GetNumberOfNodes()) self.assertEqual(3, manager.GetNumberOfVehicles()) self.assertEqual(42 + 3 * 2 - 1, manager.GetNumberOfIndices()) @@ -86,13 +85,11 @@ class TestRoutingIndexManager(unittest.TestCase): self.assertEqual(3, manager.GetNumberOfVehicles()) self.assertEqual(42, manager.GetNumberOfIndices()) for i in range(manager.GetNumberOfVehicles()): - self.assertEqual(i + 1, - manager.IndexToNode(manager.GetStartIndex(i))) + self.assertEqual(i + 1, manager.IndexToNode(manager.GetStartIndex(i))) self.assertEqual(i + 4, manager.IndexToNode(manager.GetEndIndex(i))) class TestRoutingModel(unittest.TestCase): - def testCtor(self): manager = pywrapcp.RoutingIndexManager(42, 3, 7) self.assertIsNotNone(manager) @@ -102,7 +99,7 @@ class TestRoutingModel(unittest.TestCase): self.assertEqual(7, manager.IndexToNode(model.Start(i))) self.assertEqual(7, manager.IndexToNode(model.End(i))) if __debug__: - print(f'class RoutingModel: {dir(model)}') + print(f"class RoutingModel: {dir(model)}") def testSolve(self): manager = pywrapcp.RoutingIndexManager(42, 3, 7) @@ -131,12 +128,10 @@ class TestRoutingModel(unittest.TestCase): self.assertIsNotNone(manager) model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) self.assertEqual(1, transit_idx) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) - self.assertEqual(pywrapcp.RoutingModel.ROUTING_NOT_SOLVED, - model.status()) + self.assertEqual(pywrapcp.RoutingModel.ROUTING_NOT_SOLVED, model.status()) assignment = model.Solve() self.assertTrue(assignment) self.assertEqual(pywrapcp.RoutingModel.ROUTING_SUCCESS, model.status()) @@ -147,8 +142,7 @@ class TestRoutingModel(unittest.TestCase): self.assertIsNotNone(manager) model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) - transit_id = model.RegisterTransitCallback( - lambda from_index, to_index: 1) + transit_id = model.RegisterTransitCallback(lambda from_index, to_index: 1) self.assertEqual(1, transit_id) model.SetArcCostEvaluatorOfAllVehicles(transit_id) self.assertEqual(model.ROUTING_NOT_SOLVED, model.status()) @@ -178,7 +172,8 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) transit_idx = model.RegisterUnaryTransitCallback( - partial(UnaryTransitDistance, manager)) + partial(UnaryTransitDistance, manager) + ) self.assertEqual(1, transit_idx) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) self.assertEqual(model.ROUTING_NOT_SOLVED, model.status()) @@ -222,14 +217,14 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) self.assertEqual(model.ROUTING_NOT_SOLVED, model.status()) # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) assignment = model.SolveWithParameters(search_parameters) self.assertEqual(model.ROUTING_SUCCESS, model.status()) self.assertEqual(90, assignment.ObjectiveValue()) @@ -248,13 +243,13 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) assignment = model.SolveWithParameters(search_parameters) self.assertEqual(89, assignment.ObjectiveValue()) # Inspect solution @@ -265,8 +260,7 @@ class TestRoutingModel(unittest.TestCase): index = assignment.Value(model.NextVar(index)) visited_nodes.append(manager.IndexToNode(index)) self.assertEqual(expected_visited_nodes, visited_nodes) - self.assertTrue( - model.IsEnd(assignment.Value(model.NextVar(model.Start(0))))) + self.assertTrue(model.IsEnd(assignment.Value(model.NextVar(model.Start(0))))) def testDimensionTSP(self): manager = pywrapcp.RoutingIndexManager(10, 1, 0) @@ -274,24 +268,23 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Add generic dimension - model.AddDimension(transit_idx, 90, 90, True, 'distance') - distance_dimension = model.GetDimensionOrDie('distance') + model.AddDimension(transit_idx, 90, 90, True, "distance") + distance_dimension = model.GetDimensionOrDie("distance") # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) assignment = model.SolveWithParameters(search_parameters) self.assertEqual(90, assignment.ObjectiveValue()) # Inspect solution node = model.Start(0) cumul = 0 while not model.IsEnd(node): - self.assertEqual( - cumul, assignment.Value(distance_dimension.CumulVar(node))) + self.assertEqual(cumul, assignment.Value(distance_dimension.CumulVar(node))) next_node = assignment.Value(model.NextVar(node)) cumul += Distance(node, next_node) node = next_node @@ -302,25 +295,23 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Add generic dimension - model.AddDimensionWithVehicleCapacity(transit_idx, 90, [90], True, - 'distance') - distance_dimension = model.GetDimensionOrDie('distance') + model.AddDimensionWithVehicleCapacity(transit_idx, 90, [90], True, "distance") + distance_dimension = model.GetDimensionOrDie("distance") # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) assignment = model.SolveWithParameters(search_parameters) self.assertEqual(90, assignment.ObjectiveValue()) # Inspect solution node = model.Start(0) cumul = 0 while not model.IsEnd(node): - self.assertEqual( - cumul, assignment.Value(distance_dimension.CumulVar(node))) + self.assertEqual(cumul, assignment.Value(distance_dimension.CumulVar(node))) next_node = assignment.Value(model.NextVar(node)) cumul += Distance(node, next_node) node = next_node @@ -331,25 +322,23 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Add generic dimension - model.AddDimensionWithVehicleTransits([transit_idx], 90, 90, True, - 'distance') - distance_dimension = model.GetDimensionOrDie('distance') + model.AddDimensionWithVehicleTransits([transit_idx], 90, 90, True, "distance") + distance_dimension = model.GetDimensionOrDie("distance") # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) assignment = model.SolveWithParameters(search_parameters) self.assertEqual(90, assignment.ObjectiveValue()) # Inspect solution node = model.Start(0) cumul = 0 while not model.IsEnd(node): - self.assertEqual( - cumul, assignment.Value(distance_dimension.CumulVar(node))) + self.assertEqual(cumul, assignment.Value(distance_dimension.CumulVar(node))) next_node = assignment.Value(model.NextVar(node)) cumul += Distance(node, next_node) node = next_node @@ -360,22 +349,21 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Add generic dimension distances = [ model.RegisterTransitCallback(One), model.RegisterTransitCallback(Two), - model.RegisterTransitCallback(Three) + model.RegisterTransitCallback(Three), ] - model.AddDimensionWithVehicleTransits(distances, 90, 90, True, - 'distance') - distance_dimension = model.GetDimensionOrDie('distance') + model.AddDimensionWithVehicleTransits(distances, 90, 90, True, "distance") + distance_dimension = model.GetDimensionOrDie("distance") # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) assignment = model.SolveWithParameters(search_parameters) self.assertEqual(90, assignment.ObjectiveValue()) # Inspect solution @@ -384,7 +372,8 @@ class TestRoutingModel(unittest.TestCase): cumul = 0 while not model.IsEnd(node): self.assertEqual( - cumul, assignment.Min(distance_dimension.CumulVar(node))) + cumul, assignment.Min(distance_dimension.CumulVar(node)) + ) next_node = assignment.Value(model.NextVar(node)) # Increment cumul by the vehicle distance which is equal to the vehicle # index + 1, cf. distances. @@ -397,26 +386,25 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Add constant dimension - constant_id, success = model.AddConstantDimension(1, 100, True, 'count') + constant_id, success = model.AddConstantDimension(1, 100, True, "count") self.assertTrue(success) self.assertEqual(transit_idx + 1, constant_id) - count_dimension = model.GetDimensionOrDie('count') + count_dimension = model.GetDimensionOrDie("count") # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) assignment = model.SolveWithParameters(search_parameters) self.assertEqual(90, assignment.ObjectiveValue()) # Inspect solution node = model.Start(0) count = 0 while not model.IsEnd(node): - self.assertEqual(count, - assignment.Value(count_dimension.CumulVar(node))) + self.assertEqual(count, assignment.Value(count_dimension.CumulVar(node))) count += 1 node = assignment.Value(model.NextVar(node)) self.assertEqual(10, count) @@ -427,23 +415,21 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Add vector dimension values = list(range(10)) unary_transit_idx, success = model.AddVectorDimension( - values, - 100, # capacity - True, # fix_start_cumul_to_zero - 'vector') + values, 100, True, "vector" # capacity # fix_start_cumul_to_zero + ) self.assertTrue(success) self.assertEqual(transit_idx + 1, unary_transit_idx) - vector_dimension = model.GetDimensionOrDie('vector') + vector_dimension = model.GetDimensionOrDie("vector") # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) self.assertEqual(model.ROUTING_NOT_SOLVED, model.status()) assignment = model.SolveWithParameters(search_parameters) self.assertIsNotNone(assignment) @@ -453,8 +439,7 @@ class TestRoutingModel(unittest.TestCase): node = model.Start(0) cumul = 0 while not model.IsEnd(node): - self.assertEqual(cumul, - assignment.Value(vector_dimension.CumulVar(node))) + self.assertEqual(cumul, assignment.Value(vector_dimension.CumulVar(node))) cumul += values[node] node = assignment.Value(model.NextVar(node)) @@ -469,17 +454,16 @@ class TestRoutingModel(unittest.TestCase): model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Add matrix dimension matrix_transit_idx, success = model.AddMatrixDimension( - matrix, - 100, # capacity - True, # fix_start_cumul_to_zero - 'matrix') + matrix, 100, True, "matrix" # capacity # fix_start_cumul_to_zero + ) self.assertTrue(success) self.assertEqual(transit_idx + 1, matrix_transit_idx) - dimension = model.GetDimensionOrDie('matrix') + dimension = model.GetDimensionOrDie("matrix") # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) self.assertEqual(model.ROUTING_NOT_SOLVED, model.status()) assignment = model.SolveWithParameters(search_parameters) self.assertIsNotNone(assignment) @@ -492,8 +476,7 @@ class TestRoutingModel(unittest.TestCase): self.assertEqual(cumul, assignment.Value(dimension.CumulVar(index))) prev_index = index index = assignment.Value(model.NextVar(index)) - cumul += matrix[manager.IndexToNode(prev_index)][ - manager.IndexToNode(index)] + cumul += matrix[manager.IndexToNode(prev_index)][manager.IndexToNode(index)] def testMatrixDimensionVRP(self): manager = pywrapcp.RoutingIndexManager(5, 2, 0) @@ -506,17 +489,16 @@ class TestRoutingModel(unittest.TestCase): model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Add matrix dimension matrix_transit_idx, success = model.AddMatrixDimension( - matrix, - 10, # capacity - True, # fix_start_cumul_to_zero - 'matrix') + matrix, 10, True, "matrix" # capacity # fix_start_cumul_to_zero + ) self.assertTrue(success) self.assertEqual(transit_idx + 1, matrix_transit_idx) - dimension = model.GetDimensionOrDie('matrix') + dimension = model.GetDimensionOrDie("matrix") # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) self.assertEqual(model.ROUTING_NOT_SOLVED, model.status()) assignment = model.SolveWithParameters(search_parameters) self.assertIsNotNone(assignment) @@ -527,12 +509,12 @@ class TestRoutingModel(unittest.TestCase): index = model.Start(v) cumul = 0 while not model.IsEnd(index): - self.assertEqual(cumul, - assignment.Value(dimension.CumulVar(index))) + self.assertEqual(cumul, assignment.Value(dimension.CumulVar(index))) prev_index = index index = assignment.Value(model.NextVar(index)) cumul += matrix[manager.IndexToNode(prev_index)][ - manager.IndexToNode(index)] + manager.IndexToNode(index) + ] def testDisjunctionTSP(self): manager = pywrapcp.RoutingIndexManager(10, 1, 0) @@ -540,21 +522,26 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Add disjunctions - disjunctions = [[manager.NodeToIndex(1), - manager.NodeToIndex(2)], [manager.NodeToIndex(3)], - [manager.NodeToIndex(4)], [manager.NodeToIndex(5)], - [manager.NodeToIndex(6)], [manager.NodeToIndex(7)], - [manager.NodeToIndex(8)], [manager.NodeToIndex(9)]] + disjunctions = [ + [manager.NodeToIndex(1), manager.NodeToIndex(2)], + [manager.NodeToIndex(3)], + [manager.NodeToIndex(4)], + [manager.NodeToIndex(5)], + [manager.NodeToIndex(6)], + [manager.NodeToIndex(7)], + [manager.NodeToIndex(8)], + [manager.NodeToIndex(9)], + ] for disjunction in disjunctions: model.AddDisjunction(disjunction) # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) assignment = model.SolveWithParameters(search_parameters) self.assertEqual(86, assignment.ObjectiveValue()) # Inspect solution @@ -571,25 +558,26 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Add disjunctions - disjunctions = [([manager.NodeToIndex(1), - manager.NodeToIndex(2)], 1000), - ([manager.NodeToIndex(3)], 1000), - ([manager.NodeToIndex(4)], 1000), - ([manager.NodeToIndex(5)], 1000), - ([manager.NodeToIndex(6)], 1000), - ([manager.NodeToIndex(7)], 1000), - ([manager.NodeToIndex(8)], 1000), - ([manager.NodeToIndex(9)], 0)] + disjunctions = [ + ([manager.NodeToIndex(1), manager.NodeToIndex(2)], 1000), + ([manager.NodeToIndex(3)], 1000), + ([manager.NodeToIndex(4)], 1000), + ([manager.NodeToIndex(5)], 1000), + ([manager.NodeToIndex(6)], 1000), + ([manager.NodeToIndex(7)], 1000), + ([manager.NodeToIndex(8)], 1000), + ([manager.NodeToIndex(9)], 0), + ] for disjunction, penalty in disjunctions: model.AddDisjunction(disjunction, penalty) # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE) + routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE + ) assignment = model.SolveWithParameters(search_parameters) self.assertEqual(68, assignment.ObjectiveValue()) # Inspect solution @@ -602,8 +590,7 @@ class TestRoutingModel(unittest.TestCase): def testRoutingModelParameters(self): parameters = pywrapcp.DefaultRoutingModelParameters() - parameters.solver_parameters.CopyFrom( - pywrapcp.Solver.DefaultSolverParameters()) + parameters.solver_parameters.CopyFrom(pywrapcp.Solver.DefaultSolverParameters()) parameters.solver_parameters.trace_propagation = True manager = pywrapcp.RoutingIndexManager(10, 1, 0) self.assertIsNotNone(manager) @@ -631,49 +618,49 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Close with parameters search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.SAVINGS) + routing_enums_pb2.FirstSolutionStrategy.SAVINGS + ) search_parameters.local_search_metaheuristic = ( - routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) - search_parameters.local_search_operators.use_two_opt = ( - pywrapcp.BOOL_FALSE) + routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH + ) + search_parameters.local_search_operators.use_two_opt = pywrapcp.BOOL_FALSE search_parameters.solution_limit = 20 model.CloseModelWithParameters(search_parameters) # Solve with parameters assignment = model.SolveWithParameters(search_parameters) self.assertEqual( - 11, model.GetNumberOfDecisionsInFirstSolution(search_parameters)) - self.assertEqual( - 0, model.GetNumberOfRejectsInFirstSolution(search_parameters)) + 11, model.GetNumberOfDecisionsInFirstSolution(search_parameters) + ) + self.assertEqual(0, model.GetNumberOfRejectsInFirstSolution(search_parameters)) self.assertEqual(90, assignment.ObjectiveValue()) assignment = model.SolveFromAssignmentWithParameters( - assignment, search_parameters) + assignment, search_parameters + ) self.assertEqual(90, assignment.ObjectiveValue()) def testFindErrorInRoutingSearchParameters(self): params = pywrapcp.DefaultRoutingSearchParameters() params.local_search_operators.use_cross = pywrapcp.BOOL_UNSPECIFIED - self.assertIn('cross', - pywrapcp.FindErrorInRoutingSearchParameters(params)) + self.assertIn("cross", pywrapcp.FindErrorInRoutingSearchParameters(params)) def testCallback(self): manager = pywrapcp.RoutingIndexManager(10, 1, 0) self.assertIsNotNone(manager) model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) callback = Callback(model) model.AddAtSolutionCallback(callback) search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.first_solution_strategy = ( - routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC) + routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC + ) assignment = model.SolveWithParameters(search_parameters) self.assertEqual(90, assignment.ObjectiveValue()) self.assertEqual(len(callback.costs), 1) @@ -685,8 +672,7 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # TODO(user): porting this segfaults the tests. - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) routes = [ [ @@ -695,19 +681,16 @@ class TestRoutingModel(unittest.TestCase): manager.NodeToIndex(5), manager.NodeToIndex(4), manager.NodeToIndex(2), - manager.NodeToIndex(6) - ], - [ - manager.NodeToIndex(7), - manager.NodeToIndex(9), - manager.NodeToIndex(8) + manager.NodeToIndex(6), ], + [manager.NodeToIndex(7), manager.NodeToIndex(9), manager.NodeToIndex(8)], ] assignment = model.ReadAssignmentFromRoutes(routes, False) search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.solution_limit = 1 solution = model.SolveFromAssignmentWithParameters( - assignment, search_parameters) + assignment, search_parameters + ) self.assertEqual(90, solution.ObjectiveValue()) for vehicle in range(0, model.vehicles()): node = model.Start(vehicle) @@ -715,8 +698,7 @@ class TestRoutingModel(unittest.TestCase): while not model.IsEnd(node): node = solution.Value(model.NextVar(node)) if not model.IsEnd(node): - self.assertEqual(routes[vehicle][count], - manager.IndexToNode(node)) + self.assertEqual(routes[vehicle][count], manager.IndexToNode(node)) count += 1 def testAutomaticFirstSolutionStrategy_simple(self): @@ -725,15 +707,15 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() self.assertIsNotNone(model.SolveWithParameters(search_parameters)) self.assertEqual( routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC, - model.GetAutomaticFirstSolutionStrategy()) + model.GetAutomaticFirstSolutionStrategy(), + ) def testAutomaticFirstSolutionStrategy_pd(self): manager = pywrapcp.RoutingIndexManager(31, 7, 0) @@ -741,12 +723,10 @@ class TestRoutingModel(unittest.TestCase): model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) # Add cost function - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) model.SetArcCostEvaluatorOfAllVehicles(transit_idx) - self.assertTrue( - model.AddDimension(transit_idx, 0, 1000, True, 'distance')) - dst_dimension = model.GetDimensionOrDie('distance') + self.assertTrue(model.AddDimension(transit_idx, 0, 1000, True, "distance")) + dst_dimension = model.GetDimensionOrDie("distance") # Add few Pickup and Delivery for request in [[2 * i, 2 * i + 1] for i in range(1, 15)]: print(request) @@ -754,21 +734,22 @@ class TestRoutingModel(unittest.TestCase): delivery_index = manager.NodeToIndex(request[1]) model.AddPickupAndDelivery(pickup_index, delivery_index) model.solver().Add( - model.VehicleVar(pickup_index) == model.VehicleVar( - delivery_index)) + model.VehicleVar(pickup_index) == model.VehicleVar(delivery_index) + ) model.solver().Add( - dst_dimension.CumulVar(pickup_index) <= dst_dimension.CumulVar( - delivery_index)) + dst_dimension.CumulVar(pickup_index) + <= dst_dimension.CumulVar(delivery_index) + ) # Solve search_parameters = pywrapcp.DefaultRoutingSearchParameters() self.assertIsNotNone(model.SolveWithParameters(search_parameters)) self.assertEqual( routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION, - model.GetAutomaticFirstSolutionStrategy()) + model.GetAutomaticFirstSolutionStrategy(), + ) class TestBoundCost(unittest.TestCase): - def testCtor(self): bound_cost = pywrapcp.BoundCost() self.assertIsNotNone(bound_cost) @@ -782,28 +763,23 @@ class TestBoundCost(unittest.TestCase): class TestRoutingDimension(unittest.TestCase): - def testCtor(self): manager = pywrapcp.RoutingIndexManager(31, 7, 3) self.assertIsNotNone(manager) model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) - self.assertTrue( - model.AddDimension(transit_idx, 90, 90, True, 'distance')) - model.GetDimensionOrDie('distance') + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) + self.assertTrue(model.AddDimension(transit_idx, 90, 90, True, "distance")) + model.GetDimensionOrDie("distance") def testSoftSpanUpperBound(self): manager = pywrapcp.RoutingIndexManager(31, 7, 3) self.assertIsNotNone(manager) model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) - self.assertTrue( - model.AddDimension(transit_idx, 100, 100, True, 'distance')) - dimension = model.GetDimensionOrDie('distance') + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) + self.assertTrue(model.AddDimension(transit_idx, 100, 100, True, "distance")) + dimension = model.GetDimensionOrDie("distance") bound_cost = pywrapcp.BoundCost(97, 43) self.assertIsNotNone(bound_cost) @@ -821,18 +797,15 @@ class TestRoutingDimension(unittest.TestCase): self.assertIsNotNone(manager) model = pywrapcp.RoutingModel(manager) self.assertIsNotNone(model) - transit_idx = model.RegisterTransitCallback( - partial(TransitDistance, manager)) - self.assertTrue( - model.AddDimension(transit_idx, 100, 100, True, 'distance')) - dimension = model.GetDimensionOrDie('distance') + transit_idx = model.RegisterTransitCallback(partial(TransitDistance, manager)) + self.assertTrue(model.AddDimension(transit_idx, 100, 100, True, "distance")) + dimension = model.GetDimensionOrDie("distance") bound_cost = pywrapcp.BoundCost(97, 43) self.assertIsNotNone(bound_cost) self.assertFalse(dimension.HasQuadraticCostSoftSpanUpperBounds()) for v in range(manager.GetNumberOfVehicles()): - dimension.SetQuadraticCostSoftSpanUpperBoundForVehicle( - bound_cost, v) + dimension.SetQuadraticCostSoftSpanUpperBoundForVehicle(bound_cost, v) bc = dimension.GetQuadraticCostSoftSpanUpperBoundForVehicle(v) self.assertIsNotNone(bc) self.assertEqual(97, bc.bound) @@ -840,5 +813,5 @@ class TestRoutingDimension(unittest.TestCase): self.assertTrue(dimension.HasQuadraticCostSoftSpanUpperBounds()) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main(verbosity=2)