def _minimum_spanning_tree_kruskal_adjacency_matrix(graph): mst = Graph(*[getattr(graph, str(v)) for v in graph.vertices]) sort_key = lambda item: item[1].value dsf = DisjointSetForest() for v in graph.vertices: dsf.make_set(v) for _, edge in sorted(graph.edge_weights.items(), key=sort_key): u, v = edge.source.name, edge.target.name if dsf.find_root(u) is not dsf.find_root(v): mst.add_edge(u, v, edge.value) dsf.union(u, v) return mst
def _minimum_spanning_tree_parallel_prim_adjacency_list(graph, num_threads): q = [ PriorityQueue(implementation='binomial_heap') for _ in range(num_threads) ] e = [dict() for _ in range(num_threads)] v2q = dict() mst = Graph(implementation='adjacency_list') itr = iter(graph.vertices) for i in range(len(graph.vertices)): v2q[next(itr)] = i % len(q) q[0].push(next(iter(graph.vertices)), 0) while True: _vs = [None for _ in range(num_threads)] with ThreadPoolExecutor(max_workers=num_threads) as Executor: for i in range(num_threads): Executor.submit(_find_min, q[i], _vs, i).result() v = None for i in range(num_threads): if _comp(_vs[i], v, lambda u, v: u.key < v.key): v = _vs[i] if v is None: break v = v.data idx = v2q[v] q[idx].pop() if not hasattr(mst, v): mst.add_vertex(graph.__getattribute__(v)) if e[idx].get(v, None) is not None: edge = e[idx][v] mst.add_vertex(edge.target) mst.add_edge(edge.source.name, edge.target.name, edge.value) mst.add_edge(edge.target.name, edge.source.name, edge.value) for w_node in graph.neighbors(v): w = w_node.name vw = graph.edge_weights[v + '_' + w] j = v2q[w] q[j].push(w, vw.value) if e[j].get(w, None) is None or \ e[j][w].value > vw.value: e[j][w] = vw return mst
def _minimum_spanning_tree_prim_adjacency_list(graph): q = PriorityQueue(implementation='binomial_heap') e = {} mst = Graph(implementation='adjacency_list') q.push(next(iter(graph.vertices)), 0) while not q.is_empty: v = q.pop() if not hasattr(mst, v): mst.add_vertex(graph.__getattribute__(v)) if e.get(v, None) is not None: edge = e[v] mst.add_vertex(edge.target) mst.add_edge(edge.source.name, edge.target.name, edge.value) mst.add_edge(edge.target.name, edge.source.name, edge.value) for w_node in graph.neighbors(v): w = w_node.name vw = graph.edge_weights[v + '_' + w] q.push(w, vw.value) if e.get(w, None) is None or e[w].value > vw.value: e[w] = vw return mst