Пример #1
0
def greedy_repair(current, random_state):
    """
    Greedily repairs a tour, stitching up nodes that are not departed
    with those not visited.
    """
    visited = set(current.edges.values())

    # This kind of randomness ensures we do not cycle between the same
    # destroy and repair steps every time.
    shuffled_idcs = random_state.permutation(len(current.nodes))
    nodes = [current.nodes[idx] for idx in shuffled_idcs]

    while len(current.edges) != len(current.nodes):
        node = next(node for node in nodes if node not in current.edges)

        # Computes all nodes that have not currently been visited,
        # that is, those that this node might visit. This should
        # not result in a subcycle, as that would violate the TSP
        # constraints.
        unvisited = {
            other
            for other in current.nodes if other != node if other not in visited
            if not would_form_subcycle(node, other, current)
        }

        # Closest visitable node.
        nearest = min(unvisited,
                      key=lambda other: distances.euclidean(node[1], other[1]))

        current.edges[node] = nearest
        visited.add(nearest)

    return current
Пример #2
0
 def objective(self):
     """
     The objective function is simply the sum of all individual edge lengths,
     using the rounded Euclidean norm.
     """
     return sum(
         distances.euclidean(node[1], self.edges[node][1])
         for node in self.nodes)
Пример #3
0
    def load_instance(self, name: str) -> None:
        problem: Problem = load_problem(Instance.PATH.format(name))
        coords: OrderedDict = problem.node_coords
        d = problem.dimension

        self.adjacency_matrix = np.zeros(shape=(d, d), dtype=np.int)
        for i in range(d):
            for j in range(d):
                self.adjacency_matrix[i,
                                      j] = euclidean(coords[i + 1],
                                                     coords[j + 1])

        self.city_coords: np.ndarray = np.array(list(coords.values()))
Пример #4
0
def create_distances_matrix(coords):
    """
    :param coords:
    :return:
    """
    n = len(coords)
    matrix = []
    for coord1 in coords:
        row = []
        for coord2 in coords:
          row.append(distances.euclidean(coord1, coord2))
        matrix.append(row)
    return np.array(matrix)
Пример #5
0
def load_instance_tsplib(path):
    problem = load_problem(path)
    coords = problem.node_coords
    d = problem.dimension

    dimension_matrix = np.zeros(shape=(d, d), dtype=np.int)
    for i in range(d):
        for j in range(d):
            dimension_matrix[i, j] = int(
                round(euclidean(coords[i + 1], coords[j + 1])))

    final_coords = np.array(list(coords.values()))
    return final_coords, dimension_matrix
Пример #6
0
def worst_removal(current, random_state):
    """
    Worst removal iteratively removes the 'worst' edges, that is,
    those edges that have the largest distance.
    """
    destroyed = current.copy()

    worst_edges = sorted(destroyed.nodes,
                         key=lambda node: distances.euclidean(
                             node[1], destroyed.edges[node][1]))

    for idx in range(edges_to_remove(current)):
        del destroyed.edges[worst_edges[-idx - 1]]

    return destroyed
Пример #7
0
    def cost(subpath):
        path = fix_bounds(subpath, start_node, end_node)

        return sum(
            distances.euclidean(path[idx][1], path[idx + 1][1])
            for idx in range(len(path) - 1))
Пример #8
0
def test_euclidean(start, end, dist, exc):
    if exc:
        with pytest.raises(exc):
            distances.euclidean(start, end)
    else:
        assert distances.euclidean(start, end) == dist
def test_euclidean(start, end, distance):
    assert distances.euclidean(start, end) == distance
Пример #10
0
def euclidean_jitter(a, b):
    dist = distances.euclidean(a, b) # works for n-dimensions
    return dist * random.random() * 2