Ejemplo n.º 1
0
    def dijkstra(self, source):
        """
        Computes Dijkstra's algorithm (shortest path from 
        a source vertex to all other verticies). 
        
        Assumption(s):
            - "source" is in the graph.
            - The graph has no negative edge-weights.
            - The graph has no negative cycles.

        :param source: The vertex to perform Dijkstra's on.
        :return Two dictionaries:
            -A dictionary containing the cost to traverse from "source" to each
            reachable vertex in the graph.
            -A dictionary encoding the shortest path from "source" to each
            reachable vertex in the graph.
        """

        V = self.get_vertices()
        dist, prev = {}, {}

        assert source in V

        pq = FibonacciHeap()
        for v in V:
            dist[v] = INFINITY if v != source else 0
            prev[v] = None
            pq.push(v, dist[v])

        while not pq.empty():
            u = pq.pop()

            neighbors = self.get_neighbors(u)
            for neighbor in neighbors:
                alt = dist[u] + self.get_edge_value(u, neighbor)
                if alt >= dist[neighbor]:
                    continue

                dist[neighbor] = alt
                prev[neighbor] = u

                if neighbor not in pq:
                    pq.push(neighbor, alt)
                else:
                    pq.decrease_key(neighbor, alt)

        return dist, prev
Ejemplo n.º 2
0
    def mst(self):
        """
        Computes the minimum spanning tree of the graph using
        Prim's algorithm.

        :return: The minimum spanning tree (in a list of connecting edges).
        """

        V = self.get_vertices()
        heap = FibonacciHeap()
        cost, prev = {}, {}

        for u in V:
            cost[u] = INFINITY
            prev[u] = None

        v = random.choice(V)
        cost[v] = 0
        for u in V:
            heap.push(u, cost[u])

        while not heap.empty():
            u = heap.pop()
            neighbors = self.get_neighbors(u)
            for v in neighbors:
                edge_weight = self.get_edge_value(u, v)
                if v in heap and cost[v] > edge_weight:
                    cost[v] = edge_weight
                    prev[v] = u
                    heap.decrease_key(v, cost[v])

        mst = set()
        for v in V:
            if prev[v] is None:
                continue

            edge = (prev[v], v) if prev[v] < v else (v, prev[v])
            mst.add(edge)

        return mst