Exemple #1
0
def dijkstra(nodes, edges, weight, source):
    """Finds the shortest path from source to all nodes in the
    graph (nodes and edges), where the weight on edge (u, v) is
    given by weight(u, v). Assumes that all weights are
    non-negative.

    At the end of the algorithm:
    - node.visited is True if the node is visited, False otherwise.
    (Note: node is visited if shortest path to it is computed.)
    - node.distance is set to the shortest path length from source
        to node if node is visited, or not present otherwise.
    - node.parent is set to the previous node on the shortest path
        from source to node if node is visited, or not present otherwise.        

    Returns the number of visited nodes.
    """

    global heap, ID_to_node
    
    # Initialize.
    for node in nodes:
        node.marked = False # node is marked if it has been added to the heap.
        node.visited = False # node is visited if the shortest path from source
                             # to node is found (i.e., if removed from heap).
    num_visited = 0

    # create adjacency lists/edge sets
    create_adjacency_lists(nodes, edges)
    edge_set = create_edge_set(edges)

    # run dijkstra's algorithm.

    ID_to_node = {}
    heap = heap_id.heap_id()
    source.distance = 0
    _heap_insert(source)
    source.marked = True

    while(heap.heapsize > 0):
        current = _heap_extract_min()
        current.visited = True
        num_visited = num_visited + 1
        for node in current.adj: # Relax nodes adjacent to current.
            if not node.visited:
                new_distance = weight(current, node) + current.distance
                if node.marked:
                    if new_distance < node.distance:
                        node.distance = new_distance
                        _heap_decrease_key(node)
                        node.parent = current
                else:
                    node.distance = new_distance
                    _heap_insert(node)
                    node.marked = True
                    node.parent = current

    
    return num_visited
Exemple #2
0
def dijkstra_with_max_potentials(nodes, edges, weight, source, destination):
    """Performs Dijkstra's algorithm on a graph with weights modified
    according to the max-potentials method (with multiple landmarks),
    until it finds the shortest path from source to destination in the
    graph (nodes and edges), where the weight on edge (u, v) is given
    by weight(u, v). Assumes that all weights are non-negative.

    Assumes that node.land_distances is already computed for each node.

    At the end of the algorithm:
    - node.visited is True if the node is visited, False otherwise.
    (Note: node is visited if shortest path to it is computed.)
    - node.distance is set to the shortest path length from source
        to node if node is visited, or not present otherwise.
    - node.parent is set to the previous not on the shortest path
        from source to node if node is visited, or not present otherwise.        

    Returns the number of visited nodes.
    """

    global heap, ID_to_node
    
    # Initialize.
    for node in nodes:
        node.marked = False # node is marked if it has been added to the heap.
        node.visited = False # node is visited if the shortest path from source
                             # to node is found (i.e., if removed from heap).
    num_visited = 0

    # Now run dijkstra's algorithm.

    ID_to_node = {}
    heap = heap_id.heap_id()
    source.distance = 0
    _heap_insert(source)
    source.marked = True

    while(heap.heapsize > 0):
        current = _heap_extract_min()
        current.visited = True
        num_visited = num_visited + 1
        if current == destination:
            return num_visited
        for node in current.adj: # Relax nodes adjacent to current.
            if not node.visited:
                new_distance = weight(current, node) - max(current.land_distance) + max(node.land_distance) + current.distance
                if node.marked:
                    if new_distance < node.distance:
                        node.distance = new_distance
                        _heap_decrease_key(node)
                        node.parent = current
                else:
                    node.distance = new_distance
                    _heap_insert(node)
                    node.marked = True
                    node.parent = current

    return num_visited
Exemple #3
0
def shortest_path(nodes, edges, weight, s, t):
    G = {}  # Our graph representation, key: node, value: adj nodes
    D = {
    }  # Our distance table, key: node, value: estimated shortest path length
    for node in nodes:
        G[node] = []
        D[node] = math.inf  # set all distance estimates to infinity
    for link in edges:  # store all adjacent nodes in dict[node]
        G[link.begin].append(
            link.end)  # edges are undirected so we must store both
        G[link.end].append(link.begin)  # nodes in eachother's adjacency list

    D[s] = 0  # distance from source is 0

    queue = heap_id.heap_id()  # min heap
    Q = {
        queue.insert(0): s
    }  # Q keeps track of which id in the queue belongs to which node

    S = [s]  # list of nodes whose minimum cost has already been found

    pi = {s: -1}  # tracks our predecessors, key: node, value: previous node

    while queue.heapsize > 0 and t not in S:  # while we have nodes in the queue and t hasn't been visited
        min_with_id = queue.extract_min_with_id(
        )  # extract smallest est distance from queue
        u = Q[min_with_id[1]]  # use extracted id to access corresponding node

        for adj_node in G[u]:  # for each adjacent node
            v = adj_node
            dist = weight(u, v)  # get weight of edge between u, v

            if D[u] + dist < D[v] and v not in S:  # RELAX
                D[v] = D[u] + dist
                pi[v] = u  # store u as predecessor to v
                Q[queue.insert(D[v])] = v  # queue up v

        S.append(u)  # add u to visited nodes

    shortest_path = [
        t
    ]  # our shortest path begins with t, we will reverse this later
    while pi[shortest_path[-1]] != -1:  # while our predecessor is not -1
        shortest_path.append(
            pi[shortest_path[-1]])  # add predecessor of latest node in list

    shortest_path.reverse()  # reverse our path since we started with t
    return shortest_path
Exemple #4
0
def shortest_path(nodes, edges, weight, s, t):

    infinity = 1.7976931348623157e+308
    dist = [infinity] * len(nodes)

    previous = [None] * len(nodes)
    heap = heap_id.heap_id()
    # print nodes.index(s)
    dist[nodes.index(s)] = 0

    for i in range(len(dist)):
        heap.insert(dist[i])
    u = heap.extract_min_with_id()
    #print u[1]-1
    while heap.heapsize > 0:
        index_ID = u[1] - 1
        # print index_ID
        if dist[index_ID] == infinity:
            return []
        for edge in edges:
            if edge.begin == nodes[index_ID] or edge.end == nodes[index_ID]:
                if edge.begin == nodes[index_ID]:
                    begin = edge.begin
                    end = edge.end
                if edge.end == nodes[index_ID]:
                    begin = edge.end
                    end = edge.begin
                alt = u[0] + weight(begin, end)
                index_end = nodes.index(end)
                if alt < dist[index_end]:
                    dist[index_end] = alt
                    #print index_end

                    heap.decrease_key_using_id(index_end + 1, alt)
                    previous[index_end] = nodes[index_ID]
                    #print nodes[index_ID]
            if nodes[index_ID] == t:
                path = [t]
                p = previous[nodes.index(t)]
                while p != s:
                    path.append(p)
                    p = previous[nodes.index(p)]
                path.append(s)
                path.reverse()
                return path
        u = heap.extract_min_with_id()
def shortest_path(nodes, edges, weight, s, t):
    # http://docs.python.org/tutorial/datastructures.html
    """>>> tel = {'jack': 4098, 'sape': 4139}
    >>> tel['guido'] = 4127
    >>> tel
    {'sape': 4139, 'guido': 4127, 'jack': 4098}
    """
    # Create empty data storages of dictionaries
    adj_list = {}  # nodes and edges
    node_to_id = {}  # node to id reference
    id_to_node = {}  # id to node reference
    node_to_parent = {}  # node's parent reference
    node_to_key = {}  # node to heap key reference

    # heap_id object instance
    id_heap = heap_id.heap_id()

    for edge in edges:
        # beginning node to ending node
        if edge.begin in adj_list:
            adj_list[edge.begin].append(edge.end)
        else:
            adj_list[edge.begin] = [edge.end]
        # ending node to beginning node
        if edge.end in adj_list:
            adj_list[edge.end].append(edge.begin)
        else:
            adj_list[edge.end] = [edge.begin]

    # node to key reference dictionary
    for node in nodes:
        # parent node
        if node == s:
            id = id_heap.insert(0)
            node_to_key[node] = 0  # node_to key 0
            node_to_parent[node] = None  # no parent
        # child node
        else:
            id = id_heap.insert(
                heap_id.positive_infinity)  # hep_id positive_infinity()
            node_to_key[
                node] = heap_id.positive_infinity  # node_to key to positive_infinity
        # new references
        node_to_id[node] = id  #update node_to_id dictionary
        id_to_node[id] = node  #update id_to_node dictionary

    # check what nodes still left
    while node_to_id:
        ext_min_node = id_heap.extract_min_with_id(
        )  # extract min node use heap_id obj id_heap
        ext_min_node_node = id_to_node[ext_min_node[1]]  # node
        ext_min_node_key = ext_min_node[0]  # key
        # delete id for the ext min node
        del node_to_id[ext_min_node_node]
        # has outgoing edges ?
        if ext_min_node_node in adj_list:
            for idx in adj_list[ext_min_node_node]:  # loop thru the dictionary
                if ext_min_node_key != heap_id.positive_infinity:  # has a connected path to
                    # weight priority queue
                    if node_to_key[idx] > ext_min_node_key + weight(
                            ext_min_node_node, idx):
                        node_to_key[idx] = ext_min_node_key + weight(
                            ext_min_node_node, idx)
                        id_heap.decrease_key_using_id(
                            node_to_id[idx], node_to_key[idx])  # decrease key
                        node_to_parent[idx] = ext_min_node_node  # parent node

    # prepare for shortest path result
    result_list = []
    result_list.append(t)  # put destination into result
    node = t  # where t is destination

    # parent insertion
    while node_to_parent[
            node] is not None:  # 'is not None' is not equal to '!='
        result_list.insert(0, node_to_parent[node])  # node
        node = node_to_parent[node]  # parent

    return result_list