def LabelFeature(self, graph): # for each graph # pick a random source and a random target # run each of the networkx src tgt shortest path algorithms one by one # time how long they each take # repeat for N different srcs/tgts # find the average time for each algorithm # make the label for that graph the one with the shortest time # feature key: 0 = dijkstra, 1 = bidijkstra 2 = astar numIters = 10 n = networkx.number_of_nodes(graph) dijkstraTimes = np.zeros(numIters) biDijkstraTimes = np.zeros(numIters) aStarTimes = np.zeros(numIters) for i in xrange(numIters): # pick a random source and target src = np.random.randint(0, n) + 1 tgt = np.random.randint(0, n) + 1 while tgt == src: tgt = np.random.randint(0, n) + 1 dijkstraTime = time.time() try: networkx.dijkstra_path(graph, src, tgt) except: # no path found i -= 1 continue dijkstraTime = time.time() - dijkstraTime dijkstraTimes[i] = dijkstraTime biDijkstraTime = time.time() networkx.bidirectional_dijkstra(graph, src, tgt) biDijkstraTime = time.time() - biDijkstraTime biDijkstraTimes[i] = biDijkstraTime aStarTime = time.time() networkx.astar_path(graph, src, tgt) aStarTime = time.time() - aStarTime aStarTimes[i] = aStarTime meanDijkstra = np.mean(dijkstraTimes) meanBiDijkstra = np.mean(biDijkstraTimes) meanAStar = np.mean(aStarTimes) minTime = min(meanDijkstra, meanBiDijkstra, meanAStar) if meanDijkstra == minTime: label = 0 elif meanBiDijkstra == minTime: label = 1 else: label = 2 return label
def find_path(n1, n2, skip = []): start = time.time() path = None status = 'ok' a1 = find_artist(n1) a2 = find_artist(n2) if not a1: status = "Can't find " + n1 if not a2: status = "Can't find " + n2 if a1 and a2: if skip and len(skip) > 0: # graph = G.copy() graph = G else: graph = G remove_nodes(graph, skip) try: l, path = nx.bidirectional_dijkstra(graph, a1['id'], a2['id'], 'weight') except nx.NetworkXNoPath: status = 'No path found between ' + n1 + " and " + n2; restore_nodes(graph, skip) print 'find_path took %s seconds' % (time.time() - start,) return status, path
def traceEndpoints(self, key=0): """Uses the bidirectional dijkstra to traceback the paths from the endpoints""" og = nx.DiGraph(spacing=None, origin=None, orientation=None) self._populateImageFeaturesToGraph(og) currentRoot = self.roots[(self.currentGraphKey,key)] og.graph["root"] = currentRoot endpoints = self.endpoints[self.currentGraphKey] bifurcations = self.bifurcations[self.currentGraphKey] cg = self.graphs[self.currentGraphKey] if( self.VERBOSE ): print("current root is",currentRoot) for e in endpoints: plen, path = nx.bidirectional_dijkstra(cg, currentRoot, e) i = 0 start = currentRoot path = path[1:] while( path ): try: if( path[i] in bifurcations ): og.add_edge(start,path[i],path=path[:i]) start = path[i] path = path[i+1:] i = 0 else: i += 1 except IndexError: og.add_edge(start,e,{'path':path[:-1]}) path = None self.orderedGraphs[(self.currentGraphKey,key)] = og
def set_random_loads(max_for_each_route): scheme_len = len(SystemBuilder.scheme.node) for route in SystemBuilder.routes: for k in range(int(random() * max_for_each_route)): dispatch_st_num = route.route_list[int(random() * route.length())] destination_is_founded = False counter = 0 while not destination_is_founded: counter += 1 assert counter < 999 destination_st_num = int(random() * scheme_len) + 1 try: way_length, way_list = nx.bidirectional_dijkstra( SystemBuilder.routes_scheme, dispatch_st_num, destination_st_num) new_growth_coeff = GrowthCoeff(RandomFunctions.growth_coef_func(), way_list) destination_is_founded = True SystemBuilder.growth_coeffs.append(new_growth_coeff) attr_name = SystemBuilder.ATTRIBUTE_GROWTH_LIST SystemBuilder.scheme.node[dispatch_st_num][attr_name].append(new_growth_coeff) except nx.exception.NetworkXError: pass except nx.exception.NetworkXNoPath: pass
def getPath(self, nd0, nd1, weight_name): try: _, nodes = networkx.bidirectional_dijkstra( self.digraph, nd0, nd1, weight_name ) except networkx.NetworkXNoPath: raise NoPath('no path found between the points') def getKey(u, v): keys = [] for k in self.digraph[u][v]: weight = self.digraph[u][v][k][weight_name] keys.append((weight, k)) keys.sort() return keys[0][1] keys = [] for a, b in zip(nodes[:-1], nodes[1:]): k = getKey(a,b) keys.append(k) return nodes, keys
def _areConnected(self, minkey1, minkey2): try: ret = nx.bidirectional_dijkstra(self.graph, minkey1, minkey2) if ret != None: return True else: return False except nx.NetworkXNoPath: return False
def findNeighbours(src, dest): G = nx.Graph() db = MySQLdb.connect(host = "localhost", user = "******", passwd = "", db = "project") cursor = db.cursor() cursor.execute("SELECT * FROM nodes") for row in cursor.fetchall(): G.add_node(int(row[0])) cursor.execute("SELECT * FROM lanes") for row in cursor.fetchall(): G.add_edge(int(row[1]), int(row[2])) G[row[1]][row[2]]['weight'] = row[3] print G.edges() print G.nodes() query = "SELECT node_id FROM locations WHERE name like '" + src + "'" cursor.execute(query) try: fetch = cursor.fetchall() source = fetch[0][0] query = "SELECT node_id FROM locations WHERE type = '" + dest + "'" print query cursor.execute(query) results = cursor.fetchall() print results F = [] for x in results: temp = nx.bidirectional_dijkstra(G, source, int(x[0]), weight = 'weight') F.append(temp) maxval = min(F[0:]) index = [] for ctr in range(len(F)): if F[ctr][0] == maxval[0]: index.append(ctr) cursor.execute("SELECT nodes.node_id, nodes.x, nodes.y, name from nodes left join locations on nodes.node_id = locations.node_id") results = cursor.fetchall() Pathlist = [] for y in index: A = [] for x in F[y][1]: for row in results: if x == row[0]: A.append((row[1],row[2],row[3])) Pathlist.append(A) return Pathlist except: print "Invalid Query" return []
def areConnected(self, min1, min2): return self.connected_components.areConnected(min1, min2) try: ret = nx.bidirectional_dijkstra(self.graph, min1, min2) if ret != None: return True else: return False except nx.NetworkXNoPath: return False
def get_distance(self,source,sink): """ find shortest path length """ minDistance = 1e8 if self.G.has_node(source) and self.G.has_node(sink): (dijkDist, dijkPath) = nx.bidirectional_dijkstra(self.G,source,sink) return dijkDist return None
def _search_grammer_path(self, pos_via_point): pos_via_and_end = (self.START_NODE,) + pos_via_point + (self.END_NODE,) paths = [] cost = 0 for network_start_end in sliding_window(2, pos_via_and_end): path = networkx.bidirectional_dijkstra(self._grammer_graph, network_start_end[0], network_start_end[1]) cost += path[0] node_path = path[1][1:] paths += node_path paths.pop() return cost, paths
def qfind(a1, a2): start = time.time() path = None if a1 and a2: graph = G try: l, path = nx.bidirectional_dijkstra(graph, a1['id'], a2['id'], 'weight') except nx.NetworkXNoPath: pass return path
def path(self, source_name, target_name, skipset=set()): def get_weight(src, dest, attrs): if src in skipset or dest in skipset: # print "gw", srx, dest, attrs, 10000 return 10000 # print "gw", src, dest, attrs, 1 return attrs['weight'] results = { 'status': 'ok' } if len(source_name) == 0: results['status'] = 'error' results['reason'] = "No artist given" else: source_aid = self.search(source_name) if source_aid == None: results['status'] = 'error' results['reason'] = "Can't find " + source_name target_aid = self.search(target_name) if target_aid == None: results['status'] = 'error' results['reason'] = "Can't find " + target_name print "s=t", source_aid, target_aid if source_aid not in self.G: results['status'] = 'error' results['reason'] = "Can't find " + source_name + " in the artist graph" if target_aid not in self.G: results['status'] = 'error' results['reason'] = "Can't find " + target_name + " in the artist graph" if source_aid and target_aid and results['status'] == 'ok': start = time.time() if len(skipset) > 0: rpath = nx.dijkstra_path(self.G, source_aid, target_aid, get_weight) score = len(rpath) else: score, rpath = nx.bidirectional_dijkstra(self.G, source_aid, target_aid) pdelta = time.time() - start results['score'] = score populated_path = [self.get_artist(aid) for aid in rpath] fdelta = time.time() - start results['status'] = 'ok' results['raw_path'] = rpath results['path'] = populated_path results['pdelta'] = pdelta * 1000 results['fdelta'] = fdelta * 1000 return results
def _dijkstra(self, verbose, debug): try: if verbose: print('Dijkstra algorithm', flush=True) length,triPath=nx.bidirectional_dijkstra(self._tGraph, self._startTriplet, self._endTriplet) except (nx.NetworkXNoPath, nx.NetworkXError): print('ERROR: Impossible to find a path') triPath = [] return triPath
def get_best_path (init_dest, final_dest): DG = makeDiGraph() x= findCommonRoutes(init_dest, final_dest, DG) # check if any common bus is active activeRoutes = isActive(x) if(len(activeRoutes) == 0): print "You are f****d, buddy. No active routes" else: print activeRoutes # TOTAL TIME incomplete !! total_time(x,init_dest, activeRoutes) best = (nx.bidirectional_dijkstra(DG, init_dest, final_dest , weight = 'edge_weight') ) print (best)
def mp_worker((source,sink,graphPath)): """ find shortest path length """ G = nx.read_gpickle(graphPath) minDistance = 1e8 if G.has_node(source) and G.has_node(sink): (dijkDist, dijkPath) = nx.bidirectional_dijkstra(G,source,sink) else: dijkDist = None if dijkDist: return [source,sink,dijkDist]
def build_random_routes(attempts_num, min_len): scheme_len = len(SystemBuilder.scheme.node) k = 0 while k < attempts_num: first_station_number = int(random() * scheme_len) + 1 second_station_number = int(random() * scheme_len) + 1 way_len, way_list = \ nx.bidirectional_dijkstra(SystemBuilder.scheme, first_station_number, second_station_number) if way_len >= min_len: way_list = way_list + way_list[::-1][1:] new_route = Route(way_list, RandomFunctions.launch_cost_func(way_list)) SystemBuilder.routes.append(new_route) k += 1 SystemBuilder._create_routes_scheme()
def test_bidirectional_dijkstra(self): assert_equal(nx.bidirectional_dijkstra(self.XG, "s", "v"), (9, ["s", "x", "u", "v"])) assert_equal(nx.bidirectional_dijkstra(self.G, "s", "v"), (2, ["s", "x", "v"])) assert_equal(nx.bidirectional_dijkstra(self.cycle, 0, 3), (3, [0, 1, 2, 3])) assert_equal(nx.bidirectional_dijkstra(self.cycle, 0, 4), (3, [0, 6, 5, 4])) assert_equal(nx.bidirectional_dijkstra(self.XG3, 0, 3), (15, [0, 1, 2, 3])) assert_equal(nx.bidirectional_dijkstra(self.XG4, 0, 2), (4, [0, 1, 2])) # need more tests here assert_equal(nx.dijkstra_path(self.XG, "s", "v"), nx.single_source_dijkstra_path(self.XG, "s")["v"])
def obj_get_list(self, bundle, **kwargs): from_id = int(bundle.request.GET.get('from_id', -1)) to_id = int(bundle.request.GET.get('to_id', -1)) if from_id != -1 and to_id != -1: from_building = Building.objects.get(id=from_id) to_building = Building.objects.get(id=to_id) node_from_id = from_building.centroid_id node_to_id = to_building.centroid_id lz = LazyGraph() length, path = nx.bidirectional_dijkstra(lz.get_graph(), node_from_id, node_to_id, weight='weight') return [Node.objects.get(id=x) for x in path] return []
def quickest_route(self, source, target, est_time=7200): """ INPUT: source node 'stopid_timestamp' (a stop_timepoint string) target node stop_id estimated trip time in seconds OUTPUT: path_time (seconds), path (list of stop_timepoints) """ t1 = source[-8:] p_t, p = None, None for n in self.schedule.all_stop_timepoints[target][::-1]: t2 = n[-8:] if (t2 > t1) and (ut.diff_timestamps(t1, t2) < est_time): try: p_t, p = nx.bidirectional_dijkstra(self.G, source, n, weight='bees') except nx.NetworkXNoPath: return p_t, p
def hop_counts(graph, cutoff = None, samples = 100000): """ Calculating the length (in number of hops) with nodes using dijkstra algorithm. The input graph will be automaically turned into an undirected simple graph without loops. Note the function only focus on the largest connected component if graph is disconnected. To reduce the computation complexity, sampling method is used by default. Can use the argument 'samples' to control the number of samples. Parameters: ----------- graph: Networkx Graph, NetworkX DiGraph, cutoff: integer or float, optional Depth to stop search. Only paths of length <= cutoff are counted samples: int The number of sampling node pairs in order If samples equals to 0, then all pairs of nodes will be included. Returns: -------- a dictionary, keyed by hop count, of number of paths with specific hops """ graph = to_undirected(graph) from collections import Counter cnt = Counter() if samples > 0: def gen_pairs(p, n): """ generting the sampling node pairs. duplicated pairs is possible, but self loop is impossible """ import random random.seed() pairs = [ random.sample(p, 2) for s in xrange(n) ] return(pairs) pairs = gen_pairs(nx.connected_components(graph)[0], samples) pair_lens = map(lambda x: nx.bidirectional_dijkstra(graph, x[0], x[1], weight = None)[0], pairs) if cutoff: pair_lens = filter(lambda x: x <= cutoff, pair_lens) for pl in iter(pair_lens): cnt[pl] += 1 else: plDict = nx.all_pairs_dijkstra_path_length(graph, cutoff = cutoff) for p in plDict.itervalues(): for d in p.itervalues(): cnt[d] += 1 return(dict(cnt))
def obj_get_list(self, bundle, **kwargs): from_id = int(bundle.request.GET.get('from_id', -1)) to_id = int(bundle.request.GET.get('to_id', -1)) if from_id != -1 and to_id != -1: from_building = Building.objects.get(id=from_id) to_building = Building.objects.get(id=to_id) node_from_id = Node.objects.filter(building=from_building)[0].id node_to_id = Node.objects.filter(building=to_building)[0].id lz = LazyGraph() nd = lz.get_node_dict() length, path = nx.bidirectional_dijkstra(lz.get_graph(), from_id, to_id, weight='weight') return [nd[x] for x in path] return []
def shortest_path(source, target, transfer, lines, option="dijkstra"): """Find shortest path, using given lines""" reduced_lines = dict() reduced_subway = nx.Graph() for line in transfer: reduced_lines[line] = lines[line] for l in reduced_lines.values(): for pair in pairwise(l.route): dist = np.linalg.norm([pair[0].xy, pair[1].xy]) reduced_subway.add_edge(*pair, distance=dist) if option == "dijkstra": # least distance return nx.bidirectional_dijkstra(reduced_subway, source, target, weight="distance") else: # least stops return nx.bidirectional_shortest_path(reduced_subway, source, target)
def fast_shortestpath(R): ta1=time.time() length, path=nx.bidirectional_dijkstra(R.G,1,1000,weight='Fw') ta2=time.time() print 'bidirectional: ',ta2-ta1 print path ta1 = time.time() path=nx.dijkstra_path(R.G, 1, 1000, weight='Fw') ta2 = time.time() print 'single dijkstra_path: ', ta2 - ta1 print path ta1 = time.time() gen=R.get_pathsBetween_twonodes(1,1000,'Fw',1) (length, path)=gen.next() ta2 = time.time() print 'my dijkstra_path: ', ta2 - ta1 print path
def test_bidirectional_dijkstra(self): assert_equal(nx.bidirectional_dijkstra(self.XG, "s", "v"), (9, ["s", "x", "u", "v"])) (dist, path) = nx.bidirectional_dijkstra(self.G, "s", "v") assert_equal(dist, 2) # skip this test, correct path could also be ['s','u','v'] # assert_equal(nx.bidirectional_dijkstra(self.G,'s','v'), # (2, ['s', 'x', 'v'])) assert_equal(nx.bidirectional_dijkstra(self.cycle, 0, 3), (3, [0, 1, 2, 3])) assert_equal(nx.bidirectional_dijkstra(self.cycle, 0, 4), (3, [0, 6, 5, 4])) assert_equal(nx.bidirectional_dijkstra(self.XG3, 0, 3), (15, [0, 1, 2, 3])) assert_equal(nx.bidirectional_dijkstra(self.XG4, 0, 2), (4, [0, 1, 2])) # need more tests here assert_equal(nx.dijkstra_path(self.XG, "s", "v"), nx.single_source_dijkstra_path(self.XG, "s")["v"])
def findRoute(src,dest): G = nx.Graph() db = MySQLdb.connect(host = "localhost", user = "******", passwd = "", db = "project") cursor = db.cursor() cursor.execute("SELECT * FROM nodes") for row in cursor.fetchall(): G.add_node(int(row[0])) cursor.execute("SELECT * FROM lanes") for row in cursor.fetchall(): G.add_edge(int(row[1]), int(row[2])) G[row[1]][row[2]]['weight'] = row[3] print G.edges() print G.nodes() #src = raw_input("Enter source: ") #dest = raw_input("Enter destination: ") query = "SELECT node_id FROM locations WHERE name = '" + src + "' OR name = '" + dest +"'" cursor.execute(query) try: fetch = cursor.fetchall() source = fetch[0][0] destination = fetch[1][0] F = nx.bidirectional_dijkstra(G, source, destination, weight = 'weight') print F[1] A = [] cursor.execute("SELECT node_id, x, y from nodes") results = cursor.fetchall() for x in F[1]: for row in results: if x == row[0]: A.append((row[1],row[2])) return A except: print "Invalid Query" return []
def print_paths(g): #Mapeamento dos caminhos source = "H1" target = "H6" #Utiliza o algoritimo de Djisktra para a escolha do melhor caminho length, path = nx.bidirectional_dijkstra(g, source, target) #print "O menor caminho com base no weigth eh ", (path) #Cria a lista de todos os camihos possiveis para alcancar o destino #for paths in nx.all_simple_paths(g, source="H1", target="H6"): # all_paths = paths # print(all_paths) #Cria uma lista de TODOS os camihos possiveis de uma origem para alcancar um destino paths = nx.all_simple_paths(g, source, target) #print "\nLista de todos os caminhos ", (list(paths)) #print paths #Excessao para o caso do caminho nao ser encontrado try: path = nx.shortest_path(g, source, target) except: path = None if None == path: print "No route found!"
def test_bidirectional_dijkstra(self): assert_equal(nx.bidirectional_dijkstra(self.XG, 's', 'v'), (9, ['s', 'x', 'u', 'v'])) assert_equal(nx.bidirectional_dijkstra(self.G,'s','v'), (2, ['s', 'x', 'v'])) assert_equal(nx.bidirectional_dijkstra(self.cycle,0,3), (3, [0, 1, 2, 3])) assert_equal(nx.bidirectional_dijkstra(self.cycle,0,4), (3, [0, 6, 5, 4])) assert_equal(nx.bidirectional_dijkstra(self.XG3,0,3), (15, [0, 1, 2, 3])) assert_equal(nx.bidirectional_dijkstra(self.XG4,0,2), (4, [0, 1, 2])) # need more tests here assert_equal(nx.dijkstra_path(self.XG,'s','v'), nx.single_source_dijkstra_path(self.XG,'s')['v'])
def shortest_path(X, Y): b = nx.bidirectional_dijkstra(G, X, Y) c = G.nodes() d = list(set(c) - set(b[1])) x = G.edges() z = [] a = len(b[1]) for e in range(0, a - 1): z.append((b[1][e + 1], b[1][e])) z.append((b[1][e], b[1][e + 1])) w = list(set(x) - set(z)) labels = nx.get_edge_attributes(G, "weight") plt.figure(2) plt.title("Shortest Path Route") nx.draw_networkx(G, with_labels=True, pos=nx.spectral_layout(G)) nx.draw_networkx_nodes(G, pos=nx.spectral_layout(G), nodelist=b[1], node_color="b") nx.draw_networkx_nodes(G, pos=nx.spectral_layout(G), nodelist=d, node_color="g") nx.draw_networkx_edges(G, pos=nx.spectral_layout(G), edgelist=z, edge_color="b") nx.draw_networkx_edges(G, pos=nx.spectral_layout(G), edgelist=w, edge_color="g") nx.draw_networkx_edge_labels(G, pos=nx.spectral_layout(G), edge_labels=labels) plt.axis("off") plt.show()
def test_bidirectional_dijkstra(self): validate_length_path( self.XG, 's', 'v', 9, *nx.bidirectional_dijkstra(self.XG, 's', 'v')) validate_length_path( self.G, 's', 'v', 2, *nx.bidirectional_dijkstra(self.G, 's', 'v')) validate_length_path( self.cycle, 0, 3, 3, *nx.bidirectional_dijkstra(self.cycle, 0, 3)) validate_length_path( self.cycle, 0, 4, 3, *nx.bidirectional_dijkstra(self.cycle, 0, 4)) validate_length_path( self.XG3, 0, 3, 15, *nx.bidirectional_dijkstra(self.XG3, 0, 3)) validate_length_path( self.XG4, 0, 2, 4, *nx.bidirectional_dijkstra(self.XG4, 0, 2)) # need more tests here P = nx.single_source_dijkstra_path(self.XG, 's')['v'] validate_path(self.XG, 's', 'v', sum(self.XG[u][v]['weight'] for u, v in zip( P[:-1], P[1:])), nx.dijkstra_path(self.XG, 's', 'v'))
def createShortestPath(self, start, end, attachMode='near', minEdgeLen=0., maxEdgeLen=0., prune=True, optimizeVal='length'): if attachMode=='near': self._attachToGraphNear(start, end, prune) elif attachMode=='all': self._attachToGraphAll(start, end, prune) else: self._attachToGraphNear(start, end, prune) self._pathStart = start self._pathEnd = end if tuple(start) in self._graph.nodes(): self._graph.node[tuple(start)]['index'] = 's' if tuple(end) in self._graph.nodes(): self._graph.node[tuple(end)]['index'] = 'e' try: length,shortestPath=nx.bidirectional_dijkstra(self._graph, tuple(start), tuple(end)) except (nx.NetworkXNoPath, nx.NetworkXError): shortestPath = [] if (minEdgeLen > 0.) or (maxEdgeLen > 0.): i = 1 while (i<len(shortestPath)): a = np.array(shortestPath[i-1]) b = np.array(shortestPath[i]) if (np.linalg.norm(b-a) < minEdgeLen) and (i>1) and (i<len(shortestPath)-1): #don't adjust extremes shortestPath[i] = (0.5*a+0.5*b).tolist() shortestPath.pop(i-1) i = i-1 elif (np.linalg.norm(b-a) > maxEdgeLen): shortestPath.insert(i, (0.5*a+0.5*b).tolist()) else: i = i+1 return path.Path(np.array(shortestPath), self._scene, optimizeVal)
while len(pending_connections_x) > 0: max_idx = np.argmax(confidence_pending_connections) next_element_x = pending_connections_x[max_idx] next_element_y = pending_connections_y[max_idx] if ii > 0: previous_center_x = parent_connections_x[max_idx] previous_center_y = parent_connections_y[max_idx] tmp_center = (previous_center_x, previous_center_y) G = sp.generate_graph_center(img_idx, tmp_center) target_idx = 32 * 64 + 32 source_idx = (next_element_y - previous_center_y + 32) * 64 + next_element_x - previous_center_x + 32 length, path = nx.bidirectional_dijkstra(G, source_idx, target_idx) pos_y_vector = [] pos_x_vector = [] for jj in range(0, len(path)): row_idx = path[jj] / 64 col_idx = path[jj] % 64 global_x = col_idx + previous_center_x - 32 global_y = row_idx + previous_center_y - 32 if mask_graph[global_y, global_x] == 0: pos_y_vector.append(global_y) pos_x_vector.append(global_x) else: break if len(pos_y_vector) > 0:
def test_bidirectional_dijkstra_multigraph(self): G = nx.MultiGraph() G.add_edge("a", "b", weight=10) G.add_edge("a", "b", weight=100) dp = nx.bidirectional_dijkstra(G, "a", "b") assert dp == (10, ["a", "b"])
def build_shortcut_ghaph( node_path, road_node_options, road_graph, penalties=None ): if True: indexed_road_node_options = {} indexed_node_path = [] for node_index in range(len(node_path)): node = node_path[node_index] key = (node_index, node) value = [(node_index,) + option for option in road_node_options[node]] indexed_road_node_options[key] = value indexed_node_path.append(key) road_node_options = indexed_road_node_options node_path = indexed_node_path node_tuples = [ (node_path[i], node_path[i+1]) for i in range(len(node_path)-1) ] # Build the shortcut graph edges = [] for tuple_index in range(len(node_tuples)): origin, destination = node_tuples[tuple_index] product = list( itertools.product( road_node_options[origin], road_node_options[destination] ) ) edges += [p + (tuple_index,) for p in product] def penalty(node_road_node_tuple): if True: node_road_node_tuple = node_road_node_tuple[1:] if penalties: return penalties[node_road_node_tuple] else: return 0 weighted_edges = [] for edge_index in range(len(edges)): origin, destination, tuple_index = edges[edge_index] road_origin = origin[-1] road_destination = destination[-1] try: length, path = nx.bidirectional_dijkstra( road_graph, road_origin, road_destination ) except NetworkXNoPath: length, path = float('inf'), ['wrong'] length += penalty(origin) + penalty(destination) weighted_edge = ( origin, destination, length ) weighted_edges.append(weighted_edge) origin_options = road_node_options[node_path[0]] destination_options = road_node_options[node_path[-1]] assert origin_options and destination_options o_edges= [['origin', o, penalty(o)] for o in origin_options] d_edges = [[o, 'destination', penalty(o)]for o in destination_options] shortcut_graph = nx.DiGraph() shortcut_graph.add_weighted_edges_from( weighted_edges + o_edges + d_edges ) return shortcut_graph
G = nx.path_graph(N) else: G = None G = comm.bcast(G, root=0) x = range(int((rank * N) / size), int(((rank + 1) * N) / size)) print("I am processor", rank) lengths = [] sums = [] ccs = [] # doing dijkstra's for i in x: # print("Source:", i) for j in range(N): if nx.has_path(G, i, j): length, path = (nx.bidirectional_dijkstra(G, i, j)) lengths.append(length) sums.append(sum(lengths)) for j in sums: j = (N - 1) / j ccs.append(j) lengths.clear() cc_vals = comm.gather(ccs, root=0) end_time = time.time() if rank == 0: print(cc_vals, '\n') print("Time taken:", (end_time - start_time))
def find_output_connected_points_selected_point(root_dir, selected_vertex, train, img_idx, patch_size, center, img_filenames): if train: img_filename = img_filenames[img_idx] img = Image.open( os.path.join(root_dir, 'training', 'images', img_filename)) mask_filename = img_filename[0:len(img_filename) - 1] mask_gt = Image.open( os.path.join(root_dir, 'training', '1st_manual', mask_filename)) else: img_filename = img_filenames[img_idx] img = Image.open(os.path.join(root_dir, 'val', 'images', img_filename)) mask_filename = img_filename[0:len(img_filename) - 1] mask_gt = Image.open( os.path.join(root_dir, 'val', '1st_manual', mask_filename)) img = np.array(img, dtype=np.float32) h, w = img.shape[:2] void_pixels = np.prod((img == np.array([255, 255, 255])), axis=2).astype(np.float32) void_pixels_eroded = ndimage.binary_erosion( void_pixels, structure=np.ones((5, 5))).astype(void_pixels.dtype) void_pixels = ndimage.binary_dilation(void_pixels_eroded, structure=np.ones((5, 5))).astype( void_pixels_eroded.dtype) valid_pixels = 1 - void_pixels mask_gt = np.array(mask_gt) mask_gt_skeleton = skeletonize(mask_gt > 0) mask_gt_skeleton_valid = mask_gt_skeleton * valid_pixels valid_indxs = np.argwhere(mask_gt_skeleton_valid == 1) margin = int(np.round(patch_size / 10.0)) x_tmp = int(center[0] - patch_size / 2) y_tmp = int(center[1] - patch_size / 2) img_crop = img[y_tmp:y_tmp + patch_size, x_tmp:x_tmp + patch_size, :] #Find intersection points between skeleton and inner bbox from patch mask_gt_crop = mask_gt_skeleton_valid[y_tmp:y_tmp + patch_size, x_tmp:x_tmp + patch_size] bbox_mask = np.zeros((patch_size, patch_size)) bbox_mask[margin, margin:patch_size - margin] = 1 bbox_mask[margin:patch_size - margin, margin] = 1 bbox_mask[margin:patch_size - margin, patch_size - margin] = 1 bbox_mask[patch_size - margin, margin:patch_size - margin] = 1 intersection_bbox_with_gt = mask_gt_crop * bbox_mask #Discard intersection points not connected to the patch center G = generate_graph_patch(mask_gt_crop) idx_end = (patch_size / 2) * patch_size + patch_size / 2 intersection_idxs = np.argwhere(intersection_bbox_with_gt == 1) connected_intersection_idxs = [] for ii in range(0, len(intersection_idxs)): idx_start = intersection_idxs[ii, 0] * patch_size + intersection_idxs[ ii, 1] length_pred, path_pred = nx.bidirectional_dijkstra(G, idx_start, idx_end, weight='weight') if length_pred == 0: connected_intersection_idxs.append(intersection_idxs[ii]) output_points = np.asarray(connected_intersection_idxs) for ii in range(0, len(output_points)): tmp_value = output_points[ii, 0] output_points[ii, 0] = output_points[ii, 1] output_points[ii, 1] = tmp_value return img_crop, output_points
def find_output_connected_points(root_dir, save_vertices_indxs, train, img_idx, patch_size, img_filenames): if train: img_filename = img_filenames[img_idx] img = Image.open( os.path.join(root_dir, 'training', 'images', img_filename)) mask_filename = img_filename[0:len(img_filename) - 1] mask_gt = Image.open( os.path.join(root_dir, 'training', '1st_manual', mask_filename)) else: img_filename = img_filenames[img_idx] img = Image.open(os.path.join(root_dir, 'val', 'images', img_filename)) mask_filename = img_filename[0:len(img_filename) - 1] mask_gt = Image.open( os.path.join(root_dir, 'val', '1st_manual', mask_filename)) img = np.array(img, dtype=np.float32) h, w = img.shape[:2] void_pixels = np.prod((img == np.array([255, 255, 255])), axis=2).astype(np.float32) void_pixels_eroded = ndimage.binary_erosion( void_pixels, structure=np.ones((5, 5))).astype(void_pixels.dtype) void_pixels = ndimage.binary_dilation(void_pixels_eroded, structure=np.ones((5, 5))).astype( void_pixels_eroded.dtype) valid_pixels = 1 - void_pixels mask_gt = np.array(mask_gt) mask_gt_skeleton = skeletonize(mask_gt > 0) mask_gt_skeleton_valid = mask_gt_skeleton * valid_pixels valid_indxs = np.argwhere(mask_gt_skeleton_valid == 1) margin = int(np.round(patch_size / 10.0)) #Select a random point from the ground truth #print(img_idx) #print(img_filename) #print(valid_indxs) if len(valid_indxs) > 0: num_atempts = 0 selected_point = random.randint(0, len(valid_indxs) - 1) center = (valid_indxs[selected_point, 1], valid_indxs[selected_point, 0]) while (center[0] < patch_size / 2 or center[1] < patch_size / 2 or center[0] > w - patch_size / 2 or center[1] > h - patch_size / 2) and num_atempts < 20: selected_point = random.randint(0, len(valid_indxs) - 1) center = (valid_indxs[selected_point, 1], valid_indxs[selected_point, 0]) num_atempts += 1 if num_atempts < 20: #Add selected vertex to file to reproduce the experiments if save_vertices_indxs: f = open(os.path.join(root_dir, 'points_selected.txt'), 'a') f.write( str(img_idx) + " " + str(valid_indxs[selected_point, 0]) + " " + str(valid_indxs[selected_point, 1]) + "\n") f.close() x_tmp = int(center[0] - patch_size / 2) y_tmp = int(center[1] - patch_size / 2) img_crop = img[y_tmp:y_tmp + patch_size, x_tmp:x_tmp + patch_size, :] #Find intersection points between skeleton and inner bbox from patch mask_gt_crop = mask_gt_skeleton_valid[y_tmp:y_tmp + patch_size, x_tmp:x_tmp + patch_size] bbox_mask = np.zeros((patch_size, patch_size)) bbox_mask[margin, margin:patch_size - margin] = 1 bbox_mask[margin:patch_size - margin, margin] = 1 bbox_mask[margin:patch_size - margin, patch_size - margin] = 1 bbox_mask[patch_size - margin, margin:patch_size - margin] = 1 intersection_bbox_with_gt = mask_gt_crop * bbox_mask #Discard intersection points not connected to the patch center G = generate_graph_patch(mask_gt_crop) idx_end = (patch_size / 2) * patch_size + patch_size / 2 intersection_idxs = np.argwhere(intersection_bbox_with_gt == 1) connected_intersection_idxs = [] for ii in range(0, len(intersection_idxs)): idx_start = intersection_idxs[ ii, 0] * patch_size + intersection_idxs[ii, 1] length_pred, path_pred = nx.bidirectional_dijkstra( G, idx_start, idx_end, weight='weight') if length_pred == 0: connected_intersection_idxs.append(intersection_idxs[ii]) output_points = np.asarray(connected_intersection_idxs) for ii in range(0, len(output_points)): tmp_value = output_points[ii, 0] output_points[ii, 0] = output_points[ii, 1] output_points[ii, 1] = tmp_value return img_crop, output_points else: output_points = [] img_crop = [] return img_crop, output_points else: output_points = [] img_crop = [] return img_crop, output_points
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)
def calc_sym_ssc(graph, xRRatio=10.0): #NOTE: Have to reverse vArBase for SSC to function correctly. Hence multiplaction by -1.0. #TODO: Update docstring when functionality is expanded.... L-G faults and three-phase systems """Calculates the maximum symmetrical short circuit current at each node on the network using a point-to-point calculation procedure, starting from the "service" node then running down the digraph edges out to the load nodes. The series impedance from the "service" node to each other node on the network is used to calculate the short circuit current available. Determines and sets line to line faults and line to ground faults for single phase nodes. Requires that the short circuit current avaliable is provided for the secondary terminals of the service transformer and that the service is single phase or split phase center tapped. The utility X/R can be input (on secondary of service transformer), or a default of 10 is used. """ wBase, vArBase = WBASE, VARBASE sBase = complex(wBase, vArBase * -1.0) serviceNode = graph.get_service_node() try: xRRatio = graph.node[serviceNode]['xRRatio'] except KeyError: pass #Default X/R assumption unless otherwise set try: serviceVoltage = get_node_voltage(graph, serviceNode) zBase = (serviceVoltage**2.0) / sBase zPULL = (serviceVoltage / graph.node[serviceNode]['availSSC']) / abs(zBase) zPULN = (serviceVoltage / graph.node[serviceNode]['availSSC']*1.5) / abs(zBase) #TODO: Find better way... this is rough assumption sourceXPULL = math.sin(math.atan(xRRatio)) * zPULL sourceXPULN = math.sin(math.atan(xRRatio)) * zPULN sourceRPULL = math.cos(math.atan(xRRatio)) * zPULL sourceRPULN = math.cos(math.atan(xRRatio)) * zPULN sourceZPULL= complex(sourceRPULL, -1.0 * sourceXPULL) #Lagging source impedance sourceZPULN= complex(sourceRPULN, -1.0 * sourceXPULN) #Lagging source impedance except KeyError: print ("""Missing input data for service node. Unable to perform short circuit current calculations. Avaliable short circuit current at service node is required.""") for i in graph.nodes(): #Move on from service node if i == serviceNode: continue length, path = nx.bidirectional_dijkstra(graph, serviceNode, i) #TODO: Implement way to start with a starting SSC that sets a upstream system impedance...consider source X/R and available energy zSeriesPULL = sourceZPULL #Start with service impedance from source zSeriesPULN = sourceZPULN zEdgeSeriesPU = 0 #Sum series edge impedances between service point and node for j in range(len(path)-1): if not graph.node[path[j]]["phase"] == 1: #TODO: Remove once software can calculate three phase fault currents. raise Exception("calc_sym_ssc() only works for single phase systems currently") try: zEdgeSeriesPU += 2.0 * graph[path[j]][path[j+1]]["zPU"] #Mutiply by 2 for return impedance of conductors except KeyError: print "zPU not set for edge between {0} and {1}".format(path[j], path[j+1]) #If transformer is on the path add that to the series Impedance zSeriesPULL += zEdgeSeriesPU #TODO: Only works for single phase center tapped systems... consider setting ratio from upstream transformer or service whatever is closer #Convert to base voltage for L-N from L-L base zSeriesPULN += zEdgeSeriesPU * 1.0 * ((2 / 1)**2.0) for y in path: if graph.node[y]["nodeType"] == "transformer": try: zSeriesPULL += graph.node[y]["zPU"] zSeriesPULN += graph.node[y]["zPU"] * 1.5 #TODO: Find better way... this is rough assumption except KeyError: print "zPU not set for transformer {0}".format(y) #If transformer is the node where zSeriesPU is being set, dont include that transformers impedance (ssc at primary) if graph.node[i]["nodeType"] == "transformer": graph.node[i]["zSeriesPULL"] = zSeriesPULL - graph.node[i]["zPU"] graph.node[i]["zSeriesPULN"] = zSeriesPULN - graph.node[y]["zPU"] * 1.5 #TODO: Find better way... this is rough assumption continue graph.node[i]["zSeriesPULL"] = zSeriesPULL graph.node[i]["zSeriesPULN"] = zSeriesPULN for i in graph.nodes(): if i == serviceNode: graph.node[i]["SSC_LL"] = graph.node[i]['availSSC'] try: if graph.node[serviceNode]["phase"] == 1 and graph.node[serviceNode]["nomVLL"]*0.5 == graph.node[serviceNode]["nomVLN"] : graph.node[i]["SSC_LN"] = graph.node[i]['availSSC'] * 1.5 #TODO: Find better way... this is rough assumption except KeyError: pass continue if graph.node[i]["phase"] == 1: try: if graph.node[i]["nodeType"] == "transformer": graph.node[i]["SSC_LL"] = (1.0 / graph.node[i]["zSeriesPULL"]) * (sBase / graph.node[i]["nomPrimaryV"]) else: try: graph.node[i]["SSC_LL"] = (1.0 / graph.node[i]["zSeriesPULL"]) * (sBase / graph.node[i]["nomVLL"]) except KeyError: pass try: graph.node[i]["SSC_LN"] = (1.0 / graph.node[i]["zSeriesPULN"]) * (sBase / graph.node[i]["nomVLN"]) except KeyError: pass except KeyError: print "Missing series per unit impedance for node {0}".format(i)
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 test_bidirectional_dijkstra_multigraph(self): G = nx.MultiGraph() G.add_edge('a', 'b', weight=10) G.add_edge('a', 'b', weight=100) dp = nx.bidirectional_dijkstra(G, 'a', 'b') assert dp == (10, ['a', 'b'])
def findNeighbours(src, dest): G = nx.Graph() db = MySQLdb.connect(host="localhost", user="******", passwd="", db="project") cursor = db.cursor() cursor.execute("SELECT * FROM nodes") for row in cursor.fetchall(): G.add_node(int(row[0])) cursor.execute("SELECT * FROM lanes") for row in cursor.fetchall(): G.add_edge(int(row[1]), int(row[2])) G[row[1]][row[2]]['weight'] = row[3] print G.edges() print G.nodes() query = "SELECT node_id FROM locations WHERE name like '" + src + "'" cursor.execute(query) try: fetch = cursor.fetchall() source = fetch[0][0] query = "SELECT node_id FROM locations WHERE type = '" + dest + "'" print query cursor.execute(query) results = cursor.fetchall() print results F = [] for x in results: temp = nx.bidirectional_dijkstra(G, source, int(x[0]), weight='weight') F.append(temp) maxval = min(F[0:]) index = [] for ctr in range(len(F)): if F[ctr][0] == maxval[0]: index.append(ctr) cursor.execute( "SELECT nodes.node_id, nodes.x, nodes.y, name from nodes left join locations on nodes.node_id = locations.node_id" ) results = cursor.fetchall() Pathlist = [] for y in index: A = [] for x in F[y][1]: for row in results: if x == row[0]: A.append((row[1], row[2], row[3])) Pathlist.append(A) return Pathlist except: print "Invalid Query" return []
def __call__(self, ts, p): r = self.model.search_radius region = ( p[0]-r, p[1]-r, p[0]+r, p[1]+r ) # Find edges in the search radius and # project the current measurement to them candidates = self.model.segindex.intersection(region, objects='raw') positions = [] for cand in candidates: a = self.model.node_coords[cand[0]] b = self.model.node_coords[cand[1]] t, error, point = lineseg_point_projection(p, a, b) if error > r: continue positions.append((cand, t, error, point)) # Prune duplicates that hit exactly on # the nodes. # TODO: For some reason this pruning affects # results. Probably some logic flaw in the programmer. # Which is a shame as this does remove a lot of hypotheses. """ inter_node_hits = [] exact_node_hits = {} for (e, t, error, point) in positions: node = None if t == 0.0: node = e[0] if t == 1.0: node = e[1] if node is None: inter_node_hits.append((e, t, error, point)) continue if node in exact_node_hits: continue exact_node_hits[node] = (e, t, error, point) hits = inter_node_hits + exact_node_hits.values() """ hits = positions # Do nothing if no hits found. Not catastrophical # if this is due to an outlier. # TODO: We could track "out of map" trajectories if len(hits) == 0: print >>sys.stderr, "NO HITS" return # No previous states, start with current hits if len(self.states) == 0: for e, t, error, point in positions: s = _State(ts, (e, t), point, None) s.measurement_lik = self.model.measurement_logpdf(error) s.cumlik += s.measurement_lik self.states.append(s) self._prev_pos = p return # Find most likely predecessor for each # hit. new_states = [] for (e, t, error, point) in hits: # TODO: No need to add temporary nodes for # exact hits # Add temporary target dist = self.model.edge_costs[e] self.graph.add_edge(e[0], "tmptarget", weight=t*dist) self.graph.add_edge("tmptarget", e[1], weight=(1.0-t)*dist) self.model.node_coords['tmptarget'] = point max_lik = -np.inf max_hit = None for prev in self.states: # Add temporary target node se, st = prev.position dist = self.model.edge_costs[se] if e == se and st <= t: # The source is on the same edge than the # start and before, so it can jump straight # there. self.graph.add_edge("tmpsource", "tmptarget", weight=dist*(t-st)) # Allow self-transition if the nodes are exactly the same. # TODO: Get rid of this by getting rid of the whole temporary # node mess. if are_same_node((se, st), (e, t)): self.graph.add_edge("tmpsource", "tmptarget", weight=0.0) self.graph.add_edge(se[0], "tmpsource", weight=st*dist) self.graph.add_edge("tmpsource", se[1], weight=(1.0-st)*dist) self.model.node_coords['tmpsource'] = prev.point # Find shortest path try: distance, path = networkx.bidirectional_dijkstra( self.graph, "tmpsource", "tmptarget", weight='weight') """ def euclidean_dist(a, b): return np.linalg.norm(np.subtract( self.model.node_coords[a], self.model.node_coords[b])) path = networkx.astar_path(self.graph, "tmpsource", "tmptarget", euclidean_dist, weight='weight') distance = sum(self.graph[path[i]][path[i+1]]['weight'] for i in range(len(path)-1)) """ except networkx.exception.NetworkXNoPath: continue finally: # Remove temporary target node self.graph.remove_node("tmpsource") dt = ts - prev.ts path_coords = ([prev.point] + [self.model.node_coords[n] for n in path[1:-1]] + [point]) totlik = prev.cumlik + self.model.transition_logpdf(distance, dt, (self._prev_pos, p), path_coords) if totlik > max_lik: max_lik = totlik max_hit = (prev, path) # Remove temporary source node self.graph.remove_node("tmptarget") if max_hit is None: # Non-reachable target continue s = _State(ts, (e, t), point, max_hit[0]) s.path = max_hit[1][1:-1] s.cumlik += max_lik s.cumlik += self.model.measurement_logpdf(error) new_states.append(s) if len(new_states) == 0: # No valid transitions, ignore current measurement print >>sys.stderr, "NO TRANSITIONS" return self._prev_pos = p self.states = new_states
def exists_path(self, source, target): try: path = nx.bidirectional_dijkstra(self.g, source, target) return True, path except: return False, []
trip_detail = {} for prediction in possiblities: travelled = 0 seats = 0 current_trip = [] for path in prediction: trip_detail = {"path": path} cur = [] for idx in range(len(path)): if seats > 4: trip_detail["distance"] = -1 break if (idx + 1 != len(path)): next_stop = path[idx + 1] else: next_stop = 'D' output = nx.bidirectional_dijkstra(G, path[idx], next_stop) travelled = travelled + output[0] seats = seats + 1 trip_detail["distance"] = travelled current_trip.append(trip_detail) travelled = 0 seats = 0 trip_array.append(current_trip) for trips in trip_array: idx = 0 for trip in trips: print(idx + 1, trip["path"], " to office = " + str(trip["distance"])) idx += 1
def make_steiner_tree(G, voi, generator=None): mst = Graph() for v in voi: if not v in G: raise ValueError( "make_steiner_tree(): Vertex {} not in original graph".format( v)) if len(voi) == 0: return mst if len(voi) == 1: mst.add_node(voi[0]) return mst # Initially, use (a version of) Kruskal's algorithm to extract a minimal spanning tree # from a weighted graph. This algorithm differs in that only a subset of vertices are # going to be present in the final subgraph (which is not truly a MST - must use Prim's # algorithm later. # extract all shortest paths among the voi heapq = [] paths = {} # load all the paths bwteen the Steiner vertices. Store them in a heap queue # and reconstruct the MST of the complete graph using Kruskal's algorithm for i in range(len(voi) - 1): v1 = voi[i] for v2 in voi[i + 1:]: result = bidirectional_dijkstra(G, v1, v2) if result == False: raise RuntimeError( "The two vertices given (%s, %s) don't exist on the same connected graph" % (v1, v2)) #print "The two vertices given (%s, %s) don't exist on the same connected graph" % (v1, v2) distance, vertList = result keys = [v1, v2] keys.sort() key = "%s:%s" % tuple(keys) paths[key] = (vertList) heappush(heapq, (distance, v1, v2)) # construct the minimum spanning tree of the complete graph while heapq: w, v1, v2 = heappop(heapq) # if no path exists yet between v1 and v2, add this one if v1 not in mst or v2 not in mst or not has_path(mst, v1, v2): mst.add_edge(v1, v2, weight=w) # check if the graph is tree and correct sTree = set(mst.nodes()) sSteiner = set(voi) if sTree ^ sSteiner: raise RuntimeError('Failed to construct MST spanning tree') # reconstruct subgraph of origGraph using the paths if generator is None: subgraph = Graph() else: subgraph = generator() for edge in mst.edges_iter(data=True): keys = [edge[0], edge[1]] keys.sort() key = "%s:%s" % tuple(keys) vList = paths[key] for i in range(len(vList) - 1): v1 = vList[i] v2 = vList[i + 1] w = G[v1][v2] subgraph.add_edge(v1, v2, w) # get rid of possible loops - result will be a true MST subgraph = make_prim_mst(subgraph, generator) # remove intermediate nodes in paths that are not in list of voi return _trimTree(subgraph, voi)
if node2 in G.nodes: G.add_edge(node, node2, weight=1) key_map = get_key_map(G, keylocs) for node in G.nodes: for node2 in util.adj4(node): if node2 in G.nodes and (invalid(locs[node]) or invalid(locs[node2])): if (node, node2) in G.edges: G.remove_edge(node, node2) # print(currloc) # print(G.nodes) # print(G.edges) accessible_keys = set() blocked_keys = set() for k in keylocs: try: nx.bidirectional_dijkstra(G, currloc, keylocs[k]) accessible_keys.add(k) except nx.NetworkXNoPath: blocked_keys.add(k) continue print(accessible_keys) print(blocked_keys) print(key_map) print("Part 1") print(min_dist_to_finish(currloc, G, keylocs, doorlocs, 0, None, key_map))
def k_shortest_paths(G, source, target, k=1, weight='dur'): # Determine the shortest path from the source to the target duration, path = nx.bidirectional_dijkstra(G, source, target, weight=weight) A = [tuple([duration, path])] # k_shortest_paths B = [] for i in range(1, k): i_path = A[-1][1] # k-1 shortest path # The spur node ranges from the first node to the next to last node in the previous k-shortest path for j in range(len(i_path) - 1): # Spur node is retrieved from the previous k-shortest path, k − 1. spur_node = i_path[j] root_path = i_path[:j + 1] root_path_duration = 0 for u_i in range(len(root_path) - 1): u = root_path[u_i] v = root_path[u_i + 1] root_path_duration += get_edge_dur(u, v) # print('root_path', root_path) # print('root_path_duration', root_path_duration) edges_removed = [] for path_k in A: curr_path = path_k[1] # Remove the links that are part of the previous shortest paths which share the same root path if len(curr_path) > j and root_path == curr_path[:j + 1]: u = curr_path[j] v = curr_path[j + 1] if G.has_edge(u, v): G.remove_edge(u, v) edges_removed.append((u, v, get_edge_dur(u, v))) # print('u, v, edge_duration (remove)', u, v, edge_duration) # remove rootPathNode (except spurNode) from Graph for n in range(len(root_path) - 1): u = root_path[n] # print('node', u) # out-edges nodes = copy.deepcopy(G[u]) for v in nodes: G.remove_edge(u, v) edges_removed.append((u, v, get_edge_dur(u, v))) # print('u, v, edge_duration (remove)', u, v, edge_duration) # if G.is_directed(): # # in-edges # for u, v, edge_duration in G.in_edges_iter(node, data=True): # print('u, v, edge_duration (in)', u, v, edge_duration) # G.remove_edge(u, v) # edges_removed.append((u, v, edge_duration)) try: # Calculate the spur path from the spur node to the target spur_path_duration, spur_path = nx.bidirectional_dijkstra( G, spur_node, target, weight='dur') # Entire path is made up of the root path and spur path total_path = root_path[:-1] + spur_path total_path_duration = root_path_duration + spur_path_duration potential_k = tuple([total_path_duration, total_path]) # Add the potential k-shortest path to the heap if potential_k not in B: B.append(potential_k) # print('potential_k', potential_k) except nx.NetworkXNoPath: # print('NetworkXNoPath') pass # Add back the edges and nodes that were removed from the graph for u, v, edge_duration in edges_removed: G.add_edge(u, v, weight=edge_duration) # print('u, v, edge_duration (add)', u, v, edge_duration) if len(B): B.sort(key=lambda e: e[0]) A.append(B[0]) B.pop(0) else: break A.sort(key=lambda p: p[0]) KSP = [] for (dur, path) in A: KSP.append(path) return KSP
def create(self, *args, **kwargs): # look for RawData_T * folder if bool(glob.glob(self.args["DirName"])): # create object DPT.DPObject.create(self, *args, **kwargs) # set plot options self.indexer = self.getindex("trial") # initialization self.numSets = 0 self.sumCost = [] self.unityData = [] self.unityTriggers = [] self.unityTrialTime = [] self.unityTime = [] self.timePerformance = [] self.routePerformance = [] self.trialRouteRatio = [] self.durationDiff = [] # load the rplparallel object to get the Ripple timestamps rl = RPLParallel() self.timeStamps = [rl.timeStamps] os.chdir(glob.glob(self.args["DirName"])[0]) # look for session_1_*.txt in RawData_T* if bool(glob.glob(self.args["FileName"])): filename = glob.glob(self.args["FileName"]) self.numSets = len(filename) # load data of all session files into one matrix for index in range(0, len(filename)): if index == 0: text_data = np.loadtxt( filename[index], skiprows=self.args["FileLineOffset"]) else: text_data = np.concatenate( (text_data, np.loadtxt(filename[index], skiprows=self.args["FileLineOffset"]))) # Move back to session directory from RawData directory os.chdir("..") # Unity Data # Calculate the displacement of each time stamp and its direction delta_x = np.diff(text_data[:, 2]) delta_y = np.diff(text_data[:, 3]) dist = np.sqrt(delta_x**2 + delta_y**2) displacement_data = np.append(np.array([0]), dist) # The direction is in degrees, north set to 0, clockwise degree = np.degrees(np.arctan2(delta_y, delta_x)) degree[degree < 0] = degree[degree < 0] + 360 degree = degree - 90 degree[degree < 0] = degree[degree < 0] + 360 degree = 360 - degree degree[degree == 360] = 0 direction_from_displacement = np.append(np.array([0]), degree) direction_from_displacement = np.where( displacement_data == 0, np.nan, direction_from_displacement) direction_and_direction = np.column_stack( (direction_from_displacement, displacement_data)) # Merge into the loaded text data to form Unity Data (matrix with 7 columns) unityData = np.append(text_data, direction_and_direction, axis=1) # Unity Triggers uT1 = np.where((text_data[:, 0] > self.args["TriggerVal1"]) & (text_data[:, 0] < self.args["TriggerVal2"])) uT2 = np.where((text_data[:, 0] > self.args["TriggerVal2"]) & (text_data[:, 0] < self.args["TriggerVal3"])) uT3 = np.where(text_data[:, 0] > self.args["TriggerVal3"]) num_within_time = ( np.where((text_data[:, 0] > self.args["TriggerVal3"]) & (text_data[:, 0] < 40)))[0].size # Check if there is any incomplete trial utRows = [uT1[0].size, uT2[0].size, uT3[0].size] utMax = max(utRows) utMin = min(utRows) incomplete_trials = utMax - utMin if incomplete_trials != 0: print("Incomplete session! Last", incomplete_trials, "trial discarded") unityTriggers = np.zeros((utMin, 3), dtype=int) unityTriggers[:, 0] = uT1[0][0:utMin] unityTriggers[:, 1] = uT2[0][0:utMin] unityTriggers[:, 2] = uT3[0] unityTriggers = unityTriggers.astype(int) # Unity Time unityTime = np.append(np.array([0]), np.cumsum(text_data[:, 1])) # Unity Trial Time totTrials = np.shape(unityTriggers)[0] unityTrialTime = np.empty( (int(np.amax(uT3[0] - unityTriggers[:, 1]) + 2), totTrials)) unityTrialTime.fill(np.nan) trial_counter = 0 # set up trial counter sumCost = np.zeros((totTrials, 6)) for a in range(0, totTrials): # Unity Trial Time uDidx = np.array( range(int(unityTriggers[a, 1] + 1), int(unityTriggers[a, 2] + 1))) numUnityFrames = uDidx.shape[0] tindices = np.array(range(0, numUnityFrames + 1)) tempTrialTime = np.append(np.array([0]), np.cumsum(unityData[uDidx, 1])) unityTrialTime[tindices, a] = tempTrialTime # Sum Cost trial_counter = trial_counter + 1 # get target identity target = unityData[unityTriggers[a, 2], 0] % 10 # (starting position) get nearest neighbour vertex x = unityData[unityTriggers[a, 1], 2:4] s = cdist(vertices, x.reshape(1, -1)) start_pos = s.argmin() # (destination, target) get nearest neighbour vertex d = cdist(vertices, (poster_pos[int(target - 1), :]).reshape(1, -1)) des_pos = d.argmin() ideal_cost, path = nx.bidirectional_dijkstra( G, des_pos, start_pos) mpath = np.empty(0) # get actual route taken(match to vertices) for b in range( 0, (unityTriggers[a, 2] - unityTriggers[a, 1] + 1)): curr_pos = unityData[unityTriggers[a, 1] + b, 2:4] # (current position) cp = cdist(vertices, curr_pos.reshape(1, -1)) I3 = cp.argmin() mpath = np.append(mpath, I3) path_diff = np.diff(mpath) change = np.array([1]) change = np.append(change, path_diff) index = np.where(np.abs(change) > 0) actual_route = mpath[index] actual_cost = (actual_route.shape[0] - 1) * 5 # actualTime = index # Store summary sumCost[a, 0] = ideal_cost sumCost[a, 1] = actual_cost sumCost[a, 2] = actual_cost - ideal_cost sumCost[a, 3] = target sumCost[a, 4] = unityData[unityTriggers[a, 2], 0] - target if sumCost[a, 2] <= 0: # least distance taken sumCost[ a, 5] = 1 # mark out trials completed via shortest route elif sumCost[a, 2] > 0 and sumCost[a, 4] == 30: path_diff = np.diff(actual_route) for c in range(0, path_diff.shape[0] - 1): if path_diff[c] == path_diff[c + 1] * (-1): timeingrid = np.where( mpath == actual_route[c + 1])[0].shape[0] if timeingrid > 165: break else: sumCost[a, 5] = 1 # Calculate performance error_ind = np.where(sumCost[:, 4] == 40) sumCost[error_ind, 5] = 0 # Proportion of trial ratio_within_time = num_within_time / totTrials ratio_shortest_route = np.where( sumCost[:, 5] == 1)[0].size / totTrials ratio_each_trial_route = np.divide(sumCost[:, 1], sumCost[:, 0]) # duration_diff start_ind = unityTriggers[:, 0] + 1 end_ind = unityTriggers[:, 2] + 1 start_time = unityTime[start_ind] end_time = unityTime[end_ind] trial_durations = end_time - start_time duration_diff = None try: rp_trial_dur = rl.timeStamps[:, 2] - rl.timeStamps[:, 0] # multiply by 1000 to convert to ms duration_diff = (trial_durations - rp_trial_dur) * 1000 except: print('problem with timeStamps') self.durationDiff = [duration_diff] self.trialRouteRatio = [ratio_each_trial_route] self.timePerformance = [ratio_within_time] self.routePerformance = [ratio_shortest_route] self.sumCost.append(sumCost) self.unityData.append(unityData) self.unityTriggers.append(unityTriggers) self.unityTrialTime.append(unityTrialTime) self.unityTime.append(unityTime) self.setidx = ([0] * unityTriggers.shape[0]) else: # create empty object DPT.DPObject.create(self, dirs=[], *args, **kwargs)
def getPath(self, min1, min2): try: return nx.bidirectional_dijkstra(self.graph, min1, min2) except nx.NetworkXNoPath: return None
def solver_helper(list_of_kingdom_names, H, starting_status, adjacency_matrix): """ Write your algorithm here. Input: list_of_kingdom_names: An list of kingdom names such that node i of the graph corresponds to name index i in the list starting_kingdom: The name of the starting kingdom for the walk adjacency_matrix: The adjacency matrix from the input file Output: Return 2 things. The first is a list of kingdoms representing the walk, and the second is the set of kingdoms that are conquered """ N = len(list_of_kingdom_names) starting_owned = sum([1 for i in starting_status if i > 0]) if starting_owned == N: return starting_status if N == 1: starting_status[0] = 2 return starting_status starting_status = tuple(starting_status) starting_index = 0 lengths = dict() for i in range(N): length, path = nx.bidirectional_dijkstra(H, 0, i) lengths[(-1, i)] = length lengths[(i, -1)] = length lengths[(0, i)] = length lengths[(i, 0)] = length # dfs to construct a graph of graphs queue = [] known = set() s = (starting_index, starting_owned, starting_status) found = set() smallest = float('inf') queue.append((0, (-1, starting_owned, starting_status))) while queue != []: cost, node = heappop(queue) if node not in known: cur, n, status = node known.add(node) if cur == starting_index and n == N: if cost > smallest: return found # found.add(status) # smallest = cost return status if n == N: heappush(queue, (cost + lengths[(cur, 0)], (0, n, status))) for next in range(N): if status[next] < 2: new_status = list(status) new_n = n if new_status[next] < 1: new_n = n + 1 new_status[next] = 2 for neighbor in H.adj[next]: if new_status[neighbor] < 1: new_status[neighbor] = 1 new_n += 1 new_node = (next, new_n, tuple(new_status)) if (cur, next) not in lengths: length, _ = nx.bidirectional_dijkstra(H, cur, next) lengths[(cur, next)] = length lengths[(next, cur)] = length length = lengths[(cur, next)] + adjacency_matrix[ list_of_kingdom_names[next]][ list_of_kingdom_names[next]] heappush(queue, (cost + length, new_node))
def get_street_stretch_by_geometry(self, geometry_1, geometry_2, on_street_code=None): """ Given two endpoint geometries, return a shortest path street stretch. Geometries can either be nodes or segments or a combination of the two. For nodes, if an optional on_street_code is provided, only start and end on streets on the given street code. This function works by adding temporary nodes to the Geocoder's segment_network called START and END. START connects to geometry_1 and END connects to geometry_2. Then find a shortest path from START to END and return it as a StreetStretch. This function will always return a result if there is a possible path from geometry_1 to geometry_2 even if it is not actually a "stretch" (not all along one on street). You can use the StreetStretch object's attributes to determine if the stretch is valid for your use case. Parameters ---------- geometry_1, geometry_2 : str Start and endpoints for the stretch on_street_code : str, optional An on street code to start and end on. Returns ------- StreetStretch """ geometry_1, type_1, id_1, side_1 = self.parse_geometry(geometry_1) geometry_2, type_2, id_2, side_2 = self.parse_geometry(geometry_2) # Add start node (START -> geometry_1) if type_1 == 'node': # Since we will be routing on the segment network, for nodes connect # START to all segments that the node connects to. for segment in self.node_network[geometry_1]: # If on_street_code is provided, only connect to segments # on the given street. if ( (on_street_code is None) or (on_street_code in self.get_segment(segment)['street_code']) ): self.segment_network.add_edge('START', segment, weight=1) elif type_1 == self.segment_column: # For segments, connect the segment itself. # If side isn't given, allow both sides. if not side_1: for side in ['L', 'R']: self.segment_network.add_edge('START', geometry_1 + side, weight=1) else: self.segment_network.add_edge('START', geometry_1, weight=1) # Add End Node in the same fashion, but connecting geometry_2 -> END if type_2 == 'node': for segment in self.node_network.predecessors(geometry_2): if ( (on_street_code is None) or (on_street_code in self.get_segment(segment)['street_code']) ): self.segment_network.add_edge(segment, 'END', weight=1) elif type_2 == self.segment_column: if not side_2: for side in ['L', 'R']: self.segment_network.add_edge(geometry_2 + side, 'END', weight=1) else: self.segment_network.add_edge(geometry_2, 'END', weight=1) try: path = nx.bidirectional_dijkstra( self.segment_network, 'START', 'END', weight='weight' )[1] return StreetStretch(self, path[1:-1]) finally: # Even if there's an error, make sure to remove START and END from # the network. for n in ['START', 'END']: self.segment_network.remove_node(n)
def solve(list_of_kingdom_names, starting_kingdom, adjacency_matrix, params=[]): """ Write your algorithm here. Input: list_of_kingdom_names: An list of kingdom names such that node i of the graph corresponds to name index i in the list starting_kingdom: The name of the starting kingdom for the walk adjacency_matrix: The adjacency matrix from the input file Output: Return 2 things. The first is a list of kingdoms representing the walk, and the second is the set of kingdoms that are conquered """ split_size = 15 subgraph = nx.Graph() last_node = None starting_status = [0 for _ in list_of_kingdom_names] sublist = [] starting_index = list_of_kingdom_names.index(starting_kingdom) N = len(list_of_kingdom_names) H = adjacency_matrix_to_graph(adjacency_matrix) result = [] closed_walk, conquered_kingdoms = [], [] stack = [] known = set() stack.append((None, starting_index)) while stack: prev, node = stack.pop() if node in known: continue sublist.append(node) known.add(node) flag = False if len(sublist) == 1: subgraph.add_node(0) elif prev in sublist: subgraph.add_edge(sublist.index(prev), len(sublist) - 1, weight=H[prev][node]['weight']) else: flag = True sublist.pop() if flag or len(sublist) == split_size or len(known) == N: sub_starting_status = [starting_status[node] for node in sublist] sub_result = solver_helper(sublist, subgraph, sub_starting_status, adjacency_matrix) for i in range(len(sub_result)): if sub_result[i] == 2: conquered_kingdoms.append(sublist[i]) for nbr in H.adj[sublist[i]]: starting_status[nbr] = 1 subgraph = nx.Graph() sublist = [] if flag: subgraph.add_node(0) sublist.append(node) # Need to fix the order the neigbhors being added: too costly adjs = list(H.adj[node]) avg = sum([H[node][nbr]['weight'] for nbr in adjs]) / len(adjs) adjs = sorted(adjs, key=lambda nbr: abs(H[node][nbr]['weight'] - avg), reverse=True) for nbr in adjs: stack.append((node, nbr)) if sublist != []: sub_starting_status = [starting_status[node] for node in sublist] sub_result = solver_helper(sublist, subgraph, sub_starting_status, adjacency_matrix) for i in range(len(sub_result)): if sub_result[i] == 2: conquered_kingdoms.append(sublist[i]) tmp_conquered = [(-adjacency_matrix[c][c], c) for c in conquered_kingdoms] while tmp_conquered != []: c = heappop(tmp_conquered)[1] conquered_kingdoms.remove(c) if not nx.is_dominating_set(H, conquered_kingdoms): conquered_kingdoms.append(c) conquered = list(conquered_kingdoms) if starting_index not in conquered: conquered.append(starting_index) C = len(conquered) if C == 1: return [starting_kingdom], [starting_kingdom] elif C == 2: if starting_index == conquered[0]: start, next = conquered else: next, start = conquered _, path = nx.bidirectional_dijkstra(H, start, next) path = [list_of_kingdom_names[c] for c in path] return path + path[::-1][1:], [ list_of_kingdom_names[c] for c in conquered_kingdoms ] else: matrix = np.zeros((C, C)) paths = dict() for i in range(C): for j in range(i + 1, C): matrix[i, j], path = nx.bidirectional_dijkstra( H, conquered[i], conquered[j]) paths[(i, j)] = path paths[(j, i)] = path[::-1] matrix = matrix + matrix.T if np.max(matrix) >= 10e6: matrix = matrix / 10e6 outf = "/tmp/myroute.tsp" with open(outf, 'w') as dest: dest.write(dumps_matrix(matrix, name="My Route")) tour = run(outf, start=conquered.index(starting_index), solver="LKH") tour_path = tour['tour'] for i in range(len(tour_path)): cur = tour_path[i] if i == len(tour_path) - 1: dest = conquered.index(starting_index) else: dest = tour_path[i + 1] closed_walk.append(paths[(cur, dest)]) final_walk = [] for i in range(len(closed_walk)): data = closed_walk[i] if i == 0: for j in data: final_walk.append(list_of_kingdom_names[j]) else: for j in data[1:]: final_walk.append(list_of_kingdom_names[j]) return final_walk, [ list_of_kingdom_names[c] for c in conquered_kingdoms ]
def generate_example_output(G): dijkstra = nx.bidirectional_dijkstra(G, source=source, target=target) node_path_list = dijkstra[1] edge_path = nodes_to_edges(node_path_list) path_vector = route_to_vec(edge_path) return path_vector
import matplotlib.pyplot as plt import networkx as nx G = nx.Graph() n = input() def read_data(filename): f = open(filename, 'r') return f.readlines() lines = read_data("cities.txt") for l in lines: a, b, weight = l.split() G.add_edge(a, b, weight=int(weight)) for i in nx.nodes(G): if not nx.has_path(G, n, i): print('there is no path') else: length, path = nx.bidirectional_dijkstra(G, n, i) print(length, path)
def test_bidirectional_dijkstra_no_path(self): with pytest.raises(nx.NetworkXNoPath): G = nx.Graph() nx.add_path(G, [1, 2, 3]) nx.add_path(G, [4, 5, 6]) path = nx.bidirectional_dijkstra(G, 1, 6)
# Assignment (RWA) in Optical Networks import info import itertools import numpy as np import networkx as nx # https://networkx.github.io/documentation/networkx-1.10/reference/algorithms.shortest_paths.html def dijkstra(mat, (s,d)): if any([s,d])<0 or any([s,d])>mat.shape[0]: print 'Error' return None, None G = nx.from_numpy_matrix(mat, create_using=nx.Graph()) hops, path = nx.bidirectional_dijkstra(G, s, d, weight=None) return path # https://networkx.github.io/documentation/development/_modules/networkx/algorithms/coloring/greedy_coloring.html # https://networkx.github.io/documentation/development/reference/algorithms.coloring.html def greedy_color(H, colors, strategy=nx.coloring.strategy_largest_first): G = nx.from_numpy_matrix(H, create_using=nx.Graph()) if len(G): # set to keep track of colors of neighbours neighbour_colors = set() #node = G.nodes()[-1] # last node added #for neighbour in G.neighbors_iter(node): # if neighbour in colors: # neighbour_colors.add(colors[neighbour])
def test_bidirectional_dijkstra_no_path(self): G = nx.Graph() nx.add_path(G, [1, 2, 3]) nx.add_path(G, [4, 5, 6]) path = nx.bidirectional_dijkstra(G, 1, 6)
for o, a in optlist: if o == '-b': begin = int(a) if o == '-s': stop = int(a) ## load the network baseDir = os.path.join("..", os.path.realpath(os.path.dirname(__file__))) resultsDir = os.path.join(baseDir, 'results') G = nx.read_gpickle(os.path.join(baseDir, "network.pickle")) ## create a results file outFile = os.path.join(resultsDir, f"out-{begin}-{stop}.csv") outFid = open(outFile, 'w') writer = csv.writer(outFid) writer.writerow(["i", "j", "distance"]) pathsToFind = range(begin, stop) n = len(G.nodes()) count = -1 for i in range(n): for j in range(n): if i >= j: continue count += 1 if count in pathsToFind: length, path = nx.bidirectional_dijkstra(G, str(i), str(j)) writer.writerow([i, j, length]) outFid.close()
#debug #GP.CopyFeatures(pts_inx, r'C:\temp\connectivity\network_cost\geodb.gdb\pts_inx') GP.MakeFeatureLayer(nodes_shp, 'nodes_lyr') GP.SelectLayerByAttribute_management('nodes_lyr', 'NEW_SELECTION', "\"NodeType\" = 'centroid'") GP.GenerateNearTable_analysis(pts_inx, 'nodes_lyr', centroids_near_pts, "", "NO_LOCATION", "NO_ANGLE", "CLOSEST", "0") # loop through points, getting paths and edges for display cur = GP.SearchCursor(centroids_near_pts) row = cur.Next() nbunch = [] while row: near_fid = row.GetValue('NEAR_FID') nbunch.append(near_fid) #FIX!: using dirtball shortcut of NodeID = FID + 1 row = cur.Next() ebunch = [] for u,v in cm.list_lower_tri(nbunch): d, p = NX.bidirectional_dijkstra(G, u, v) # real work is here to calculate shortest path #GP.TableSelect_analysis(network_trunc_lc_paths_dbf, selected_paths_table, "\"FromNode\" IN (%d, %d) AND \"ToNode\" IN (%d, %d)" % (u,v,u,v)) # get EdgeIDs from path of nodes for i in range(len(p)-1): ebunch.append(G.eid[p[i]][p[i+1]]) GP.addmessage('Patch %d (node %d) to Patch %d (node %d)' % (G.npatchid[u], u, G.npatchid[v], v)) GP.addmessage(' total cost distance: %d' % d) GP.addmessage(' path by NodeIDs: %s' % ','.join([str(x) for x in p])) GP.SelectLayerByAttribute_management(edges_lyr, "NEW_SELECTION", "\"EdgeID\" IN (%s)" % ','.join([str(x) for x in ebunch]))
def shortest_path(G, source=None, target=None, weight=None, method="dijkstra"): """Compute shortest paths in the graph. Parameters ---------- G : NetworkX graph source : node, optional Starting node for path. If not specified, compute shortest paths for each possible starting node. target : node, optional Ending node for path. If not specified, compute shortest paths to all possible nodes. weight : None or string, optional (default = None) If None, every edge has weight/distance/cost 1. If a string, use this edge attribute as the edge weight. Any edge attribute not present defaults to 1. method : string, optional (default = 'dijkstra') The algorithm to use to compute the path. Supported options: 'dijkstra', 'bellman-ford'. Other inputs produce a ValueError. If `weight` is None, unweighted graph methods are used, and this suggestion is ignored. Returns ------- path: list or dictionary All returned paths include both the source and target in the path. If the source and target are both specified, return a single list of nodes in a shortest path from the source to the target. If only the source is specified, return a dictionary keyed by targets with a list of nodes in a shortest path from the source to one of the targets. If only the target is specified, return a dictionary keyed by sources with a list of nodes in a shortest path from one of the sources to the target. If neither the source nor target are specified return a dictionary of dictionaries with path[source][target]=[list of nodes in path]. Raises ------ NodeNotFound If `source` is not in `G`. ValueError If `method` is not among the supported options. Examples -------- >>> G = nx.path_graph(5) >>> print(nx.shortest_path(G, source=0, target=4)) [0, 1, 2, 3, 4] >>> p = nx.shortest_path(G, source=0) # target not specified >>> p[4] [0, 1, 2, 3, 4] >>> p = nx.shortest_path(G, target=4) # source not specified >>> p[0] [0, 1, 2, 3, 4] >>> p = nx.shortest_path(G) # source, target not specified >>> p[0][4] [0, 1, 2, 3, 4] Notes ----- There may be more than one shortest path between a source and target. This returns only one of them. See Also -------- all_pairs_shortest_path all_pairs_dijkstra_path all_pairs_bellman_ford_path single_source_shortest_path single_source_dijkstra_path single_source_bellman_ford_path """ if method not in ("dijkstra", "bellman-ford"): # so we don't need to check in each branch later raise ValueError(f"method not supported: {method}") method = "unweighted" if weight is None else method if source is None: if target is None: # Find paths between all pairs. if method == "unweighted": paths = dict(nx.all_pairs_shortest_path(G)) elif method == "dijkstra": paths = dict(nx.all_pairs_dijkstra_path(G, weight=weight)) else: # method == 'bellman-ford': paths = dict(nx.all_pairs_bellman_ford_path(G, weight=weight)) else: # Find paths from all nodes co-accessible to the target. if G.is_directed(): G = G.reverse(copy=False) if method == "unweighted": paths = nx.single_source_shortest_path(G, target) elif method == "dijkstra": paths = nx.single_source_dijkstra_path(G, target, weight=weight) else: # method == 'bellman-ford': paths = nx.single_source_bellman_ford_path(G, target, weight=weight) # Now flip the paths so they go from a source to the target. for target in paths: paths[target] = list(reversed(paths[target])) else: if target is None: # Find paths to all nodes accessible from the source. if method == "unweighted": paths = nx.single_source_shortest_path(G, source) elif method == "dijkstra": paths = nx.single_source_dijkstra_path(G, source, weight=weight) else: # method == 'bellman-ford': paths = nx.single_source_bellman_ford_path(G, source, weight=weight) else: # Find shortest source-target path. if method == "unweighted": paths = nx.bidirectional_shortest_path(G, source, target) elif method == "dijkstra": _, paths = nx.bidirectional_dijkstra(G, source, target, weight) else: # method == 'bellman-ford': paths = nx.bellman_ford_path(G, source, target, weight) return paths