def insert(self, i): min_si = None min_cost = math.inf for si in range(self.n): cost = basic.distance(self.xy, self.node_id(si), i) cost += basic.distance(self.xy, self.node_id(si + 1), i) cost -= self.next_length(si) #print(cost) assert (cost >= -1) if cost < min_cost: min_cost = cost min_si = si self.node_ids.insert(min_si + 1, i) self.n += 1
def improve(xy, tour): n = len(tour) for i in range(n): ilen = basic.distance(xy, tour[i], tour[(i + 1) % n]) for j in range(i + 2, n): jlen = basic.distance(xy, tour[j], tour[(j + 1) % n]) cost = basic.distance(xy, tour[i], tour[j]) + basic.distance( xy, tour[(i + 1) % n], tour[(j + 1) % n]) improvement = ilen + jlen - cost if improvement > 0: new_tour = swap(tour, i, j) assert (tour != new_tour) return new_tour, improvement return tour, 0
def compute_sorted_edges(xy, node_id): edges = [] for i in range(len(xy)): if i == node_id: continue edges.append((basic.distance(xy, node_id, i), i)) edges.sort(reverse=True) return edges
def length(xy, tour): seen = set() n = len(tour) L = 0 for i in range(n): L += basic.distance(xy, tour[i - 1], tour[i]) seen.add(tour[i]) assert (len(seen) == len(tour)) return L
def get_all_edges(xy): """Gets all (n-1)*(n)/2 edges. Returns list of tuples : (cost, (i, j)) i, j are the point IDs in the edge, in no particular order. """ edges = [] n = len(xy) for i in range(n - 1): for j in range(i + 1, n): if i == j: continue edge = [i, j] random.shuffle(edge) edges.append((basic.distance(xy, i, j), edge)) return edges
def next_length(self, si): assert (si < self.n and si >= 0) return basic.distance(self.xy, self.node_id(si), self.node_id(si + 1))
def length(self, si, sj): i = self.node_id(si) j = self.node_id(sj) return basic.distance(self.xy, i, j)
def sort_nearest(xy, ref_point): ixy = [] for i in range(len(xy)): ixy.append((i, xy[i])) ixy.sort(key=lambda x: basic.distance(xy, x[0], ref_point)) return [x[0] for x in ixy][1:]