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
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
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
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