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
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