Example #1
0
def __shortest_path_lengths_noinf(g, src):
    """Compute shortest-path distances from src to reachable vertices of g
    without python inf notation."""
    dist = {}  # dist[v] is upper bound from s to v
    cloud = {}  # map reachable v to its dist[v] value
    pq = AdaptableHeapPriorityQueue()  # vertex v will have key dist[v]
    pq_locator = {}  # map from vertex to its pq locator

    dist[src] = 0
    pq_locator[src] = pq.add(0, src)
    while not pq.is_empty():
        key, u = pq.remove_min()
        cloud[u] = key  # its correct dist[u] value
        del pq_locator[u]  # u is no longer needed
        for edge in g.incident_edges(u):  # outgoing edges (u, v)
            v = edge.opposite(u)
            if v not in cloud:
                # perform relaxation step on edge (u, v)
                new_dist = dist[u] + edge.element()
                if v not in dist:
                    # add an vertex to dist until after an edge reaches it
                    dist[v] = new_dist
                    # and add it to the priority queue and save locator for
                    # future updates
                    pq_locator[v] = pq.add(new_dist, v)
                elif dist[v] > new_dist:  # If better path to v exists...
                    dist[v] = new_dist  # update the distance, and...
                    pq.update(pq_locator[v], new_dist, v)  # the pq entry
    # Now, dist and cloud are the same, they both only include the reachable
    # vertices.
    return cloud
Example #2
0
def MST_PrimJarnik(g):  # O((n+m)logn)
    """Compute a minimum spanning tree of simple connected weighted graph g.

    Return a list of edges that comprise the MST (in arbitrary order).
    """
    dist = {}  # dist[v] is bound on distance to tree
    tree = []  # list of edges in spanning tree
    pq = AdaptableHeapPriorityQueue()  # dist[v] maps to value (v, e=(u, v))
    pq_locator = {}  # map from vertex to its pq locator

    # for each vertex v of the graph, add an entry to the priority queue,
    # with the source having distance 0 and all others having infinite dist-
    # ance.
    for v in g.vertices():
        dist[v] = float("inf") if len(dist) > 0 else 0
        pq_locator[v] = pq.add(dist[v], (v, None))

    while not pq.is_empty():
        _, (u, edge) = pq.remove_min()  # unpack tuple from pq
        del pq_locator[u]  # u is no longer in pq
        if edge is not None:
            tree.append(edge)  # add edge to tree
        for link in g.incident_edges(u):
            v = link.opposite(u)
            if v in pq_locator:  # thus v not yet in tree
                # see if edge (u, v) better connects v to the growing tree
                wgt = link.element()
                if wgt < dist[v]:
                    dist[v] = wgt  # update the distance and ...
                    pq.update(pq_locator[v], wgt, (v, link))  # the pq entry
    return tree
Example #3
0
def __shortest_path_lengths_noinf(g, src):
    """Compute shortest-path distances from src to reachable vertices of g
    without python inf notation."""
    dist = {}    # dist[v] is upper bound from s to v
    cloud = {}    # map reachable v to its dist[v] value
    pq = AdaptableHeapPriorityQueue() # vertex v will have key dist[v]
    pq_locator = {}    # map from vertex to its pq locator

    dist[src] = 0
    pq_locator[src] = pq.add(0, src)
    while not pq.is_empty():
        key, u = pq.remove_min()
        cloud[u] = key      # its correct dist[u] value
        del pq_locator[u]   # u is no longer needed
        for edge in g.incident_edges(u):    # outgoing edges (u, v)
            v = edge.opposite(u)
            if v not in cloud:
                # perform relaxation step on edge (u, v)
                new_dist = dist[u] + edge.element()
                if v not in dist:
                    # add an vertex to dist until after an edge reaches it
                    dist[v] = new_dist
                    # and add it to the priority queue and save locator for
                    # future updates
                    pq_locator[v] = pq.add(new_dist, v)
                elif dist[v] > new_dist:    # If better path to v exists...
                    dist[v] = new_dist      # update the distance, and...
                    pq.update(pq_locator[v], new_dist, v)  # the pq entry
    # Now, dist and cloud are the same, they both only include the reachable
    # vertices.
    return cloud
Example #4
0
def __shortest_path_lengths_inf(g, src):
    """Compute shortest-path distances from src to reachable vertices of g
    with python inf notation."""

    dist = {}  # dist[v] is upper bound from s to v
    cloud = {}  # map reachable v to its dist[v] value
    pq = AdaptableHeapPriorityQueue()  # vertex v will have key dist[v]
    pq_locator = {}  # map from vertex to its pq locator

    # for each vertex v of the graph, add an entry to the priority queue, with
    # the source having distance 0 and all others having infinite distance
    for v in g.vertices():
        if v is src:
            dist[v] = 0
        else:
            dist[v] = float('inf')  # syntax for positive infinity
        pq_locator[v] = pq.add(dist[v], v)  # save locator for future updates

    while not pq.is_empty():
        key, u = pq.remove_min()
        cloud[u] = key  # its correct dist[u] value
        del pq_locator[u]  # u is no longer in pq
        for e in g.incident_edges(u):  # outgoing edges (u,v)
            v = e.opposite(u)
            if v not in cloud:
                # perform relaxation step on edge (u,v)
                wgt = e.element()
                if dist[u] + wgt < dist[v]:  # better path to v?
                    dist[v] = dist[u] + wgt  # update the distance, and
                    pq.update(pq_locator[v], dist[v], v)  # the pq entry

    return cloud  # only includes reachable vertices
Example #5
0
File: mst.py Project: storypku/tlpi
def MST_PrimJarnik(g):  # O((n+m)logn)
    """Compute a minimum spanning tree of simple connected weighted graph g.

    Return a list of edges that comprise the MST (in arbitrary order).
    """
    dist = {}   # dist[v] is bound on distance to tree
    tree = []   # list of edges in spanning tree
    pq = AdaptableHeapPriorityQueue()   # dist[v] maps to value (v, e=(u, v))
    pq_locator = {} # map from vertex to its pq locator

    # for each vertex v of the graph, add an entry to the priority queue,
    # with the source having distance 0 and all others having infinite dist-
    # ance.
    for v in g.vertices():
        dist[v] = float("inf") if len(dist) > 0 else 0
        pq_locator[v] = pq.add(dist[v], (v, None))

    while not pq.is_empty():
        _, (u, edge) = pq.remove_min()  # unpack tuple from pq
        del pq_locator[u]               # u is no longer in pq
        if edge is not None:
            tree.append(edge)           # add edge to tree
        for link in g.incident_edges(u):
            v = link.opposite(u)
            if v in pq_locator: # thus v not yet in tree
                # see if edge (u, v) better connects v to the growing tree
                wgt = link.element()
                if wgt < dist[v]:
                    dist[v] =  wgt          # update the distance and ...
                    pq.update(pq_locator[v], wgt, (v, link)) # the pq entry
    return tree
Example #6
0
def __shortest_path_lengths_inf(g, src):
    """Compute shortest-path distances from src to reachable vertices of g
    with python inf notation."""

    dist = {}                         # dist[v] is upper bound from s to v
    cloud = {}                        # map reachable v to its dist[v] value
    pq = AdaptableHeapPriorityQueue() # vertex v will have key dist[v]
    pq_locator = {}                   # map from vertex to its pq locator

    # for each vertex v of the graph, add an entry to the priority queue, with
    # the source having distance 0 and all others having infinite distance
    for v in g.vertices():
        if v is src:
            dist[v] = 0
        else:
            dist[v] = float('inf')          # syntax for positive infinity
        pq_locator[v] = pq.add(dist[v], v)  # save locator for future updates

    while not pq.is_empty():
        key, u = pq.remove_min()
        cloud[u] = key                  # its correct dist[u] value
        del pq_locator[u]               # u is no longer in pq
        for e in g.incident_edges(u):   # outgoing edges (u,v)
            v = e.opposite(u)
            if v not in cloud:
                # perform relaxation step on edge (u,v)
                wgt = e.element()
                if dist[u] + wgt < dist[v]:         # better path to v?
                    dist[v] = dist[u] + wgt         # update the distance, and
                    pq.update(pq_locator[v], dist[v], v)        # the pq entry

    return cloud      # only includes reachable vertices