Exemplo n.º 1
0
    def solve(self) -> TspSolver:
        vertices_base = deepcopy(self.vertices())
        for vertices in permutations(vertices_base):
            edges = []
            solution = 0.0
            u = vertices[0]
            for v in vertices[1:]:
                w = distance_vertex(u, v)
                edges.append(Edge(u, v, w))
                solution += w
                u = v
            v = vertices[0]
            w = distance_vertex(u, v)
            edges.append(Edge(u, v, w))
            solution += w

            if solution < self.__solution:
                self.__solution = solution
                self.__edges = edges

        graph = self.graph()

        for edge in self.__edges:
            graph.add_edge(edge)

        return self
Exemplo n.º 2
0
 def _add_edge(self, edge: Edge) -> Graph:
     vertex1, vertex2 = edge.vertices()
     weight = edge.weight()
     AdjListGraph._insert_into_adjlist(vertex1, vertex2, weight,
                                       self._adjlist())
     AdjListGraph._insert_into_adjlist(vertex2, vertex1, weight,
                                       self.__transpose_adj_list)
     return self
Exemplo n.º 3
0
 def __is_crossed_edge(
     self,
     candidate: Edge,
 ):
     for edge in self.__edge_stack[1:]:
         line0 = (edge.source_vertex().coordinate(),
                  edge.destination_vertex().coordinate()
                  )  # Line segment edge list
         line1 = (candidate.source_vertex().coordinate(),
                  candidate.destination_vertex().coordinate()
                  )  # Line segment candidate edge
         if intersects(line0, line1):
             return True
     return False
Exemplo n.º 4
0
 def add_edge(self, edge: Edge) -> "Graph":
     """Add an edge in the graph and returns itself for chaining"""
     if self.__vgraph:
         u, v = edge.vertices()
         self.__vgraph.add_edge(u.id(), v.id())
     self.__edge_count += 1
     return self._add_edge(edge)
Exemplo n.º 5
0
    def solve(self) -> TspSolver:
        self.__solution = 0.0
        graph = self.graph()
        vertices = self.vertices()
        src_vertex = vertices[0]
        next = src_vertex

        for v in vertices[1:]:
            distance = distance_vertex(next, v)
            graph.add_edge(Edge(next, v))
            next = v
            self.__solution += distance

        distance = distance_vertex(next, src_vertex)
        graph.add_edge(Edge(next, src_vertex))
        self.__solution += distance

        return self
Exemplo n.º 6
0
 def __build_complete_graph(self) -> None:
     vertices = self.vertices()
     for i in range(len(vertices)):
         for j in range(i):
             u = vertices[i]
             v = vertices[j]
             u[ADDED_KEY] = False
             v[ADDED_KEY] = False
             self.__complete_graph.add_vertex(u)
             self.__complete_graph.add_vertex(v)
             self.__complete_graph.add_edge(
                 Edge(u, v, distance_vertex(u, v)))
Exemplo n.º 7
0
    def __find_path(self, before: Vertex, current: Vertex,
                    is_keeping_direction: FunctionType) -> float:
        current[ADDED_KEY] = True
        self.__remaining_vertices -= 1
        graph = self.graph()

        if current != self.__further_west and self.__is_crossed_edge(
                Edge(before, current)):
            current[ADDED_KEY] = False
            self.__remaining_vertices += 1
            return float('inf')
        elif self.__remaining_vertices == 0 and current == self.__further_west:
            # found the solution!
            w = distance_vertex(current, before)
            graph.add_edge(Edge(before, current, w))
            return w
        else:
            self.__edge_stack.insert(0, Edge(before, current))

            if current == self.__further_east:
                predicate = self.__is_left_direction  # change the direction
            else:
                predicate = is_keeping_direction  # keep the direction (starts following right direction from further_west)

            for next in self.__complete_graph.neighborhood(current):
                x0 = current.coordinate()[0]
                x1 = next.coordinate()[0]

                if not next[ADDED_KEY] and predicate(x0, x1):
                    cost = self.__find_path(current, next, predicate)
                    if cost != float('inf'):
                        w = distance_vertex(current, before)
                        graph.add_edge(Edge(before, current, w))
                        return w + cost

            current[ADDED_KEY] = False
            self.__remaining_vertices += 1
            self.__edge_stack.pop(0)
            return float('inf')