def make_loop(graph, center_pivot, start, dist): """ Makes loop trail corresponding to center-pivot w.r.t start Parameters: graph (osmnx graph): graph structure determined by start location center_pivot (int): osmid of center-pivot node start (int): osmid of nearest node to start coordinates dist (int): distance goal in km Returns: temp (list): list of osmid corresponding to path nodes """ pivots = get_pivots(graph, center_pivot, dist) # handle duplicate pivots - implement better fix later pivots = list(set(pivots)) temp = nx.multi_source_dijkstra(graph, pivots, start, weight="length")[-1] visited = {temp[0]} while len(pivots) != len(visited): temp[0:0] = nx.multi_source_dijkstra(graph, set(pivots) - visited, temp[0], weight="length")[-1][:-1] visited.add(temp[0]) temp[0:0] = nx.shortest_path(graph, start, temp[0], weight="length")[:-1] return temp
def dijkstra_explored(G, source, destination): return " -> ".join( nx.multi_source_dijkstra(G, source, target=destination, cutoff=None, weight="weight")[1])
def calculate_skill_match(required, candidate_skills, skill_endorsements, max_endorsements): endorsements = {} for skill_endorsement in skill_endorsements: endorsements[str(skill_endorsement['name']).lower()] = int( skill_endorsement['endorsements']) # find closest item to each required score = 0.0 all_nodes = list(skill_graph.nodes()) candidate_skills = set(candidate_skills).intersection(set(all_nodes)) for skill in required: # find closest skill to skill if skill in candidate_skills: score += 1 score += endorsements[skill] / max_endorsements[skill] else: try: path = nx.multi_source_dijkstra(skill_graph, candidate_skills, skill) length = path[0] closest_node = path[1][0] score += endorsements[closest_node] / max_endorsements[ closest_node] except Exception: length = 1 length = 1.0 if length >= 1 else float(length) score += (1.0 - length) return float(score / (2 * len(required)))
def _nx_sp(nx_graph, s, weight): if weight is None: return nx.single_source_shortest_path_length(nx_graph, s) dist, _ = nx.multi_source_dijkstra(graph, [s], weight=weight) return dist
def _calculate_reachable_paths(self): if self._reachable_paths is not None: return self._reachable_costs, self._reachable_paths = networkx.multi_source_dijkstra( self._digraph, {self.state.node}, weight=lambda source, target, attributes: 0 if self._can_advance(target) else 1)
def analyze_graph(G): start_nodes = [n for n in G.nodes if n[0] == 0] max_frame = max([frame for frame, _ in G.nodes]) cost, path = nx.multi_source_dijkstra(G, start_nodes, cutoff=100) cost = {k: v for k, v in cost.items() if k[0] == max_frame} path = {k: v for k, v in path.items() if k[0] == max_frame} return cost, path
def test_two_sources(self): edges = [(0, 1, 1), (1, 2, 1), (2, 3, 10), (3, 4, 1)] G = nx.Graph() G.add_weighted_edges_from(edges) sources = {0, 4} distances, paths = nx.multi_source_dijkstra(G, sources) expected_distances = {0: 0, 1: 1, 2: 2, 3: 1, 4: 0} expected_paths = {0: [0], 1: [0, 1], 2: [0, 1, 2], 3: [4, 3], 4: [4]} assert_equal(distances, expected_distances) assert_equal(paths, expected_paths)
def test_two_sources(self): edges = [(0, 1, 1), (1, 2, 1), (2, 3, 10), (3, 4, 1)] G = nx.Graph() G.add_weighted_edges_from(edges) sources = {0, 4} distances, paths = nx.multi_source_dijkstra(G, sources) expected_distances = {0: 0, 1: 1, 2: 2, 3: 1, 4: 0} expected_paths = {0: [0], 1: [0, 1], 2: [0, 1, 2], 3: [4, 3], 4: [4]} assert distances == expected_distances assert paths == expected_paths
def analyze_graph(G, cutoff=100): """Trace a path forward from each nucleus in the starting frame. Only keep the paths that reach the final frame. """ start_nodes = [n for n in G.nodes if n[0] == 0] max_frame = max([frame for frame, _ in G.nodes]) cost, path = nx.multi_source_dijkstra(G, start_nodes, cutoff=cutoff) cost = {k: v for k, v in cost.items() if k[0] == max_frame} path = {k: v for k, v in path.items() if k[0] == max_frame} return cost, path
def compute_tree_distances(tree): """ Computes the matrix of pairwise distances between leaves of the tree """ num_leaves = len(get_leaves(tree)) - 1 distances = np.zeros([num_leaves, num_leaves]) for leaf in range(num_leaves): distance_dictionary, tmp = nx.multi_source_dijkstra( tree.to_undirected(), [leaf], weight='time') for target_leaf in range(num_leaves): distances[leaf, target_leaf] = distance_dictionary[target_leaf] return distances
def resolve(src, tgt, rectgt, reclimit): if reclimit <= 0: raise ValueError("Max recursion depth is reached!") result = set() for t in tgt: # print("Searching path from [{}] to [{}]".format( # ' '.join(map(str, src)), ' '.join(map(str, t)))) mask = set() while True: try: path = nx.multi_source_dijkstra(dg, src - mask, t)[1] except nx.NetworkXNoPath: return None except ValueError: if src == mask: return None raise resolved, unres = set(), set() wrongway = False for pnode in path[1:]: if dg.nodes[pnode].get('transform', False): for n in dg.predecessors(pnode): if n not in src: unres.add(n) for n in dg.successors(pnode): if n in src: wrongway = True if pnode not in src: resolved.add(pnode) if wrongway: mask.add(path[0]) continue if len(unres) > 0: if not unres.isdisjoint(rectgt): mask.add(path[0]) continue else: sub = resolve(src | resolved, unres, rectgt | frozenset( (t, )), reclimit - 1) if sub is None: mask.add(path[0]) continue resolved.update(sub) result.update(resolved) break return result
def _calculate_reachable_paths(self): if self._reachable_paths is not None: return all_nodes = self.game.world_list.all_nodes def weight(source: int, target: int, attributes): if self._can_advance(all_nodes[target]): return 0 else: return 1 self._reachable_costs, self._reachable_paths = networkx.multi_source_dijkstra( self._digraph, {self.state.node.index}, weight=weight)
def modified_edge_betweenness_centrality(graph, nodes): betweenness = dict.fromkeys(graph.edges(), 0.0) for v1 in nodes: for v2 in nodes: l, path = nx.multi_source_dijkstra(graph, [v1], v2) for i in range(len(path) - 1, 0, -1): e1 = path[i] e2 = path[i - 1] betweenness[(e2, e1)] = betweenness[(e2, e1)] + 1
def join(network, exclude, T, v): """Implementation of the greedy approximation algorithm for constructing DSTs. See algorithm 3 in 'Resilient SDN-based multicast'. Arguments: network: network graph exclude: all links that should be excluded from the trees T: current trees v: node to be added to T """ if v in T: return [] def weight(x, y, edata): if not edata['live']: return None if (x, y) in exclude: return None if not T.has_edge(x, y) and y in T: return None #Resulting trees should actually be trees return 1 try: length, paths = nx.multi_source_dijkstra(G=network, sources=set(T.nodes()), target=v, weight=weight) if v not in paths: return [] path = paths[v] w = path[0] pre = [] cur = w root = T.graph['root'] while cur != root: cur = list(T.predecessors(cur))[0] pre.append(cur) pre.reverse() return pre + path except (nx.NetworkXNoPath, nx.NetworkXError): return []
def calculate_depth(self, surface_graph): """Calculates depth on the graph surface. Parameters ---------- surface_graph : nx.Graph Graph of surface. Returns ------- tuple of two dictionaries keyed by node The first dictionary stores distance from one of the source nodes. The second stores the path from one of the sources to that node. """ level = list(self.get_vertices(self.get_simplices_by_step(step=-1))) return nx.multi_source_dijkstra(surface_graph, level)
def generate_counterfactual(self, instance, label): """Generates counterfactual to flip prediction of example using dijkstra shortest path for the graph created Args: instance: instance to generate CE Returns: path to CE as instances from data as a pandas DataFrame probability of CE (if prediction_prob specified) """ if self.G.number_of_nodes() == 0: self.add_nodes_and_edges() instance = instance.reshape(1, -1) target = int(abs(label - 1)) target_data = self.data[self.y == target] #target_data = self.y #target_data = self.data[self.y['encoded_income'] == target] target_nodes = list( set(list(self.G.nodes())).intersection(target_data.index)) #target_nodes = target_data.indexes example_in_data = self.data[self.data.eq(instance)].dropna() if len(example_in_data) > 0: start_node = example_in_data.iloc[0].name else: start_node = self.data.iloc[-1].name + 1 self.data = self.data.append( pd.Series(instance.squeeze(), index=list(self.data), name=start_node)) self.add_nodes_and_edges(new_point=True) assert start_node in list( self.G.nodes), "Instance does not meet thresholds" _, path = nx.multi_source_dijkstra(self.G, target_nodes, target=start_node) path = path[::-1] path_df = self.data.loc[path].reset_index(drop=True) #pred = self.clf.predict(path_df).astype(int).reshape(-1, 1) #prob_df = pd.DataFrame(pred, columns=['prediction']) return path_df
def shortest_path(self, source): ''' The function computes the shortest path between hospital nodes and the node from which the emergency call was generated. Break-down: - Edge: Using Dijkstra method, the mean travel time of edges are used as weights to identify the fastest paths rather than the shorted paths to the emergency node. The function evaluates all the hospitals to determine the best option. - Dispatching: based on the radius of the region from which the ambulace is dispatched the estimated time of dispatching is calculated based on the ambulace average speed. mean = time for the ambulance to travel the radius of the region standard deviation = 5 seconds - Pick_up: Also based on the radius of the region from which the emergency call was generated mean = time for the ambulance to travel the radius of the region standard deviation = 10 seconds Note: sd is higher because the ambulance is less certain about the emergency call source the ambulace average speed is in Km\h hence the conversion to seconds ''' # Identify the hospital node that is fastest to dispatch the ambulance from edge = nx.multi_source_dijkstra(self.graph, sources=self.hospital_nodes, target=source, weight='m_travel_time') # Estimate the time for the ambulance to be dispatched dispatching = np.random.normal( (self.graph.nodes[edge[1][-1]]['radius'] / (self.v_ambulance)) * 3600, 5) # Estimate the time it takes for the ambulance to pick up the patient pick_up = np.random.normal( (self.graph.nodes[source]['radius'] / (self.v_ambulance)) * 3600, 10) # Record the hospital from which the ambulance was dispateched self.visits.append(edge[1][0]) # Estimate the travel time on the shortest path trip = self.estimated_travel_time(edge[1]) # Return the sum of the whole trip return dispatching + trip + pick_up
def find_evac_path(self, c, tofront_data): """evacuate a cluster by finding shortest path from each robot in cluster to origin""" master_nodes = set(v for r, v in self.graph.agents.items() if r == self.master) active_nodes = set( v for C in tofront_data.frontier_clusters for v in tofront_data.cs.subgraphs[C]).union(master_nodes) evac = {} for r, v in self.graph.agents.items(): if r in tofront_data.cs.agent_clusters[c]: _, path = nx.multi_source_dijkstra(self.graph_tran, sources=active_nodes, target=v, weight="weight") path = path[::-1] evac[r] = path return evac
def voter(node, other): region1_nodes = {context[k] for k in [node] if k in context.keys()} region2_nodes = {context[k] for k in [other] if k in context.keys()} region1_hypernodes = list() region2_hypernodes = list() for node, node_data in working_graph.nodes(data=True): call_graph_label = node_data['label'] if call_graph_label in region1_nodes: region1_hypernodes.append(node_id_lookup[call_graph_label]) if call_graph_label in region2_nodes: region2_hypernodes.append(node_id_lookup[call_graph_label]) distances = list() if len(region1_hypernodes) > 0: for target in region2_hypernodes: try: distances_, _ = nx.multi_source_dijkstra(working_graph, region1_hypernodes, target) distances.append(distances_) except nx.NetworkXNoPath: pass return min(distances, default=0)
def multi_source_dijkstra(self, sources: Set[int], weight: Callable[[int, int, Requirement], float]): return networkx.multi_source_dijkstra(self, sources, weight=weight)
def test_no_sources(self): with pytest.raises(ValueError): nx.multi_source_dijkstra(nx.Graph(), {})
def generate_counterfactual(self, instance): """Generates counterfactual to flip prediction of example using dijkstra shortest path for the graph created Args: instance: instance to generate CE Returns: path to CE as instances from data as a pandas DataFrame probability of CE (if prediction_prob specified) """ if self.G.number_of_nodes() == 0: self.add_nodes_and_edges() instance = instance.reshape(1, -1) target = int(abs(self.clf.predict(instance) - 1)) target_data = self.data[self.clf.predict(self.data) == target] target_nodes = list( set(list(self.G.nodes())).intersection(target_data.index)) example_in_data = self.data[self.data.eq(instance)].dropna() if len(example_in_data) > 0: start_node = example_in_data.iloc[0].name else: start_node = self.data.iloc[-1].name + 1 self.data = self.data.append( pd.Series(instance.squeeze(), index=list(self.data), name=start_node)) self.add_nodes_and_edges(new_point=True) assert start_node in list( self.G.nodes), "Instance does not meet thresholds" _, path = nx.multi_source_dijkstra(self.G, target_nodes, target=start_node) path = path[::-1] if self.pred_threshold is not None: pred_prob = self.clf.predict_proba( target_data.loc[path[-1]].values.reshape(1, -1)).squeeze()[target] while pred_prob < self.pred_threshold: target_data = target_data.drop(path[-1]) target_nodes = list( set(list(self.G.nodes())).intersection(target_data.index)) assert len( target_nodes) > 0, "Target nodes do not meet thresholds" _, path = nx.multi_source_dijkstra(self.G, target_nodes, target=start_node) path = path[::-1] pred_prob = self.clf.predict_proba( target_data.loc[path[-1]].values.reshape( 1, -1)).squeeze()[target] path_df = self.data.loc[path].reset_index(drop=True) pred = self.clf.predict(path_df).astype(int).reshape(-1, 1) prob = np.take_along_axis(self.clf.predict_proba(path_df), pred, axis=1) prob_df = pd.DataFrame(np.concatenate((pred, prob), axis=1), columns=['prediction', 'probability']) return path_df, prob_df path_df = self.data.loc[path].reset_index(drop=True) pred = self.clf.predict(path_df).astype(int).reshape(-1, 1) prob_df = pd.DataFrame(pred, columns=['prediction']) return path_df, prob_df
start_c = time.time() connect = np.loadtxt(mesh_connectivity) weighted_graph_with_connectivity = add_connectivity( np.copy(graph[0]), weighted_graph.copy(), connect) # create networkx graph G = nx.from_edgelist(weighted_graph) G_prime = nx.from_edgelist(weighted_graph_with_connectivity) # load boundary vertices and find their indices in the graph sources = np.loadtxt(mesh_boundary) src = np.where(np.isin(graph[0][:, 0:2], sources[:, 0:2])[:, 0])[0] # run Dijkstra - to set sources on the bounday use set(src) as the sources # parameter length, path = nx.multi_source_dijkstra(G, {15}) length_prime, path_prime = nx.multi_source_dijkstra(G_prime, {15}) #convert lengths into array for triplot dist = np.zeros(np.shape(graph[0])[0]) for key, value in length.items(): dist[key] = value dist_prime = np.zeros(np.shape(graph[0])[0]) for key, value in length_prime.items(): dist_prime[key] = value #plot fig1, ax1 = plt.subplots() ax1.set_aspect('equal') #for i in np.arange(len(src)):
def test_no_sources(self): nx.multi_source_dijkstra(nx.Graph(), {})
def agent_clustering(cp, num_clusters): """ cluster agents into k clusters INPUTS ====== cp.graph_tran : transition graph cp.static_agents : static agent list RETURNS ======= agent_clusters : dict(c: set(r)) clustering of agents """ # Step 1: create dynamic agent graph da_graph = nx.Graph() dynamic_agents = [ r for r in cp.graph_tran.agents if r not in cp.static_agents ] dynamic_agent_nodes = set(cp.graph_tran.agents[r] for r in dynamic_agents) da_agents = [ (tuple([r for r in dynamic_agents if cp.graph_tran.agents[r] == v]), v) for v in dynamic_agent_nodes ] for r, v in da_agents: da_graph.add_node(r) for (r1, v1), (r2, v2) in product(da_agents, da_agents): if r1 == r2: add_path = False else: add_path = True sh_path = nx.shortest_path(cp.graph_tran, source=v1, target=v2, weight="weight") for v in sh_path: if v in dynamic_agent_nodes and v != v1 and v != v2: add_path = False if add_path: w = nx.shortest_path_length(cp.graph_tran, source=v1, target=v2, weight="weight") da_graph.add_edge(r1, r2, weight=w) # add small weight to every edge to prevent divide by zero. (w += 0.1 -> agents in same node has 10 similarity) for edge in da_graph.edges: da_graph.edges[edge]["weight"] += 0.1 # inverting edge weights as agent_clustering use them as similarity measure for edge in da_graph.edges: da_graph.edges[edge]["weight"] = 1 / da_graph.edges[edge]["weight"] # Step 2: cluster it # Cluster (uses weights as similarity measure) sc = SpectralClustering(num_clusters, affinity="precomputed") sc.fit(nx.to_numpy_matrix(da_graph)) # construct dynamic agent clusters agent_clusters = {} c_group = [] for c in range(num_clusters): for i, r_list in enumerate(da_graph): if sc.labels_[i] == c: c_group += r_list agent_clusters["cluster" + str(c)] = c_group c_group = [] # add static agents to nearest cluster for (r, v) in cp.graph_tran.agents.items(): added = False if r in cp.static_agents: start_node = nx.multi_source_dijkstra(cp.graph_tran, sources=dynamic_agent_nodes, target=v)[1][0] for c in agent_clusters: for rc in agent_clusters[c]: if start_node == cp.graph_tran.agents[rc] and not added: agent_clusters[c].append(r) added = True return agent_clusters
def inflate_agent_clusters(cp, cs): """ inflate a clustering of agents to return a clustering of nodes REQUIRES ======== cp cs.agent_clusters cs.dead_nodes (optional) WRITES TO ========= cs.subgraphs : dict(c: set(v)) cs.child_clusters : dict(c0 : (c1,v1)) cs.parent_clusters : dict(c1 : (c0,v0)) """ # node clusters with agent positions clusters = { c: set(cp.graph.agents[r] for r in r_list) for c, r_list in cs.agent_clusters.items() } child_clusters = {c: set() for c in cs.agent_clusters.keys()} parent_clusters = {} # start with master cluster active active_clusters = [ c for c, r_list in cs.agent_clusters.items() if cp.master in r_list ] while True: # check if active cluster can activate other clusters directly found_new = True while found_new: found_new = False for c0, c1 in product(active_clusters, clusters.keys()): if c0 == c1 or c1 in active_clusters: continue for v0, v1 in product(clusters[c0], clusters[c1]): if cp.graph.has_conn_edge(v0, v1): active_clusters.append(c1) child_clusters[c0].add((c1, v1)) parent_clusters[c1] = (c0, v0) found_new = True # all active nodes active_nodes = set.union(*[clusters[c] for c in active_clusters]) free_nodes = set(cp.graph.nodes) - set.union(*clusters.values()) if cs.dead_nodes is not None: free_nodes -= cs.dead_nodes # make sure clusters are connected via transitions, if not split for c, v_set in clusters.items(): c_subg = cp.graph_tran.subgraph(v_set | free_nodes).to_undirected() comps = nx.connected_components(c_subg) comp_dict = { i: [ r for r in cs.agent_clusters[c] if cp.graph.agents[r] in comp ] for i, comp in enumerate(comps) } comp_dict = {i: l for i, l in comp_dict.items() if len(l) > 0} if len(comp_dict) > 1: # split and restart del cs.agent_clusters[c] for i, r_list in comp_dict.items(): cs.agent_clusters["{}_{}".format(c, i + 1)] = r_list return inflate_agent_clusters(cp, cs) # recursive call # find closest neighbor and activate it neighbors = cp.graph.post_tran(active_nodes) - active_nodes if cs.dead_nodes is not None: neighbors -= cs.dead_nodes if len(neighbors) == 0: break # nothing more to do new_cluster, new_node, min_dist = -1, -1, 99999 for c in active_clusters: c_neighbors = cp.graph.post_tran(clusters[c]) agent_positions = [ cp.graph.agents[r] for r in cs.agent_clusters[c] ] for n in neighbors & c_neighbors: dist, _ = nx.multi_source_dijkstra(cp.graph_tran, sources=agent_positions, target=n) if dist < min_dist: min_dist, new_node, new_cluster = dist, n, c clusters[new_cluster].add(new_node) cs.subgraphs = clusters cs.child_clusters = child_clusters cs.parent_clusters = parent_clusters return cs
links, nodes = linknodenetwork(Network, draw=0) graph, G = graphs(links, epsg) ########################## # Routes ########################## # orig = (645855.629,5956835.576) # desti = (638129.780,5954136.820) #################### buildnetwork(graph, G, draw=0, impe=impedance) # length, path = nx.multi_source_dijkstra(G, {14000},weight= impedance) # length = nx.multi_source_dijkstra_path_length(G, {12000, 14000},weight= impedance) start_time = time.time() for p in range(12000, 12100): length, path = nx.multi_source_dijkstra(G, {p}, weight=impedance) print(round((time.time() - start_time), 1), "seconds--") import igraph as ig g = ig.Graph.from_networkx(G) # path = g.get_shortest_paths(1,1000,mode="out",weights=impedance,output="epath") # sum(g.es[path[0]][impedance]) start_time = time.time() for p in range(12000, 12100): path = g.get_all_shortest_paths(p, to=None, weights=impedance, mode='out') print(round((time.time() - start_time), 1), "seconds--") route = nx.shortest_path(G=G, source=1, target=1000, weight=impedance) print("impedance: " + str(round(path_weight(G=G, path=route, weight=impedance), 1)))