Esempio n. 1
0
def Dijkstra_algorithm(graph: Graph,
                       starting_node: int) -> DijkstraAlgorithmResult:

    dist = [INFINITY for _ in range(graph.nodes_count)]
    prev = [None for _ in range(graph.nodes_count)]

    dist[starting_node] = 0
    prev[starting_node] = starting_node

    # prepare list of tuples of nodes labels with their starting distances
    dist_nodes = [
        PQNode(key=i, priority=dist[i]) for i in range(0, graph.nodes_count)
    ]

    Q = PriorityQueue(raw=dist_nodes)

    while not Q.is_empty:
        # pick the closest node
        fst = Q.pop().key
        for e in graph.get_neighbourhood(fst):
            # scan the neighbourhood
            snd = e.snd
            weight = e.weight
            if dist[snd] > dist[fst] + weight:
                # update if better route found
                dist[snd] = dist[fst] + weight
                prev[snd] = fst
                Q.bottom_bound_flatten_priority(snd, dist[snd])

    return DijkstraAlgorithmResult(dist=dist, prev=prev)
Esempio n. 2
0
def Prim(graph: Graph) -> Iterable[GraphEdge]:
    """Returns a MST using Prim's algorithm.
    """

    cost = [INFINITY for _ in range(graph.nodes_count)]
    prev = [None for _ in range(graph.nodes_count)]

    # take the first node as the starting node
    starting_node = 0

    cost[starting_node] = 0
    prev[starting_node] = starting_node

    # build a priority queue
    cost_nodes = [
        PQNode(key=i, priority=cost[i]) for i in range(0, graph.nodes_count)
    ]
    Q = PriorityQueue(raw=cost_nodes)

    while not Q.is_empty:
        fst = Q.pop().key
        for e in graph.get_neighbourhood(fst):
            snd = e.snd
            weight = graph.get_edge_weight(fst, snd, twoway=True)
            if cost[snd] > weight:
                cost[snd] = weight
                prev[snd] = fst
                Q.bottom_bound_flatten_priority(snd, cost[snd])

    # render out actual graph edges using the `prev` list
    mst = []
    for node in range(0, graph.nodes_count):
        if node == starting_node:
            continue
        mst.append(
            GraphEdge(prev[node], node,
                      graph.get_edge_weight(prev[node], node, twoway=True)))

    return mst