def sum_costs(G, path, impedance): """ This function calculates the sum of the costs of a path created according to the geographic scenario graph. :param G: NetworkX graph. Geographic scenario :param path: list The list must contains the id of nodes of the path. :param weight: String or function :return: float The sum of all cost (weight) edges of the path. """ weight = Graph._weight(G, impedance) sum_costs = 0 for i in range(len(path) - 1): e = G.adj[path[i]].get(path[i + 1]) weight_edge = weight(path[i], path[i + 1], e) sum_costs += weight_edge return sum_costs
def bellman_ford(G, initial_node, target_node, weight): weight = Graph._weight(G, weight) distance, route = nx.single_source_bellman_ford(G, initial_node, target_node, weight) return distance, route
def bidirectional_dijkstra(G, initial_node, target_node, weight): weight = Graph._weight(G, weight) print("dij", initial_node, target_node) distance, route = nx.bidirectional_dijkstra(G, initial_node, target_node, weight) return distance, route
def _shortest_path_faster(G, source, weight): """ This function returns the single-source shortest path in weighted directed graph based on Shortest Path Faster Algorithm (SPFA). It is an improvement of the Bellman– Ford algorithm. The pseudocode of the SPFA: https://en.wikipedia.org/wiki/Shortest_Path_Faster_Algorithm :param G: NetworkX graph. input graph :param source: Float Id of the start node :param target: Float Id of the goal node :param weight: Function :return: List List with all nodes of the shortest path """ weight = Graph._weight(G, weight) last_edge = {source: (None, None)} pred_edge = {source: None} source = [source] q = deque(source) G_adjacents = G.succ if G.is_directed() else G.adj n_G = len(G_adjacents) count = {} dist = {} parent = {} inf = float("inf") # Initialization for i in G.nodes: dist.update([(i, inf)]) parent.update([(i, None)]) dist.update([(source[0], 0)]) while q: u = q.popleft() # for each edge between the node u and their adjacent nodes for v, e in G_adjacents[u].items(): # Relaxing new_dist_v = dist.get(u) + weight(u, v, e) if new_dist_v < dist.get(v): if v in last_edge[u]: print("Error: Negative cost cycle.") return False if v in pred_edge and pred_edge[v] == u: last_edge[v] = last_edge[u] else: last_edge[v] = (u, v) dist.update([(v, new_dist_v)]) parent.update([(v, u)]) if v not in q: q.append(v) count_v = count.get(v, 0) + 1 if count_v == n_G: print("Error: Negative cost cycle") return False count[v] = count_v pred_edge[v] = u return dist, parent
if __name__ == '__main__': G = ox.graph_from_bbox(-22.796008, -22.843953, -47.054891, -47.107718000000006, network_type='all') stop_points = [(-22.820204, -47.085525), (-22.825029, -47.068495), (-22.824376, -47.070952), (-22.82503, -47.07410), (-22.82504, -47.07730), (-24.992554, -47.069115)] # (-22.816008, -47.075614)] # fig1, ax1 = ox.plot_graph(G, node_size=5, edge_color='#333333', bgcolor='k') # Graph.save_graph_file(G, '../' + MAPS_DIRECTORY, 'test1') weigths = { (-22.816639, -47.074891): (50, 'Kg'), (-22.818317, -47.083415): (30, 'Kg'), (-22.820244, -47.085422): (15, 'Kg'), (-22.823953, -47.087718): (12, 'Kg') } G, nodes_collect_and_coordinates, nodes_collect_and_weights = add_collect_points( G, stop_points, weigths) G = Graph.set_node_elevation(G, '../' + MAPS_DIRECTORY + '22S48_ZN.tif') G = Graph.edge_grades(G) Graph.save_graph_file(G, '../' + MAPS_DIRECTORY, 'test.graphml') # Graph.plot_graph(G) weight = Graph._weight(G, 'weight') distance, route = nx.bidirectional_dijkstra(G, 1000000002, 1000000011, weight) print(route)