class PrimMSTEager: def __init__(self, edge_weighted_graph): self.__EWG = edge_weighted_graph self.__distance_to = dict() self.__edge_to = dict() self.__min_pq = MinPQ() self.__mst_vertices = dict() for v in self.__EWG.get_vertices(): self.__mst_vertices[v] = False self.__build() def weight(self): sum = 0 for distance in self.__distance_to.values(): sum += distance return sum def edges(self): return self.__edge_to.values() def __build(self): v = self.__EWG.get_vertices()[0] # v = '0' self.__distance_to[v] = 0 self.__mst_vertices[v] = True for adjacent in self.__EWG.adj(v): w = adjacent.other(v) self.__min_pq.insert(adjacent.weight(), adjacent) self.__distance_to[w] = adjacent.weight() self.__edge_to[w] = adjacent while not self.__min_pq.is_empty(): edge = self.__min_pq.del_min() if not self.__mst_vertices.get(edge.either()): v = edge.either() self.__mst_vertices[v] = True elif not self.__mst_vertices.get(edge.other(edge.either())): v = edge.other(edge.either()) self.__mst_vertices[v] = True if v is None: continue for adjacent in self.__EWG.adj(v): w = adjacent.other(v) if w == self.__EWG.get_vertices()[0]: continue weight = adjacent.weight() if not self.__distance_to.get(w): self.__distance_to[w] = weight self.__edge_to[w] = adjacent self.__min_pq.insert(weight, adjacent) elif weight < self.__distance_to.get( w) and not self.__mst_vertices.get(w): self.__distance_to[w] = weight self.__edge_to[w] = adjacent self.__min_pq.insert(weight, adjacent)
class PrimMSTLazy: def __init__(self, edge_weighted_graph): self.__EWG = edge_weighted_graph self.__MST_vertices = dict() self.__MST_edges = list() self.__min_pq = MinPQ() for vertex in self.__EWG.get_vertices(): self.__MST_vertices[vertex] = False self.__build() def edges(self): return self.__MST_edges def weight(self): total_weight = 0 for edge in self.__MST_edges: total_weight += edge.weight() return total_weight def __build(self): v = self.__EWG.get_vertices()[0] # v = '0' self.__MST_vertices[v] = True # print self.__EWG.adj(v) for adjacent in self.__EWG.adj(v): self.__min_pq.insert(adjacent.weight(), adjacent) while not self.__min_pq.is_empty(): edge = self.__min_pq.del_min() v = edge.either() w = edge.other(v) if self.__MST_vertices.get(v) and not self.__MST_vertices.get(w): self.__MST_vertices[w] = True self.__MST_edges.append(edge) for adjacent in self.__EWG.adj(w): if not adjacent.same_edge(edge): self.__min_pq.insert(adjacent.weight(), adjacent) elif self.__MST_vertices.get(w) and not self.__MST_vertices.get(v): self.__MST_vertices[v] = True self.__MST_edges.append(edge) for adjacent in self.__EWG.adj(v): if not adjacent.same_edge(edge): # filter self.__min_pq.insert(adjacent.weight(), adjacent)
class DijkstraSP: def __init__(self, edge_weighted_digraph, source): self.edge_to = dict() self.dist_to = dict() self.relaxed_vertices = dict() self.min_pq = MinPQ() self.EWD = edge_weighted_digraph self.source = source for vertex in self.EWD.get_vertices(): self.dist_to[vertex] = float("inf") self.dist_to[source] = 0 self.relax_vertex(self.source) self.build() for vertex, edge in self.edge_to.items(): print vertex, ' : ', edge.to_string() print self.dist_to # def has_path_to(self, node): # return def build(self): while not self.min_pq.is_empty(): v = self.min_pq.del_min() if not self.relaxed_vertices.get(v): self.relax_vertex(v) def has_path_to(self, vertex): return self.dist_to.get(vertex) != float('inf') def path_to(self, vertex): if self.has_path_to(vertex): path = list() vertex = str(vertex) edge = self.edge_to.get(vertex) From = edge.From() To = edge.To() while From != self.source: path.insert(0, To) edge = self.edge_to.get(From) From = edge.From() To = edge.To() path.insert(0, To) path.insert(0, self.source) return path else: return def relax_vertex(self, v): self.relaxed_vertices[v] = True if self.EWD.adj(v) is not None: for edge in self.EWD.adj(v): self.relax_edge(edge) def relax_edge(self, edge): To = edge.To() From = edge.From() # print edge.weight()+ self.dist_to.get(From) # print self.dist_to.get(To) if edge.weight() + self.dist_to.get(From) < self.dist_to.get(To): self.edge_to[To] = edge self.dist_to[To] = edge.weight() + self.dist_to[From] self.min_pq.insert(self.dist_to.get(To), To)