def test_paths_length_tree(tree_and_cascade): g = tree_and_cascade[0] for i in range(10): s, t = np.random.permutation(g.num_vertices())[:2] length = shortest_distance(g, s, t) forbidden_nodes = {} for p in all_simple_paths_of_length(g, s, t, length, forbidden_nodes=forbidden_nodes, debug=True): correct_path = [ int(v) for v in shortest_path(g, g.vertex(s), g.vertex(t))[0] ] assert correct_path == p for i in range(10): s, t = np.random.permutation(g.num_vertices())[:2] length = shortest_distance(g, s, t) if length > 2: forbidden_nodes = { int( random.choice( shortest_path(g, g.vertex(s), g.vertex(t))[0][1:-1])) } with pytest.raises(StopIteration): next( all_simple_paths_of_length(g, s, t, length, forbidden_nodes=forbidden_nodes, debug=True))
def simulate_cascade(g, p, source=None, return_tree=False): """ graph_tool version of simulating cascade return np.ndarray on vertices as the infection time in cascade uninfected node has dist -1 """ if source is None: source = random.choice(np.arange(g.num_vertices(), dtype=int)) gv = sample_graph_by_p(g, p) times = get_infection_time(gv, source) if return_tree: all_edges = set() for target in np.nonzero(times != -1)[0]: path = shortest_path(gv, source=source, target=gv.vertex(target))[0] edges = set(zip(path[:-1], path[1:])) all_edges |= edges tree = Graph(directed=True) for _ in range(g.num_vertices()): tree.add_vertex() for u, v in all_edges: tree.add_edge(int(u), int(v)) return source, times, tree else: return source, times
def distance(word1, word2): v1 = self.g.vertex(self.lemma_to_vertex_id.get(word1)) v2 = self.g.vertex(self.lemma_to_vertex_id.get(word2)) shortest_path = list(graph_tool.shortest_path(self.g, v1, v2)) depth_v1 = self._vertex_depth(v1) depth_v2 = self._vertex_depth(v2) # lsc = Least Common Subsumer; [0] index means next vertices of shortest path lcs_candidates = shortest_path[0] shortest_path_len = len(shortest_path[1]) # [1] for edges # find lcs depth if simplified: lsc_depth = self._vertex_depth(lcs_candidates[int( len(lcs_candidates) / 2)]) else: lsc_depth = 2147483647 for candidate in lcs_candidates[ 1:-1]: # first and last are vertices v1 and v2 depth = self._vertex_depth(candidate) if depth < lsc_depth: lsc_depth = depth wu_plamer = 2 * lsc_depth / (depth_v1 + depth_v2) return wu_plamer
def _vertex_depth(self, vertex): # distances = graph_tool.shortest_distance(self.g, source=vertex).a # distances = list(filter(lambda x: x != 2147483647, distances)) # remove max_int # depth = max(distances) depth = len( list(graph_tool.shortest_path(self.g, self.v_root, vertex)[1])) return depth
def layout(g, rootv, sfdp=True, deg0=-45.0, degspan=90.0, radius=100): isouter = lambda x: not bool([ v for v in x.out_neighbours() if v != x ]) ## isouter = lambda x: x.out_degree()==0 outer_vertices = [ int(x) for x in g.vertices() if isouter(x) ] nouter = len(outer_vertices) angle = [float(deg0)] unit = float(degspan)/(nouter-1) iv2angle = {} outer_seen = set() iv2dist = defaultdict(lambda:0) all_seen = set() pos = g.new_vertex_property('vector<float>') pin = g.new_vertex_property('bool') pin[rootv] = 1 for v in g.vertices(): pos[v] = [0.0, 0.0] radius = float(radius) wt = g.new_edge_property('float') for e in g.edges(): strees = g.edge_strees[e] if len(strees) > 0: wt[e] = 1.0 else: wt[e] = 0.01 for iv in outer_vertices: pv, pe = gt.shortest_path(g, rootv, g.vertex(iv)) for e in reversed(pe): wt[e] += 0.5 g.wt = wt def traverse(v, dist=0, angle=angle): iv = int(v) if iv in outer_vertices: iv2dist[iv] = max(iv2dist[iv], dist) if iv not in outer_seen: ang = angle[0] iv2angle[iv] = ang angle[0] += unit rad = math.radians(ang) x = math.cos(rad) * radius y = math.sin(rad) * radius pos[v] = [x, y] pin[v] = 1 outer_seen.add(iv) all_seen.add(iv) for oe in v.out_edges(): ov = oe.target() ## if len(G.edge_strees[oe])>0 and (int(ov) not in all_seen): if int(ov) not in all_seen: traverse(ov, dist+1, angle) traverse(rootv) if sfdp: pos = gt.sfdp_layout(g, pos=pos, pin=pin, C=10, p=3,# theta=2, K=0.1, eweight=wt, mu=0.0, multilevel=False) return pos, pin
def get_paths(t, source, terminals): return [ list( map(int, shortest_path(t, source=source, target=t.vertex(int(n)))[0])) for n in terminals ]
def __distance(self, node_from, node_to): if node_from == node_to: return 0 v_l, e_l = gt.shortest_path(self._network, node_from, node_to) if len(v_l) == 0: return 1 else: return 1 - (1.0 / len(v_l))
def distance(word1, word2): v1 = self.g.vertex(self.lemma_to_vertex_id.get(word1)) v2 = self.g.vertex(self.lemma_to_vertex_id.get(word2)) # graph_tool.shortest_path_len(g, v1, v2) returns 2 element tuple: # list of vertices # list of edges # we count number of edges shortest_path_len = len( list(graph_tool.shortest_path(self.g, v1, v2)[1])) lc_dist = float( max(0, -np.log(shortest_path_len / (2 * (self.depth))))) return lc_dist
def test_paths_length_tree(tree_and_cascade): g = tree_and_cascade[0] for i in range(10): s, t = np.random.permutation(g.num_vertices())[:2] length = shortest_distance(g, s, t) forbidden_nodes = {} for p in all_simple_paths_of_length(g, s, t, length, forbidden_nodes=forbidden_nodes, debug=True): correct_path = [int(v) for v in shortest_path(g, g.vertex(s), g.vertex(t))[0]] assert correct_path == p for i in range(10): s, t = np.random.permutation(g.num_vertices())[:2] length = shortest_distance(g, s, t) if length > 2: forbidden_nodes = {int(random.choice( shortest_path(g, g.vertex(s), g.vertex(t))[0][1:-1]))} with pytest.raises(StopIteration): next(all_simple_paths_of_length(g, s, t, length, forbidden_nodes=forbidden_nodes, debug=True))
def to_directed(g, t, root): new_t = Graph(directed=True) all_edges = set() leaves = [v for v in t.vertices() if (v.out_degree() + v.in_degree()) == 1 and t != root] for target in leaves: path = shortest_path(t, source=root, target=target)[0] edges = set(zip(path[:-1], path[1:])) all_edges |= edges for _ in range(g.num_vertices()): new_t.add_vertex() for u, v in all_edges: new_t.add_edge(int(u), int(v)) return new_t
def to_directed(g, t, root): new_t = Graph(directed=True) all_edges = set() leaves = [ v for v in t.vertices() if (v.out_degree() + v.in_degree()) == 1 and t != root ] for target in leaves: path = shortest_path(t, source=root, target=target)[0] edges = set(zip(path[:-1], path[1:])) all_edges |= edges for _ in range(g.num_vertices()): new_t.add_vertex() for u, v in all_edges: new_t.add_edge(int(u), int(v)) return new_t
def get_shortest_path(self, source, target): tic = time.time() # compute shortest path vertices_path, _ = shortest_path(self.graph, source, target, weights=self.weight, negative_weights=True) # else: # vertices_path = nx.dijkstra_path(self.graph, source, target) path_map = np.zeros(self.hard_constraints.shape) col = 1 # transform path path = [] out_costs = [] for v in vertices_path: v_ind = self.graph.vertex_index[v] x_inds, y_inds = np.where(self.pos2node == v_ind) # find minimum value field out of possible if self.mode == "all": min_val = 1 for (i, j) in zip(x_inds, y_inds): val_cost = np.mean(self.cost_instance[:, i, j]) if val_cost < min_val: min_val = val_cost min_ind_x = i min_ind_y = j # current plotting path_map[i, j] = col col += 1 elif self.mode == "center": min_ind_x = int(np.mean(x_inds)) min_ind_y = int(np.mean(y_inds)) path.append((min_ind_x, min_ind_y)) out_costs.append(self.cost_rest[:, min_ind_x, min_ind_y].tolist()) plt.imshow(path_map, origin="upper") plt.savefig("path_map.png") self.time_logs["shortest_path"] = round(time.time() - tic, 3) return path, out_costs
def build_tree(self, source=None, targets=None, dist_target=None): ''' Starting from a source node and a list of nodes reachable from 'source', then we create a new network where we only include the edges of the shortest path from 'source' to 'targets'. This way, the final network is a tree. ''' if source==None: return None else: source_tree = gt.Graph(directed=False) g_to_tree = defaultdict(lambda:-1) tree_to_g = defaultdict(lambda:-1) g_to_tree[source] = 0 tree_to_g[0] = source last_index = 0 edgelist = [] for tgt in targets: vlist, elist = gt.shortest_path(self.g, self.g.vertex(source), self.g.vertex(tgt)) for v in vlist: if g_to_tree[v]==-1: g_to_tree[v] = last_index+1 tree_to_g[last_index+1] = v last_index += 1 for e in elist: edgelist.append([int(e.source()), int(e.target())]) new_edgelist = [] for e in edgelist: new_edgelist.append([g_to_tree[e[0]], g_to_tree[e[1]]]) g_tree = gt.Graph(directed=False) fmt_edgelist = np.vstack(new_edgelist) fmt_edgelist = np.unique(fmt_edgelist, axis=0) g_tree.add_edge_list(fmt_edgelist) original_index = g_tree.new_vp('int') for v in g_tree.get_vertices(): original_index[v] = tree_to_g[v] g_tree.vertex_properties['original_index'] = original_index return g_tree
def get_shortest_path(self, source, target): """ Compute shortest path from source vertex to target vertex """ tic = (time.time()) # #if source and target are given as indices: if self.graphtool: vertices_path, _ = shortest_path(self.graph, source, target, weights=self.weight, negative_weights=True) else: try: vertices_path = nx.dijkstra_path(self.graph, source, target) except nx.exception.NetworkXNoPath: return [] self.time_logs["shortest_path"] = round(time.time() - tic, 3) return vertices_path
def remove_redundant_edges_from_tree(g, tree, r, terminals): """given a set of edges, a root, and terminals to cover, return a new tree with redundant edges removed""" efilt = g.new_edge_property('bool') for u, v in tree: efilt[g.edge(u, v)] = True tree = GraphView(g, efilt=efilt) # remove redundant edges min_tree_efilt = g.new_edge_property('bool') min_tree_efilt.set_2d_array(np.zeros(g.num_edges())) for o in terminals: if o != r: tree.vertex(r) tree.vertex(o) _, edge_list = shortest_path(tree, source=tree.vertex(r), target=tree.vertex(o)) assert len(edge_list) > 0, 'unable to reach {} from {}'.format(o, r) for e in edge_list: min_tree_efilt[e] = True min_tree = GraphView(g, efilt=min_tree_efilt) return min_tree
def find_path(origin_id, destination_id, max_jump_distance): origin = g.vertex(origin_id) destination = g.vertex(destination_id) if not origin or not destination: bottle.abort(400, "Origin or destination unknown") v = gt.GraphView( g, efilt=lambda e: (g.edge_properties['jump_distance'][e]) <= float(max_jump_distance) ) vlist,elist = gt.shortest_path(v, origin, destination, g.edge_properties['jump_distance']) ret = [] if len(vlist) > 0: for vtx, edge in zip(vlist, elist): ret.append(vtx_to_json(vtx)) ret.append(edge_to_json(edge)) ret.append(vtx_to_json(vlist[-1])) return json.dumps(ret)
def find_path(origin_id, destination_id, max_jump_distance): origin = g.vertex(origin_id) destination = g.vertex(destination_id) if not origin or not destination: bottle.abort(400, "Origin or destination unknown") v = gt.GraphView( g, efilt=lambda e: (g.edge_properties['jump_distance'][e]) <= float(max_jump_distance)) vlist, elist = gt.shortest_path(v, origin, destination, g.edge_properties['jump_distance']) ret = [] if len(vlist) > 0: for vtx, edge in zip(vlist, elist): ret.append(vtx_to_json(vtx)) ret.append(edge_to_json(edge)) ret.append(vtx_to_json(vlist[-1])) return json.dumps(ret)
tri, pos = gt.triangulation(ppoints, type="delaunay") print 'Done Triangulation' weight = tri.new_edge_property("double") for e in tri.edges(): weight[e] = np.sqrt(sum((np.array(pos[e.source()]) - np.array(pos[e.target()]))**2)) print 'Done weighting' b = gt.betweenness(tri, weight=weight) b[1].a *= 120 dist = gt.shortest_distance(tri,tri.vertex(0),tri.vertex(5),weights=weight) path, elist = gt.shortest_path(tri,tri.vertex(0),tri.vertex(5)) print 'Done shortest distance and path' print 'dist' print dist print 'path' for i in path: print i gt.graph_draw(tri, vertex_text=tri.vertex_index, edge_text=tri.edge_index, edge_pen_width=b[1], output_size=(1000,1000), output="triang.pdf") #weights = pdist(ppoints) #print weights
def search(self,from_node,to_node): return gt.shortest_path(self.graph,from_node,to_node)
def assign(self,demand,init_flow = None,init_flow_node = None, params = {'epsilon':1e-12,'theta':1e-12,'mu':1e-3,'nu':0.5, 'dg':10,'time':1200,'iter':50,'out_flag':False}): ''' # input # demand: python dictionary of demand record in form {(o_node,d_node):flow} # init_flow: initial flow assignment of the demand # params: parameter for the algorithm # out_flag: bool variable for output ''' t = time.time() epsilon = params['epsilon'] theta = params['theta'] mu = params['mu'] nu = params['nu'] dg_limit = params['dg'] max_iter = params['iter'] time_limit = params['time'] out_flag = params['out_flag'] network = self.network link_background = self.link_background link_param = self.link_param cost_func = self.link_cost_func edge_list = self.edge_list edge_index = self.edge_index ori_index = self.ori_index link_cost = network.new_edge_property("float",val=0) link_cost_de = network.new_edge_property("float",val=0) link_flow = network.new_edge_property("float",val=0) link_flow_node = {} for ori in ori_index.keys(): link_flow_node[ori] = network.new_edge_property("float",val=0) # Step 0 : Initialization if not init_flow or not init_flow_node: _,link_cost.a,_ = cost_func(link_background.a,[p.a for p in link_param]) subnet = {} for ori in ori_index.keys(): _,subnet[ori] = gt.shortest_distance(network, source=network.vertex(ori), weights=link_cost, max_dist=100000, pred_map=True) for key,value in demand.items(): _,e_list = gt.shortest_path(network, source=network.vertex(key[0]), target=network.vertex(key[1]), pred_map=subnet[key[0]]) e_list = [edge_index.get(tuple(e)) for e in e_list] link_flow.a[e_list] += value link_flow_node[key[0]].a[e_list] += value else: link_flow.a = init_flow.a for ori in ori_index.keys(): link_flow_node[ori].a = init_flow_node[ori].a _,link_cost.a,link_cost_de.a = cost_func(link_flow.a + link_background.a, [p.a for p in self.link_param]) dg = self.get_duality_gap(link_flow,link_cost,demand) if out_flag: print('ITAPAS: Initial duality gap = {:.0f}. Elapsed time = {:.2f}.'.format(dg,time.time() - t)) if dg < dg_limit: return link_flow,link_flow_node pas_set = {} # (e1,e2):r0 pas_set_node = {} for v in network.get_vertices(): pas_set_node[int(v)] = {} flag = True curr_iter = 0 while flag: comp_slack = 0.0 for ori in ori_index.keys(): # Step 1: local_link_flow = link_flow_node[ori] d_map,prev_map = gt.shortest_distance(network, source=network.vertex(ori), weights=link_cost, max_dist=10000, pred_map=True) # update reduced cost and put into link set node link_set = [] rc_start = d_map.a[edge_list[:,0]] rc_start[np.isinf(rc_start)] = -1 rc_end = d_map.a[edge_list[:,1]] rc_end[np.isinf(rc_end)] = 100000 comp_slack = float(np.sum(local_link_flow.a * (rc_start - rc_end + link_cost.a))) if comp_slack > 1e-8: ind_list = list(np.logical_and(local_link_flow.a > epsilon * comp_slack, (rc_start - rc_end + link_cost.a) > theta * comp_slack)) link_set = [(edge_list[i,0],edge_list[i,1]) for i,ind in enumerate(ind_list) if ind] while link_set: # identify pas e = link_set.pop() if local_link_flow.a[edge_index.get((e[0],e[1]))] > epsilon: pas = self.MFS(link_flow,local_link_flow,link_cost,link_cost_de, prev_map,ori,e,epsilon) if pas: if pas not in pas_set: pas_set[pas] = ori pas_set_node[e[1]][pas] = ori if pas_set: pas_list = list(pas_set.keys()) if len(pas_list) > 100: pas_list_select = [pas_list[idx] for idx in np.random.choice(len(pas_list),100,replace=False)] else: pas_list_select = pas_list for pas in pas_list_select: self.shift(link_flow,link_flow_node[pas_set.get(pas)], link_cost,link_cost_de,pas,epsilon,mu,True) for _ in range(20): pas_list = list(pas_set.keys()) for pas in pas_list: if not self.shift(link_flow,link_flow_node[pas_set.get(pas)], link_cost,link_cost_de,pas,epsilon,mu,False): del pas_set[pas] _,link_cost.a,link_cost_de.a = cost_func(link_flow.a + link_background.a, [p.a for p in self.link_param]) dg = self.get_duality_gap(link_flow,link_cost,demand) if out_flag: print('ITAPAS: Iteration {} finished. PAS size = {}. Duality gap = {:.0f}. Elapsed time = {:.2f}.'.format(curr_iter,len(pas_set),dg,time.time() - t)) curr_iter += 1 if (dg < dg_limit) or (curr_iter > max_iter) or (time.time() - t > time_limit): return link_flow,link_flow_node
def MFS(self,flow_map,local_flow_map,cost_map,cost_de_map, prev_map,r,e0,epsilon): network = self.network param_map = self.link_param link_background = self.link_background link_cost_func = self.link_cost_func edge_index = self.edge_index prev_new_map = network.new_vertex_property("int",val=-1) status_map = network.new_vertex_property("int",val=0) v_list,e_list = gt.shortest_path(network,source=network.vertex(r), target=network.vertex(e0[1]),pred_map=prev_map) if e0[0] == r: return (tuple([edge_index.get(tuple(e)) for e in e_list]),tuple([edge_index.get(e0)])) # count = 0 # debug_flag = False while True: # if count > 100: # debug_flag = True # print count,r,e0,local_flow_map[e0],[int(v) for v in v_list] # step 1: initialization prev_new_map.set_value(-1) status_map.set_value(0) i,j = e0 prev_new_map[j] = i for v in v_list: status_map[v] = -1 status_map[j] = 1 status_map[i] = 1 inner_flag = True while inner_flag: # step 2: find max incoming edge m_list = [int(m) for m in network.vertex(i).in_neighbours()] f_list = [local_flow_map.a[edge_index.get((m,i))] for m in m_list] m = m_list[np.argmax(f_list)] # if debug_flag: # print i,m_list,f_list,status_map[m] prev_new_map[i] = m if status_map[m] == -1: # step 3: return pas _,e1 = gt.shortest_path(network,source=network.vertex(m), target=network.vertex(j),pred_map=prev_map) _,e2 = gt.shortest_path(network,source=network.vertex(m), target=network.vertex(j),pred_map=prev_new_map) return (tuple([edge_index.get(tuple(e)) for e in e1]), tuple([edge_index.get(tuple(e)) for e in e2])) elif status_map[m] == 1: # step 4: remove cycle e_list = [] curr_m = prev_new_map[m] e_list += [edge_index.get((curr_m,m))] prev_m = prev_new_map[curr_m] while curr_m != m: e_list += [edge_index.get((prev_m,curr_m))] curr_m = prev_m prev_m = prev_new_map[curr_m] e_list = np.array(e_list) delta = np.min(local_flow_map.a[e_list]) local_flow_map.a[e_list] -= delta flow_map.a[e_list] -= delta _,cost_map.a[e_list],cost_de_map.a[e_list] = link_cost_func(flow_map.a[e_list] + \ link_background.a[e_list], [p.a[e_list] for p in param_map]) if local_flow_map.a[edge_index.get(e0)] < epsilon: return None inner_flag = False # if debug_flag: # print delta else: i = m status_map[i] = 1
def get_path(self, src, tgt): g = self.graph vlist, elist = gt.shortest_path(g, g.vertex(src), g.vertex(tgt)) return vlist, elist
def get_paths(t, source, terminals): return [list(map(int, shortest_path(t, source=source, target=t.vertex(int(n)))[0])) for n in terminals]
def get_shortest_path(self, source, target, weights): vertex_list, edge_list = gt.shortest_path(self.g, source, target, weights) return vertex_list, edge_list
def extractReferences(G, dbOrder, outPrefix, existingRefs=None): """Extract references for each cluster based on cliques Writes chosen references to file by calling :func:`~writeReferences` Args: G (graph) A network used to define clusters from :func:`~constructNetwork` dbOrder (list) The order of files in the sketches, so returned references are in the same order outPrefix (str) Prefix for output file (.refs will be appended) existingRefs (list) References that should be used for each clique Returns: refFileName (str) The name of the file references were written to references (list) An updated list of the reference names """ if existingRefs == None: references = set() reference_indices = [] else: references = set(existingRefs) index_lookup = {v: k for k, v in enumerate(dbOrder)} reference_indices = [index_lookup[r] for r in references] # extract cliques from network cliques_in_overall_graph = [c.tolist() for c in gt.max_cliques(G)] # order list by size of clique cliques_in_overall_graph.sort(key=len, reverse=True) # iterate through cliques for clique in cliques_in_overall_graph: alreadyRepresented = 0 for node in clique: if node in reference_indices: alreadyRepresented = 1 break if alreadyRepresented == 0: reference_indices.append(clique[0]) # Find any clusters which are represented by multiple references # First get cluster assignments clusters_in_overall_graph = printClusters(G, dbOrder, printCSV=False) # Construct a dict containing one empty set for each cluster reference_clusters_in_overall_graph = [ set() for c in set(clusters_in_overall_graph.items()) ] # Iterate through references for reference_index in reference_indices: # Add references to the originally empty set for the appropriate cluster # Allows enumeration of the number of references per cluster reference_clusters_in_overall_graph[clusters_in_overall_graph[ dbOrder[reference_index]]].add(reference_index) # Use a vertex filter to extract the subgraph of refences # as a graphview reference_vertex = G.new_vertex_property('bool') for n, vertex in enumerate(G.vertices()): if n in reference_indices: reference_vertex[vertex] = True else: reference_vertex[vertex] = False G_ref = gt.GraphView(G, vfilt=reference_vertex) G_ref = gt.Graph( G_ref, prune=True ) # https://stackoverflow.com/questions/30839929/graph-tool-graphview-object # Calculate component membership for reference graph clusters_in_reference_graph = printClusters(G, dbOrder, printCSV=False) # Record to which components references below in the reference graph reference_clusters_in_reference_graph = {} for reference_index in reference_indices: reference_clusters_in_reference_graph[ dbOrder[reference_index]] = clusters_in_reference_graph[ dbOrder[reference_index]] # Check if multi-reference components have been split as a validation test # First iterate through clusters network_update_required = False for cluster in reference_clusters_in_overall_graph: # Identify multi-reference clusters by this length if len(cluster) > 1: check = list(cluster) # check if these are still in the same component in the reference graph for i in range(len(check)): component_i = reference_clusters_in_reference_graph[dbOrder[ check[i]]] for j in range(i, len(check)): # Add intermediate nodes component_j = reference_clusters_in_reference_graph[ dbOrder[check[j]]] if component_i != component_j: network_update_required = True vertex_list, edge_list = gt.shortest_path( G, check[i], check[j]) # update reference list for vertex in vertex_list: reference_vertex[vertex] = True reference_indices.add(int(vertex)) # update reference graph if vertices have been added if network_update_required: G_ref = gt.GraphView(G, vfilt=reference_vertex) G_ref = gt.Graph( G_ref, prune=True ) # https://stackoverflow.com/questions/30839929/graph-tool-graphview-object # Order found references as in mash sketch files reference_names = [dbOrder[int(x)] for x in sorted(reference_indices)] refFileName = writeReferences(reference_names, outPrefix) return reference_indices, reference_names, refFileName, G_ref
def find_path_prm(self, start, goal, use_weights=False): # dist = graph_tool.all.shortest_distance(self._g, self._g.vertex(start), self._g.vertex(goal)) # start_time = time.time() # path = graph_tool.all.shortest_path(self._g, self._g.vertex(start), self._g.vertex(goal)) # elapsed_time = (time.time() - start_time) # f = elapsed_time # print "Time to calc path: %f" % f # p = path[0] # p2 = [] # p2 = list(np.array(p, dtype=int)) # return p2 if start == goal: return [] if type(start) is not int or type(goal) is not int: start = int(start) goal = int(goal) weights = None if use_weights and not self._use_dist_in_paths: print "Dropping path cache, because we use distance now." self._use_dist_in_paths = True self._path_cache = {} elif not use_weights and self._use_dist_in_paths: print "Dropping path cache, because we don't use distances anymore." self._use_dist_in_paths = False self._path_cache = {} if use_weights: weights = self._edge_dist if start == goal: pass # print "Start equals goal. Path will be empty." # assert goal != start try: path = self._path_cache[(start, goal)] # path_assert = list( # np.array(graph_tool.all.shortest_path(self._g, self._g.vertex(start), self._g.vertex(goal))[0], # dtype=int)) # if path_assert != path: # assert path == path_assert if len(path) < 2: raise KeyError return path except KeyError: pass try: path = copy.copy(self._path_cache[(goal, start)]) # type: list path.reverse() # path_assert = list( # np.array(graph_tool.all.shortest_path(self._g, self._g.vertex(start), self._g.vertex(goal))[0], # dtype=int)) # if path_assert != path: # assert path == path_assert if len(path) < 2: raise KeyError return path except KeyError: pass # path = list( # np.array(graph_tool.all.shortest_path(self._g, self._g.vertex(start), self._g.vertex(goal))[0], dtype=int)) # path_assert = list( # np.array(graph_tool.all.shortest_path(self._g, self._g.vertex(goal), self._g.vertex(start))[0], dtype=int)) # path_assert.reverse() # assert path == path_assert path = list( np.array(gt.shortest_path(self._g, self._g.vertex(start), self._g.vertex(goal), weights=weights)[0], dtype=int)) if len(path) < 2: print("path invalid: shorter than 2 for start != goal.") component_start = self.get_nodes_of_component(start) component_goal = self.get_nodes_of_component(goal) if goal not in component_start: print( "nodes {} and {} are not connected. Check Roadmap!".format( start, goal)) # if path[0] == 46 and path[-1] == 135: # print "here" # # if path[0] != start or path[-1] != goal: # print "path[0] != start or path[-1] != goal" self._path_cache[(start, goal)] = path # if not path: # print "Path is empty. Something is wrong." return path
def _yens_ksp(g, num_k, precursors_v, target_v, edge_prop="bool", weight_prop="weight"): """ Yen's Algorithm for k-shortest paths. Inspired by igraph implementation by Antonin Lenfant. Ref: Jin Y. Yen, "Finding the K Shortest Loopless Paths in a Network", Management Science, Vol. 17, No. 11, Theory Series (Jul., 1971), pp. 712-716. Args: g (gt.Graph): the graph-tool graph object. num_k (int): number of k shortest paths that should be found. precursors_v (gt.Vertex): graph-tool vertex object containing precursors. target_v (gt.Vertex): graph-tool vertex object containing target. edge_prop (str): name of edge property map which allows for filtering edges. Defaults to the word "bool". weight_prop (str): name of edge property map that stores edge weights/costs. Defaults to the word "weight". Returns: List of lists of graph vertices corresponding to each shortest path (sorted in increasing order by cost). """ def path_cost(vertices): """Calculates path cost given a list of vertices.""" cost = 0 for j in range(len(vertices) - 1): cost += g.ep[weight_prop][g.edge(vertices[j], vertices[j + 1])] return cost path = gt.shortest_path(g, precursors_v, target_v, weights=g.ep[weight_prop])[0] if not path: return [] a = [path] a_costs = [path_cost(path)] b = queue.PriorityQueue( ) # automatically sorts by path cost (priority) for k in range(1, num_k): try: prev_path = a[k - 1] except IndexError: print(f"Identified only k={k} paths before exiting. \n") break for i in range(len(prev_path) - 1): spur_v = prev_path[i] root_path = prev_path[:i] filtered_edges = [] for path in a: if len(path) - 1 > i and root_path == path[:i]: e = g.edge(path[i], path[i + 1]) if not e: continue g.ep[edge_prop][e] = False filtered_edges.append(e) gv = gt.GraphView(g, efilt=g.ep[edge_prop]) spur_path = gt.shortest_path(gv, spur_v, target_v, weights=g.ep[weight_prop])[0] for e in filtered_edges: g.ep[edge_prop][e] = True if spur_path: total_path = root_path + spur_path total_path_cost = path_cost(total_path) b.put((total_path_cost, total_path)) while True: try: cost_, path_ = b.get(block=False) except queue.Empty: break if path_ not in a: a.append(path_) a_costs.append(cost_) break return a
def matchGraphs(graph1, graph2): g1, pos1, weight1, clase1, nodetype1, age1 = graph1 g2, pos2, weight2, clase2, nodetype2, age2 = graph2 vertices1 = g1.get_vertices() vertices2 = g2.get_vertices() age = np.zeros_like(vertices1) for i in range(0, len(vertices1)): age[i] = age1[vertices1[i]] vertices1 = np.argsort(age)[::-1] pos_vertex2 = [] for i in vertices2: pos_vertex2.append(pos2[i]) pos_vertex2 = np.array(pos_vertex2) for i in vertices1: p1 = pos1[i] v, d = find_nearest_nodes(p1, pos_vertex2, 15) v = v[np.argsort(d)] if len(v) == 1: age2[v[0]] = age1[i] + 1 if nodetype2[v[0]] == "null": nodetype2[v[0]] = nodetype1[i] elif len(v) == 2: n_0 = len(g1.get_out_neighbours(i)) n_1 = len(g2.get_out_neighbours(v[0])) n_2 = len(g2.get_out_neighbours(v[1])) dif_a = np.abs(n_1 - n_0) dif_b = np.abs(n_2 - n_0) if dif_a <= dif_b: age2[v[0]] = age1[i] + 1 if nodetype2[v[0]] == "null": nodetype2[v[0]] = nodetype1[i] else: age2[v[1]] = age1[i] + 1 if nodetype2[v[1]] == "null": nodetype2[v[1]] = nodetype1[i] available = np.ones(pos_vertex2.shape[0]) ## If seed is not found => debug seed = gt.find_vertex(g2, nodetype2, "Ini") if len(seed) == 1: seed = seed[0] else: seed_prev = gt.find_vertex(g1, nodetype1, "Ini") p1 = pos1[seed_prev[0]] v, d = find_nearest_b(p1, pos_vertex2) if d < 20: age2[v] = age1[seed_prev[0]] + 1 nodetype2[v] = "Ini" seed = g2.vertex(v) available[v] = 0 else: print('No SEED') raise Exception("BAD TRACKING") pos_vertex2[:, 0] = pos_vertex2[:, 0] * available pos_vertex2[:, 1] = pos_vertex2[:, 1] * available ## If main root tip is not found => debug end = gt.find_vertex(g2, nodetype2, "FTip") if len(end) == 1: end = end[0] else: end_prev = gt.find_vertex(g1, nodetype1, "FTip") p1 = pos1[end_prev[0]] v, d = find_nearest_b(p1, pos_vertex2) if d < 20: age2[v] = age1[end_prev[0]] + 1 nodetype2[v] = "FTip" end = g2.vertex(v) else: v = np.argmax(pos_vertex2[:, 1]) nodetype2[v] = "FTip" end = g2.vertex(v) # print('No TIP') # raise Exception ("BAD TRACKING") vertices2 = g2.get_vertices() for i in vertices2: if age2[i] == 0: age2[i] == 1 if nodetype2[i] == "null": vecinos = g2.get_out_neighbours(i) if len(vecinos) > 1: nodetype2[i] = "Bif" else: if len(vecinos) == 1: nodetype2[i] = "LTip" # edge tracking camino, _ = gt.shortest_path(g2, seed, end, weights=weight2) l = len(camino) for k in range(0, l - 1): arista = g2.edge(camino[k], camino[k + 1]) clase2[arista][1] = 10 return [g2, pos2, weight2, clase2, nodetype2, age2]