class DijkSP(object): def __init__(self, G, s, t = None): "find the shortest path tree (in a directed graph with non-negative weights) from s to every other vertex using Dijkstra's alg" self._G = G self._s = s self._distTo = [_INF for _ in range(G.V())] self._distTo[s] = 0 self._edgeTo = [_SENTINEL for _ in range(G.V())] # edgeTo[v]: last edge on shortest path from s to v self._pq = IndexMinPQ(G.V()) self._pq.insert(s, 0) while (not self._pq.isEmpty()): v = self._pq.delMin() # add closest vertex to source to Tree if t and v == t: return self._relaxVertix(v) def distTo(self, v): "distance from src to vertex v" return self._distTo[v] def hasPathTo(self, v): "checks whether path exists from src to vertex v" return self._edgeTo[v] != _SENTINEL def pathTo(self, v): "returns path from src to vertex v" if not self.hasPathTo(v): return path = [] e = self._edgeTo[v] # last edge of path while e.src() != self._s: path.append(e) e = self._edgeTo[e.src()] path.append(e) return path[::-1] def _relaxVertix(self, v): for e in self._G.adj(v): self._relaxEdge(e) # relaxEdge(e) updates the distTo and edgeTo data structures def _relaxEdge(self, edge): "relaxes an edge by updating data structures with that edge" v = edge.src() w = edge.sink() if self._distTo[w] > self._distTo[v] + edge.weight(): self._distTo[w] = self._distTo[v] + edge.weight() # distance to source self._edgeTo[w] = edge if not self._pq.contains(w): self._pq.insert(w, self._distTo[w]) else: self._pq.decreaseKey(w, self._distTo[w]) def __repr__(self): "print spt built by Digjkstra object" V = len(self._edgeTo) spt = GraphLib.EdgeWeightedDigraph(V) for i in range(V): if self._edgeTo[i] != _SENTINEL: spt.addEdge(self._edgeTo[i]) print str(spt.edges())
class DijkSP(object): def __init__(self, G, s, t=None): "find the shortest path tree (in a directed graph with non-negative weights) from s to every other vertex using Dijkstra's alg" self._s = s self._distTo = [_INF for _ in range(G.V())] self._distTo[s] = 0 self._edgeTo = [_SENTINEL for _ in range(G.V()) ] # edgeTo[v]: last edge on shortest path from s to v self._pq = IndexMinPQ(G.V()) self._pq.insert(s, 0) while (not self._pq.isEmpty()): v = self._pq.delMin() # add closest vertex to source to Tree if t and v == t: return for e in G.adj(v): self._relax( e ) # relax(e) updates the distTo and edgeTo data structures def distTo(self, v): "distance from src to vertex v" return self._distTo[v] def hasPathTo(self, v): "checks whether path exists from src to vertex v" return self._edgeTo[v] != _SENTINEL def pathTo(self, v): "returns path from src to vertex v" if not self.hasPathTo(v): return path = [] e = self._edgeTo[v] # last edge of path while e.src() != self._s: path.append(e) e = self._edgeTo[e.src()] path.append(e) return path[::-1] def _relax(self, edge): "relaxes an edge by updating data structures with that edge" v = edge.src() w = edge.sink() if self._distTo[w] > self._distTo[v] + edge.weight(): self._distTo[w] = self._distTo[v] + edge.weight( ) # distance to source self._edgeTo[w] = edge if not self._pq.contains(w): self._pq.insert(w, self._distTo[w]) else: self._pq.decreaseKey(w, self._distTo[w]) def __repr__(self): "print spt built by Digjkstra object" V = len(self._edgeTo) spt = GraphLib.EdgeWeightedDigraph(V) for i in range(V): if self._edgeTo[i] != _SENTINEL: spt.addEdge(self._edgeTo[i]) print str(spt.edges())
class EagerPrimMST(object): ''' similar to LazyPrimMST except remove obsolete edges from PQ given a connected, undirected, weighted graph, finds an MST and its weight key = vertex; priority = weight of edge PQ has 1 entry per vertex ''' def __init__(self, EG): self._edgeTo = [-1 for _ in range(EG.V())] self._distTo = [_INF for _ in range(EG.V()) ] self._distTo[0] = 0 self._pq = IndexMinPQ(EG.V()) self._mst = [] # list of edges in MST self._weight = 0 self._marked = set() # set of vertices in MST self._pq.insert(0, 0) while (not self._pq.isEmpty() and len(self._mst) < EG.V() - 1): v = self._pq.delMin() if v > 0: self._mst.append(self._edgeTo[v]) self._weight += self._edgeTo[v].weight() self._visit(EG, v) def _visit(self, EG, v): ''' add v to Tree; add all non-tree vertices adjacent to v to PQ; update priority of edges connecting non-tree vertices to Tree ''' self._marked.add(v) for e in EG.adj(v): # e is edge connecting w (non-Tree vertex) to Tree w = e.other(v) if w not in self._marked: if self._distTo[w] > e.weight(): self._edgeTo[w] = e self._distTo[w] = e.weight() if not self._pq.contains(w): # w is not in PQ self._pq.insert(w, e.weight()) else: self._pq.decreaseKey(w, e.weight()) def mst(self): "returns edges in MST" return self._mst def weight(self): "returns weight of MST" return self._weight def __repr__(self): "Everything about MST" return "edges=%r wt=%r" % (self.mst(), self.weight())
class EagerPrimMST(object): ''' similar to LazyPrimMST except remove obsolete edges from PQ given a connected, undirected, weighted graph, finds an MST and its weight key = vertex; priority = weight of edge PQ has 1 entry per vertex ''' def __init__(self, EG): self._edgeTo = [-1 for _ in range(EG.V())] self._distTo = [_INF for _ in range(EG.V())] self._distTo[0] = 0 self._pq = IndexMinPQ(EG.V()) self._mst = [] # list of edges in MST self._weight = 0 self._marked = set() # set of vertices in MST self._pq.insert(0, 0) while (not self._pq.isEmpty() and len(self._mst) < EG.V() - 1): v = self._pq.delMin() if v > 0: self._mst.append(self._edgeTo[v]) self._weight += self._edgeTo[v].weight() self._visit(EG, v) def _visit(self, EG, v): ''' add v to Tree; add all non-tree vertices adjacent to v to PQ; update priority of edges connecting non-tree vertices to Tree ''' self._marked.add(v) for e in EG.adj(v): # e is edge connecting w (non-Tree vertex) to Tree w = e.other(v) if w not in self._marked: if self._distTo[w] > e.weight(): self._edgeTo[w] = e self._distTo[w] = e.weight() if not self._pq.contains(w): # w is not in PQ self._pq.insert(w, e.weight()) else: self._pq.decreaseKey(w, e.weight()) def mst(self): "returns edges in MST" return self._mst def weight(self): "returns weight of MST" return self._weight def __repr__(self): "Everything about MST" return "edges=%r wt=%r" % (self.mst(), self.weight())
def __init__(self, EG): self._edgeTo = [-1 for _ in range(EG.V())] self._distTo = [_INF for _ in range(EG.V())] self._distTo[0] = 0 self._pq = IndexMinPQ(EG.V()) self._mst = [] # list of edges in MST self._weight = 0 self._marked = set() # set of vertices in MST self._pq.insert(0, 0) while (not self._pq.isEmpty() and len(self._mst) < EG.V() - 1): v = self._pq.delMin() if v > 0: self._mst.append(self._edgeTo[v]) self._weight += self._edgeTo[v].weight() self._visit(EG, v)
def __init__(self, G, s, t=None): "find the shortest path tree (in a directed graph with non-negative weights) from s to every other vertex using Dijkstra's alg" self._s = s self._distTo = [_INF for _ in range(G.V())] self._distTo[s] = 0 self._edgeTo = [_SENTINEL for _ in range(G.V()) ] # edgeTo[v]: last edge on shortest path from s to v self._pq = IndexMinPQ(G.V()) self._pq.insert(s, 0) while (not self._pq.isEmpty()): v = self._pq.delMin() # add closest vertex to source to Tree if t and v == t: return for e in G.adj(v): self._relax( e ) # relax(e) updates the distTo and edgeTo data structures
def __init__(self, G, s, t = None): "find the shortest path tree (in a directed graph with non-negative weights) from s to every other vertex using Dijkstra's alg" self._G = G self._s = s self._distTo = [_INF for _ in range(G.V())] self._distTo[s] = 0 self._edgeTo = [_SENTINEL for _ in range(G.V())] # edgeTo[v]: last edge on shortest path from s to v self._pq = IndexMinPQ(G.V()) self._pq.insert(s, 0) while (not self._pq.isEmpty()): v = self._pq.delMin() # add closest vertex to source to Tree if t and v == t: return self._relaxVertix(v)
def __init__(self, EG): self._edgeTo = [-1 for _ in range(EG.V())] self._distTo = [_INF for _ in range(EG.V()) ] self._distTo[0] = 0 self._pq = IndexMinPQ(EG.V()) self._mst = [] # list of edges in MST self._weight = 0 self._marked = set() # set of vertices in MST self._pq.insert(0, 0) while (not self._pq.isEmpty() and len(self._mst) < EG.V() - 1): v = self._pq.delMin() if v > 0: self._mst.append(self._edgeTo[v]) self._weight += self._edgeTo[v].weight() self._visit(EG, v)