示例#1
0
def _dijkstra_adjacency_list(graph: Graph, start: str, target: str):
    V = len(graph.vertices)
    visited, dist, pred = {}, {}, {}
    for v in graph.vertices:
        visited[v] = False
        pred[v] = None
        if v != start:
            dist[v] = float('inf')
    dist[start] = 0
    pq = PriorityQueue(implementation='binomial_heap')
    for vertex in dist:
        pq.push(vertex, dist[vertex])
    for _ in range(V):
        u = pq.pop()
        visited[u] = True
        for v in graph.vertices:
            edge_str = u + '_' + v
            if (edge_str in graph.edge_weights and graph.edge_weights[edge_str].value > 0 and
                visited[v] is False and dist[v] > dist[u] + graph.edge_weights[edge_str].value):
                dist[v] = dist[u] + graph.edge_weights[edge_str].value
                pred[v] = u
                pq.push(v, dist[v])

    if target != "":
        return (dist[target], pred)
    return dist, pred
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 = dict()
    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