def setUp(self): self._solarsystem = Solar_system() #self._planet_1 = None route_1_x = [1000, 0, 0] route_1_v = [0, -1000, 0] route_1 = Route(route_1_x, route_1_v) name_1 = "Aalto-3" mass_1 = 10 state_1 = State.ALIVE self._satellite_1 = Satellite(name_1, route_1, mass_1, state_1) route_1_x = [152100000000, 0, 0] route_1_v = [0, 29780, 0] route_1 = Route(route_1_x, route_1_v) name_1 = "Earth" mass_1 = 5.97237*10**24 diameter = 2*6371000 self._planet_1 = Planet(name_1, route_1, mass_1, diameter) self.pos_test_string = "x:220my:100kmz:20m" self.test_read = Read_planets() test_file = open("test_read.txt") self._solarsystem.read_planets(test_file) test_file.close()
def setUp(self): self.gossip_universe = GossipUniverse() # - minute stop G1 G2 G3 # # - 1 3 y y n # 3 y y n # 4 n n y # # - 2 1 y y n # 2 y y y # 2 y y y # # - 3 2 y y n # 3 y y y # 3 y y y # # - 4 3 y y n # 1 y y y # 4 y y y # # - 5 3 y y y # 3 y y y # 5 y y y # # - result => 5 self.bob = bus_driver_from(Route([3, 1, 2, 3]), self.gossip_universe) self.alice = bus_driver_from(Route([3, 2, 3, 1]), self.gossip_universe) self.sascha = bus_driver_from(Route([4, 2, 3, 4, 5]), self.gossip_universe) self.drivers = [self.bob, self.alice, self.sascha]
def test_with_given_two_route_parents_with_odd_number_of_genes_should_crossover_correctly( self): #ASSET #Route 1 n = 3 coordinates_for_dot_1_of_route_1 = (0, 2) coordinates_for_dot_2_of_route_1 = (2, 1) coordinates_for_dot_3_of_route_1 = (2, 2) dot_1_of_route_1 = Dot(coordinates_for_dot_1_of_route_1) dot_2_of_route_1 = Dot(coordinates_for_dot_2_of_route_1) dot_3_of_route_1 = Dot(coordinates_for_dot_3_of_route_1) dots_route_1 = [dot_1_of_route_1, dot_2_of_route_1, dot_3_of_route_1] route_1 = Route(dots_route_1) #Route 2 coordinates_for_dot_1_of_route_2 = (2, 2) coordinates_for_dot_2_of_route_2 = (0, 2) coordinates_for_dot_3_of_route_2 = (2, 1) dot_1_of_route_2 = Dot(coordinates_for_dot_1_of_route_2) dot_2_of_route_2 = Dot(coordinates_for_dot_2_of_route_2) dot_3_of_route_2 = Dot(coordinates_for_dot_3_of_route_2) dots_route_2 = [dot_1_of_route_2, dot_2_of_route_2, dot_3_of_route_2] route_2 = Route(dots_route_2) #expected_children child_1 = Route([Dot((0, 2)), Dot((2, 1)), Dot((2, 2))]) child_2 = Route([Dot((2, 2)), Dot((0, 2)), Dot((2, 1))]) expected_children = (child_1, child_2) #ACT result_children = crossover(route_1, route_2, n) #ASSERT self.assertEqual(result_children, expected_children)
def setUp(self): self.gossip_universe = GossipUniverse() # 14 23 34 13 24 33 => 6 minutes self.andy = bus_driver_from(Route([1, 2, 3]), self.gossip_universe) self.cindy = bus_driver_from(Route([4, 3]), self.gossip_universe) self.drivers = [self.andy, self.cindy]
def test_comparisons(self): shuffled = Route( Edge(i='A', f='B', d=1), Edge(i='D', f='A', d=3), Edge(i='B', f='C', d=1), Edge(i='C', f='D', d=2), ) longer_both = Route(Edge(i='A', f='B', d=1), Edge(i='B', f='C', d=1), Edge(i='C', f='D', d=2), Edge(i='D', f='E', d=3), Edge(i='E', f='F', d=5), Edge(i='F', f='A', d=8)) longer_mag_fewer_stops = Route(Edge(i='A', f='B', d=1), Edge(i='B', f='C', d=2), Edge(i='C', f='A', d=8)) peer = Route(Edge(i='A', f='B', d=1), Edge(i='B', f='C', d=1), Edge(i='C', f='D', d=1), Edge(i='D', f='A', d=4)) more_stops_same_mag = Route(Edge(i='A', f='B', d=1), Edge(i='B', f='C', d=1), Edge(i='C', f='D', d=1), Edge(i='D', f='E', d=1), Edge(i='E', f='A', d=2)) self.assertGreater(longer_both, self.route) self.assertGreater(longer_mag_fewer_stops, self.route) self.assertNotEqual(peer, self.route) self.assertNotEqual(more_stops_same_mag, self.route) self.assertNotEqual(shuffled, self.route)
def test_base_adj_rib_in_insert(self, populated_adj_rib_in, require_route, empty_adj_rib_in_noiw): r = require_route("40.0.0.0/24") populated_adj_rib_in.insert(r) empty_adj_rib_in_noiw.insert(r) assert len(populated_adj_rib_in) == 4 assert len(empty_adj_rib_in_noiw) == 1 r2 = require_route("40.0.0.0/24") r2.nh = "f" assert len(populated_adj_rib_in[r2]) == 1 assert len(empty_adj_rib_in_noiw[r2]) == 1 assert populated_adj_rib_in.insert(r2)[0] == r2 assert empty_adj_rib_in_noiw.insert(r2)[0] == r2 assert len(populated_adj_rib_in[r2]) == 2 assert len(empty_adj_rib_in_noiw[r2]) == 2 assert populated_adj_rib_in.insert(r2)[0] == r2 assert empty_adj_rib_in_noiw.insert(r2)[0] == None assert len(empty_adj_rib_in_noiw[r2]) == 2 ipaddr = ipaddress.ip_network("40.0.0.0/24") r2 = Route(ipaddr, [1, 2, 3], "K") assert populated_adj_rib_in.insert(r2)[0] == r2 assert empty_adj_rib_in_noiw.insert(r2)[0] == r2 assert len(populated_adj_rib_in[r2]) == 3 assert len(empty_adj_rib_in_noiw[r2]) == 3 ipaddr = ipaddress.ip_network("40.0.0.0/24") r2 = Route(ipaddr, [1, 3], "K") assert populated_adj_rib_in.insert(r2)[0] == r2 assert empty_adj_rib_in_noiw.insert(r2)[0] == r2 assert len(populated_adj_rib_in[r2]) == 3 assert len(empty_adj_rib_in_noiw[r2]) == 4
def get_shortest_route(self, start, end): """ Gets the shortest route by given start and end node. For departure, end node must be a runway node. For arrival, end node must be a gate node. Assume the arrival start point is outside of Spot. """ # GEO_MIDDLE_NORTH = {"lat": 37.122000, "lng": -122.079057} # SP1 = Spot("SP1", GEO_MIDDLE_NORTH) if end in self.runway_nodes: if start not in self.depart_routing_table[end]: return None return self.depart_routing_table[end][start] if type(end) == Gate: spot = end.get_spots() # spot = SP1 gate_to_spot = self.arrival_routing_table[spot][end] gate_to_spot_links = gate_to_spot.get_links() spot_to_gate = Route(spot, end, []) for i in range(len(gate_to_spot_links) - 1, -1, -1): spot_to_gate.add_link(gate_to_spot_links[i].reverse) if type(start) == Spot: return spot_to_gate node_to_spot = self.arrival_routing_table[spot][start] result = Route(start, end, []) result.add_links(node_to_spot.get_links()) result.add_links(spot_to_gate.get_links()) return result raise Exception("End node is not a runway node nor a gate node.")
def findShortestRoute(self, startNode, destinationName): # get routes to process by getting all out going links of the starting node candidateRoutes = Routes( [Route([link]) for link in startNode.getLinks()]) minRoute = None # candiate routes are the routes to process. # they can be empty when no more routes can have distances less than the current minimum distance # or cannot find any more routes while candidateRoutes.len() > 0: # finished routes store the routes connecting start node and end node finishedRoutes = candidateRoutes.getRoutesEndedWithNode( destinationName) _minRoute = finishedRoutes.getMinDistance() minRoute = _minRoute if minRoute is None or ( _minRoute is not None and minRoute.getDistance() > _minRoute.getDistance()) else minRoute # filter out routes having bigger distance than min route candidateRoutes = Routes([ route for route in candidateRoutes.getRoutes() if minRoute is None or route.getDistance() < minRoute.getDistance() ]) # all candidate routes go one step further. Store the new generated routes candidateRoutes = Routes([Route([]).copyFrom(route).addNextLink(link) \ for route in candidateRoutes.getRoutes() for link in self.findByName(route.getLastLink().child).getLinks() \ if not route.hasNode(link.child) or (link.child == destinationName and startNode.name == destinationName)]) return minRoute
def Gene_Alg(maps, popsize, max_it=50, mu_rate=0.01, elite=0.2, greedy_pool=5): t = datetime.datetime.now() #g0: current generation g0 = [Route(maps, selfopt=True) for _ in range(popsize)] d_list = [r.d for r in g0] rank = sorted(range(len(g0)), key=lambda i: d_list[i]) d_opt = [d_list[rank[0]]] diver = [Diverge(g0, maps)] it = 0 print(popsize, max_it, it, diver[-1], (datetime.datetime.now() - t).seconds) while it < max_it: next_g = [g0[i] for i in rank[:int(popsize * elite)]] while len(next_g) < popsize: p1, p2 = random.sample(range(popsize), 2) rc_index = breedDPX(g0[p1], g0[p2], maps=maps) rc = Route(maps, rc_index, selfopt=True) rc.two_opt() if random.random() < mu_rate: i, k = random.sample(range(len(maps)), 2) rc.mutate(i, k) next_g.append(rc) d_list = [r.d for r in next_g] rank = sorted(range(len(g0)), key=lambda i: d_list[i]) d_opt.append(d_list[rank[0]]) diver.append(Diverge(next_g, maps)) g0 = next_g.copy() it += 1 print(popsize, max_it, it, diver[-1], (datetime.datetime.now() - t).seconds) return (next_g[rank[0]], d_opt, diver, (datetime.datetime.now() - t).seconds)
def test_base_adj_rib_in_preference_ordering(self, empty_adj_rib_in): ipaddr = ipaddress.ip_network("40.0.0.0/24") r1 = Route(ipaddr, ["F"], "K") ipaddr = ipaddress.ip_network("40.0.0.0/24") r2 = Route(ipaddr, ["F", "2", "3"], "4") assert empty_adj_rib_in.insert(r2)[0] == r2 assert empty_adj_rib_in.insert(r1)[0] == r1 assert empty_adj_rib_in[r2][0] == r2 empty_adj_rib_in.preference_ordering() assert empty_adj_rib_in[r2][0] == r1
def testInitializeRoutes(self, mockCreateRoute): ifacefailover.initializeRoutes(self.routes) assert 3 == mockCreateRoute.call_count expected = [ call(self.defaultRoute, ), call(Route('8.8.8.8', '192.168.1.1', '255.255.255.255', 'eth0'), ), call(Route('8.8.4.4', '192.168.1.1', '255.255.255.255', 'eth0'), ) ] assert expected == mockCreateRoute.call_args_list
def testCreateRouteWithExistingRoute(self, mockGetRoute, mockDeleteRoute, mockAddRoute): existingRoute = Route('0.0.0.0', '192.168.1.1', '0.0.0.0', 'eth0') mockGetRoute.return_value = existingRoute route = Route('0.0.0.0', '192.168.1.1', '0.0.0.0', 'eth0') ifacefailover.createRoute(route) mockGetRoute.assert_called_once_with('0.0.0.0') mockDeleteRoute.assert_called_once_with(existingRoute) mockAddRoute.assert_called_once_with(route)
def crossover(self, mom, dad): size = self.city_graph.n - 1 start, end = sorted([random.randrange(size) for _ in range(2)]) momxo = set(mom.vertices[start:end + 1]) dadxo = set(dad.vertices[start:end + 1]) alice = [i for i in dad.vertices if not i in momxo] bob = [i for i in mom.vertices if not i in dadxo] alice[start:start] = mom.vertices[start:end + 1] bob[start:start] = dad.vertices[start:end + 1] return Route(self.city_graph, alice), Route(self.city_graph, bob)
def generate_routes(no_of_routes): global no_of_buses, routes, no_of_ons_sensors, no_of_gateways, no_of_ons_sensors #generates random values from normal dist within a range circ = trunc_normal_dist(mean=sim.route_circ_mean_sd[0], sd=sim.route_circ_mean_sd[1], low=10, upp=40, n=no_of_routes) bus_per_route_distribution = random_int(sim.bus_per_route[0], sim.bus_per_route[1], no_of_routes) no_of_buses = sum(bus_per_route_distribution) if (sim.ons_per_route[0] == sim.ons_per_route[1] == 0): sim.no_of_ons = [0] * no_of_routes else: sim.no_of_ons = random_int(sim.ons_per_route[0], sim.ons_per_route[1], no_of_routes) ons_per_route_distribution = random_int(sim.ons_per_route[0], sim.ons_per_route[1], no_of_routes) sim.no_of_ons = sum(ons_per_route_distribution) gw_per_route_distribution = random_int(sim.gw_per_route[0], sim.gw_per_route[1], no_of_routes) no_of_gateways = sum(gw_per_route_distribution) #add new routes for i in range(no_of_routes): r = Route(circ=circ[i], no_of_buses = bus_per_route_distribution[i], \ no_of_gw= gw_per_route_distribution[i], no_of_ons=ons_per_route_distribution[i]) routes.append(r)
def visualize(batteries, houses): # Show the route in a grid mng = plt.get_current_fig_manager() mng.full_screen_toggle() plt.grid() for house in houses: plt.plot(house.get_x(), house.get_y(), 'o', color='black', markersize=2) # Iterate over the batteries to find the route with the corresponding house for battery in batteries: plt.plot(battery.get_x(), battery.get_y(), 'X', color='black', markersize=12) for route in battery.get_routes(): # Check if the route selected is optimal, or if the house has # a battery closer by length = route.get_length() optimal = True for battery in batteries: test = Route(route.get_house(), battery) if test.get_length() < length: optimal = False if optimal: routes = [(tup1, tup2) for tup1, tup2 in route.get_coordinates()] plt.plot(*zip(*routes), linewidth=1, linestyle='solid', marker='o', markersize=1, color='blue') plt.pause(0.1) else: routes = [(tup1, tup2) for tup1, tup2 in route.get_coordinates()] plt.plot(*zip(*routes), linewidth=1, linestyle='solid', marker='o', markersize=1, color='red') plt.pause(0.1)
def gerar_rotas(self): distancias = self.__pegar_distancias() rotas = [] for i in range(15): aux = [] for j in range(15): rota = Route(distancias[i][j]) if [i, j] in self.lista_pontos_adj \ or [j, i] in self.lista_pontos_adj: index = 0 try: index = self.lista_pontos_adj.index([i, j]) except ValueError: index = self.lista_pontos_adj.index([j, i]) rota.set_delay_calculator(DelayTime(str(index))) aux.append(rota) rotas.append(aux) return rotas
def constraint_relaxation(batteries, houses): """ Keeps connecting the closest house and battery, then switches routes until constraints are satisfied """ houses_local = houses batteries_local = batteries # distances contains a number of lists, one for each battery, # containing tuples of houses and distances to the corresponding battery distances = [] for battery in batteries_local: unsorted = [] for house in houses_local: route = Route(house, battery) unsorted.append((route.get_length(), house)) sorted_houses = countSort2(unsorted) distances.append(sorted_houses) while len(houses_local) > 0: closest = distances[0][0] id = 0 for i in range(len(distances)): # check the first element of eacht list if it is closer than the # previous one if len(distances[i]) > 0: if distances[i][0][0] < closest[0]: closest = distances[i][0] id = i # connect the closest house batteries_local[id].connect_house(closest[1]) houses_local.remove(closest[1]) for d in distances: for tuple in d: if tuple[1] == closest[1]: d.remove(tuple) return apply_constraints(batteries_local)
def plot_main(plot_func): # Read and validate command-line arguments if len(sys.argv) != 1 and len(sys.argv) != 3: sys.exit(help()) if len(sys.argv) == 3 and sys.argv[1] != '-o': sys.exit(help()) output_path = sys.argv[2] if len(sys.argv) == 3 else None plt.rcParams['text.latex.preamble'] = [r'\usepackage{lmodern}'] plt.rcParams.update({ 'text.usetex': True, 'text.latex.unicode': True, 'font.family': 'lmodern', 'font.size': 10, 'axes.titlesize': 10 }) fig = plt.figure() route = Route() route.load('/dev/stdin') plot_func(plt, fig, route) plt.tight_layout() if output_path is not None: plt.savefig(output_path, dpi=1000, box_inches='tight') else: plt.show()
def __init__(self, states, seconds, inc_support, dec_support): self.states = states self.seconds = seconds self.inc_support = inc_support self.dec_support = dec_support self.best_solution = Route(inc_support, dec_support) self.best_solution.calculate_value()
def test_good_constructor_args(self): route = Route("AB1", Edge(i='B', f='C', d=1), Edge(i='C', f='D', d=2), Edge(i='D', f='A', d=3)) with self.assertRaises(AttributeError): _ = route.magnitude _ = route.stops self.assertEqual(route.end_vertex, 'A')
def onImport(self): fileName = tkinter.filedialog.askopenfilename( filetypes=[("Corrdinates files", "*.gpx;*.kml"), ("All files", "*.*")]) if self.fill_between != None: self.fill_between.remove() self.fill_between = None try: self.route = r = Route(fileName) self.fill_between = self.plt.fill_between(r.xPoints, r.yPoints, facecolor="#ff000020") self.heightLine.set_data(r.xPoints, r.yPoints) self.markerLine.set_data(r.xMarkedPoints, r.yMarkedPoints) dif = abs(r.yMin - r.yMax) * 0.2 self.plt.axis([r.xMin, r.xMax, r.yMin - dif, r.yMax + dif]) except Exception as e: if self.fill_between != None: self.fill_between.remove() self.fill_between = None self.heightLine.set_data([], []) self.markerLine.set_data([], []) self.plt.axis([0, 10, 100, 500]) print(e) showerror("Error", e.__str__()) self.canvas.draw()
def readRouteTable(): rt = Route() (dbStatus, routes) = rt.readRoutes(con) if (dbStatus == False): return render_template('error.html', error=rt.error) else: return (routes)
def search_route_dep1(self): ori_map = np.array(self.map, copy=True) for i in range(5): for j in range(6): for di in range(4): if not moveable(i, j, di): continue pos = self.move_node(i, j, di) self.calc_combos() rou = Route([i, j]) rou.update(di, pos) rou.set_ncombos(self.num_combos + 0.01 * self.num_cbnodes, self.dropcom) if len(self.save_route) < BEAM_DEPTH: self.save_route.append(rou) self.save_map.append(self.map) #if rou.ncombos > 0: # rou.print_route() elif rou.sumcoms > min(self.save_route, key=lambda x: x.ncombos).sumcoms: ind = self.save_route.index( min(self.save_route, key=lambda x: x.ncombos)) # Replace min self.save_route.pop(ind) self.save_map.pop(ind) self.save_route.append(rou) self.save_map.append(self.map) # Back to start map self.map = np.array(ori_map, copy=True)
def find_best_position(self, route, customer): ##cost, position = return #put in position #check if it's valid #find all possible positions cost_before = route.cost if route.calculate_cost(update=True) != cost_before: print("ERROR MY DAWG COST BEFORE FINDB BEST IN OPTI NEEDS SOME LOOKY LOOK") customers_copy = route.customers[:] n = len(customers_copy) b_position = -1 b_cost = 999999999 for position in range(1,n-1): trial_route = customers_copy[:] trial_route.insert(position, customer) trial_route_ = Route(self.problem, trial_route, get_depot_=False) possible, cost = trial_route_.is_valid() if possible and cost < b_cost: b_position = position b_cost = cost b_cost = b_cost - cost_before return b_cost, b_position
def editschedule(): global con # set debugging level db.enabled = False # Only administrators have access to this page if not session['administrator']: return render_template( 'error.html', error="Only Administrators can access schedules") # create the objects we need sched = Schedule() bt = Boat() rt = Route() # process the data sent back from the form if request.method == 'POST': # Read the boats and schedule to display in option lists boats = readBoatTable() routes = readRouteTable() # If they processed the edit button then read the scchedule record and pass the details # to the new schedule scren if 'Edit' in request.form: CruiseDate = request.form['Edit'].split('.')[0] CruiseNo = int(request.form['Edit'].split('.')[1]) (dbStatus, rows) = sched.readSched(con, CruiseDate, CruiseNo) if dbStatus == False: # return render_template("newschedule.html", sched = rows, CruiseDate = CruiseDate, CruiseNo = CruiseNo, boats = boats, routes = routes, action = 'UPDATE', returnmessage = sched.error) return render_template("newschedule.html", sched=rows, CruiseDate=CruiseDate, CruiseNo=CruiseNo, boats=boats, routes=routes, action='UPDATE', returnmessage=sched.error) else: return render_template("newschedule.html", sched=rows[0], CruiseDate=CruiseDate, CruiseNo=CruiseNo, boats=boats, routes=routes, action='UPDATE') # If they have pressed add then create a blank 'rows' record and pass to the newschedule form if 'Add' in request.form: rows = sched.blankScheduleRow() CruiseDate = rows[0]["CruiseDate"] CruiseNo = int(rows[0]["CruiseNo"]) return render_template("newschedule.html", sched=rows, CruiseDate=CruiseDate, CruiseNo=CruiseNo, boats=boats, routes=routes, action='ADD')
def reproduce(sample_of_individuals, n): #get the first 25% from the sample for reproduction number_of_individuals_preserved = int(n / 4 if n % 2 == 0 else n / 4 + 1) individuals_preserved_for_next_generation = sample_of_individuals[:number_of_individuals_preserved] number_of_children_needed = n - number_of_individuals_preserved index_of_pair_of_parents = 0 children_reproduced = [] while number_of_children_needed > 0: #create 2 children from pair children_from_crossover = crossover(sample_of_individuals[index_of_pair_of_parents], sample_of_individuals[index_of_pair_of_parents + 1], n) children_reproduced.append(children_from_crossover[0]) children_reproduced.append(children_from_crossover[1]) #increase with 2 because for crossover 2 parents are needed index_of_pair_of_parents += 2 #decrease with 2 because 2 children are reproduced from crossover number_of_children_needed -= 2 next_generation_individuals = [] for i in individuals_preserved_for_next_generation: d = [do for do in i.dots] r = Route(d) next_generation_individuals.append(r) for i in children_reproduced: next_generation_individuals.append(i) return next_generation_individuals
def generate_initial_route(n): dots = generate_n_different_random_dots(n) #uncomment for shiwing initial dots when using solver #print([dot.coordinates for dot in dots]) initial_route = Route(dots) return initial_route
def load_routes(self): routes_file = os.path.join(self.source_folder, 'routes.txt') self.available_files['routes.txt'] = True data = self.open(routes_file) # Iterate over all the stops and puts them in the stops dictionary for i in range(data.shape[0]): r = Route() # Required fields r.id = data['route_id'][i] r.short_name = data['route_short_name'][i] r.long_name = data['route_long_name'][i] r.type = data['route_type'][i] # optional fields available_fields = data.dtype.names if 'agency_id' in available_fields: r.agency_id = data['agency_id'][i] if 'route_desc' in available_fields: r.desc = data['route_desc'][i] if 'route_url' in available_fields: r.url = data['route_url'][i] if 'route_color' in available_fields: r.color = data['route_color'][i] if 'route_text_color' in available_fields: r.text_color = data['route_text_color'][i] if 'route_sort_order' in available_fields: r.sort_order = data['route_sort_order'][i] self.routes[r.id] = r del data
def greedy_assignment(route, buses): routes = [] picked_up = [False for stop in route.stops] while False in picked_up: bus = None for bus in buses[::-1]: #Found an unassigned bus if bus.route == None: break if bus == None: print("Out of buses. Terminating bus assignment.") break route_creating = Route() for i in range(len(route.stops)): if not picked_up[i]: route_creating.add_stop(route.stops[i]) picked_up[i] = True if (not bus.can_handle(route_creating)): route_creating.remove_stop(route.stops[i]) picked_up[i] = False for bus in buses: if bus.can_handle(route_creating): bus.assign(route_creating) break if route_creating.bus != None: routes.append(route_creating) continue #If no bus was large enough, should be for one stop. assert (len(route_creating.stops) == 1), str(len(route_creating.stops)) for bus in buses[::-1]: if bus.route == None: break bus.assign(route_creating) routes.append(route_creating) return routes
def two_opt_1(index, k=5, max_it=10, improvement_threshold=1e-3, maps=maps): must_list = random.sample(range(len(maps)), k) record = [] for swap_first in must_list: new_index = index[swap_first:] + index[:swap_first] impr = 1e6 for swap_last in range(len(index)): if (swap_first - swap_last) % len(index) < 3: continue a, b, c, d = swap_first, swap_first - 1, swap_last, ( swap_last + 1) % len(index) d2_former = (maps[index[a]]).distance( maps[index[b]]) + (maps[index[c]]).distance(maps[index[d]]) d2_new = (maps[index[c]]).distance( maps[index[b]]) + (maps[index[d]]).distance(maps[index[a]]) diff = d2_former - d2_new if diff > impr: impr = diff swap = swap_last r_temp = Route(maps, two_opt_swap(index, swap_first, swap)) r_temp.distance() r_temp.two_opt(max_it) r_temp.cal_score() record.append(new_index + [r_temp.score, r_temp.d, r_temp.steps]) return record