class LazyPrimMST: def __init__(self, g): self.pq = MinPQ() self.marked = [] self.mst = Queue() for i in range(g.v): self.marked.append(False) self.visit(g, 0) while not self.pq.is_empty(): e = self.pq.del_min() v = e.either() w = e.other(v) if self.marked[v] and self.marked[w]: continue self.mst.enqueue(e) if not self.marked[v]: self.visit(g, v) if not self.marked[w]: self.visit(g, w) def visit(self, g, v): self.marked[v] = True for e in g.adj[v]: if not self.marked[e.other(v)]: self.pq.insert(e)
class LazyPrimMST(object): ''' given a connected, undirected, weighted graph, finds an MST and its weight key = edge; priority = weight of edge delete-min to determine next edge to add to to Tree disregard if both endpoints v, w are in T if w is vertex not in T: 1. add w to T 2. add edge to T 3. add to PQ any edge incident to w (if other endpoint not in T) PQ has 1 entry per edge ''' def __init__(self, EG): self._marked = [False for _ in range(EG.V())] # MST vertices self._mst = [] # list of MST edges self._weight = 0 self._pq = MinPQ() # MinPQ of edges self._visit(EG, 0) while (not self._pq.isEmpty() and len(self._mst) < EG.V() - 1): e = self._pq.delMin() v = e.either() w = e.other(v) if (self._marked[v] and self._marked[w]): continue # edge is obsolete; both vertices are on Tree # add edge to MST list self._mst.append(e) self._weight += e.weight() # visit non-Tree vertex if (not self._marked[v]): self._visit(EG, v) if (not self._marked[w]): self._visit(EG, w) def _visit(self, EG, v): "add v to Tree; add each edge e incident on v to PQ if e.other() is not in Tree" self._marked[v] = True for e in EG.adj(v): w = e.other(v) if (not self._marked[w]): self._pq.insert(e) 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 LazyPrimMST(object): ''' given a connected, undirected, weighted graph, finds an MST and its weight key = edge; priority = weight of edge delete-min to determine next edge to add to to Tree disregard if both endpoints v, w are in T if w is vertex not in T: 1. add w to T 2. add edge to T 3. add to PQ any edge incident to w (if other endpoint not in T) PQ has 1 entry per edge ''' def __init__(self, EG): self._marked = [False for _ in range(EG.V())] # MST vertices self._mst = [] # list of MST edges self._weight = 0 self._pq = MinPQ() # MinPQ of edges self._visit(EG, 0) while (not self._pq.isEmpty() and len(self._mst) < EG.V() - 1): e = self._pq.delMin() v = e.either(); w = e.other(v) if (self._marked[v] and self._marked[w]): continue # edge is obsolete; both vertices are on Tree # add edge to MST list self._mst.append(e) self._weight += e.weight() # visit non-Tree vertex if (not self._marked[v]): self._visit(EG, v) if (not self._marked[w]): self._visit(EG, w) def _visit(self, EG, v): "add v to Tree; add each edge e incident on v to PQ if e.other() is not in Tree" self._marked[v] = True for e in EG.adj(v): w = e.other(v) if (not self._marked[w]): self._pq.insert(e) 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 KruskalMST: def __init__(self, g): self.mst = Queue() self.pq = MinPQ() self.uf = UF(g.v) for e in g.edges: self.pq.insert(e) while not self.pq.is_empty() and self.mst.size() < g.v - 1: e = self.pq.del_min() v = e.either() w = e.other(v) if self.uf.connected(v, w): continue self.mst.enqueue(e) self.uf.union(v, w)
class KruskalMST(object): "Kruskal's algorithm" def __init__(self, EG): "given a connected, undirected, weighted graph, finds an MST and its weight" # list of edges in mst self._mst = [] self._weight = 0 # build priority queue of edges self._pq = MinPQ() for e in EG.edges(): self._pq.insert(e) # build union-find data structure uf = UF(EG.V()) while (not self._pq.isEmpty() and len(self._mst) < EG.V() - 1): # get next edge from PQ e = self._pq.delMin() # greedily add edges to MST v = e.either() w = e.other(v) if (not uf.isConnected(v, w)): # edge v-w does not create a cycle uf.union(v, w) # merge components self._mst.append(e) # add edge to MST self._weight += e.weight() def mst(self): "returns edges in MST" return self._mst def weight(self): "returns sum of weights of MST" return self._weight def __repr__(self): "Everything about MST" return "edges=%r wt=%r" % ([e for e in self.mst()], self.weight())