def test_limited_descendants_at_distance(self): for distance, descendants in enumerate([{0}, {1}, {2}, {3, 7}, {4, 8}, {5, 9}, {6, 10}]): assert nx.descendants_at_distance(self.G, 0, distance) == descendants for distance, descendants in enumerate([{2}, {3, 7}, {8}, {9}, {10}]): assert nx.descendants_at_distance(self.D, 2, distance) == descendants
def _net_transform_step(net, step_type='factorization', t=None, h=None): tree = net.subnet_tree() root = (net.start, net.end) i = 0 queue = [root] # print(f'\n{step_type} attempt with t={t} h={h}') while queue: flag = False for subnet in queue: if step_type == 'factorization': res = net.factorize(subnet) elif step_type == 'division': res = net.divide(subnet, tree, t, h) else: raise ValueError flag = flag or res if res: net = res print(f'\tSuccess {step_type} of {subnet} ({i})') if flag: return net i += 1 queue = nx.descendants_at_distance(tree, root, i) return None
def subForest(rt, node, distance=0): '''Return a forst of RootedTree by finding subTree of children at the distance''' logger.warning('Depricated. Use RootedTree.subForest() instead') distance += 1 children = nx.descendants_at_distance(rt.directed, node, distance) subForests = [rt.subTree(child) for child in children] return subForests
def n_neighbor(g, node, dist): dist_range = list(range(1, dist + 1)) dist_range = sorted(dist_range, reverse=True) neighbors_set = set() for i in dist_range: neighbors_set |= nx.descendants_at_distance(g, node, distance=i) neighbors_set = list(neighbors_set) return sorted(neighbors_set, key=lambda x: int(x[0]))
def get_alternative_actors(actor): if get_index_from_title(actor) is None: candids = nx.descendants_at_distance(MG, actor, 3) result = "" for candid in candids: if get_index_from_title(candid) is None: result = result + ", " + candid print(actor + " ? " + result) return [candid] return []
def transitive_closure_dag(G, topo_order=None): """Returns the transitive closure of a directed acyclic graph. This function is faster than the function `transitive_closure`, but fails if the graph has a cycle. The transitive closure of G = (V,E) is a graph G+ = (V,E+) such that for all v, w in V there is an edge (v, w) in E+ if and only if there is a non-null path from v to w in G. Parameters ---------- G : NetworkX DiGraph A directed acyclic graph (DAG) topo_order: list or tuple, optional A topological order for G (if None, the function will compute one) Returns ------- NetworkX DiGraph The transitive closure of `G` Raises ------ NetworkXNotImplemented If `G` is not directed NetworkXUnfeasible If `G` has a cycle Examples -------- >>> DG = nx.DiGraph([(1, 2), (2, 3)]) >>> TC = nx.transitive_closure_dag(DG) >>> TC.edges() OutEdgeView([(1, 2), (1, 3), (2, 3)]) Notes ----- This algorithm is probably simple enough to be well-known but I didn't find a mention in the literature. """ if topo_order is None: topo_order = list(topological_sort(G)) TC = G.copy() # idea: traverse vertices following a reverse topological order, connecting # each vertex to its descendants at distance 2 as we go for v in reversed(topo_order): TC.add_edges_from((v, u) for u in nx.descendants_at_distance(TC, v, 2)) return TC
def bfs(size, graph): # save network nodes list in a variable nodes = list(graph.nodes(data=True)) # initialize a list which will be filled with appropriate sized modules module_list = [] # loop through all nodes for i in nodes: tree_level = 0 # initialize variable to save nodes found at the current tree level # until it reaches the appropriate size current_list = [] # loop while the current module has the given amount of nodes while len(current_list) < size: # nodes found at the current tree level current_nodes = list( nx.descendants_at_distance(graph, source=i[0], distance=tree_level)) tree_level += 1 # to avoid repeat of nodes at the current tree level compare nodes # at the current level and the nodes in current sized module overlap = set(current_list) & set(current_nodes) if len(overlap) == len(current_nodes): break else: if len(current_list) + len(current_nodes) < size: current_list = current_list + current_nodes else: n = size - len(current_list) sub_nodes = random.sample(current_nodes, n) current_list = current_list + sub_nodes # sort current module to be able to remove duplicated ones # from whole modules list later current_list.sort() module_list.append(current_list) # remove duplicated modules dup_free = [] dup_free_set = set() for x in module_list: if tuple(x) not in dup_free_set: dup_free.append(x) dup_free_set.add(tuple(x)) # network node coverage percentage coverage = (len(list(set(chain(*dup_free)))) / len(nodes)) * 100 # add module id column module_id = range(1, len(dup_free) + 1) modules = pd.DataFrame(dup_free) modules.insert(0, "", module_id) return [modules, coverage]
def force_field(G, day): reset_risk(G) for node in G.nodes(): node_infectiness = infectiness(day - G.nodes[node]["last_infection_time"]) #print("Node last infected at {} with infectiness {}".format(G.nodes[node]["last_infection_time"], node_infectiness)) if node_infectiness > 0: # print("computing force field diffusion") G.nodes[node]["cumulative_field_infectiness"] = node_infectiness for level in range(1, 4): level_descendents = nx.descendants_at_distance(G, node, level) # print("{} descendents at level {}".format(len(level_descendents), level)) for descendent in level_descendents: G.nodes[descendent]["cumulative_field_infectiness"] = max( G.nodes[descendent]["cumulative_field_infectiness"], node_infectiness * coefficients[level])
def pairs_from_bonds(bonds, distance=3): """ Generate pairs from bonds Parameters ---------- bonds : set bonds describing a molecule distance : int distance (in bonds) the pairs should have Returns ------- pairs : set """ pairs = set() G = nx.Graph(bonds) for atom1 in G.nodes: for atom2 in nx.descendants_at_distance(G, atom1, distance): pair = frozenset({atom1, atom2}) pairs.add(pair) return pairs
def dotgraph_html(zk, note: Note): # nbd = self.zk.get_notes_by_depth(root=note.nid) # maxdepth = min(2, len(nbd)) categories = collections.defaultdict(set) selected_nodes = {note.nid} # self.zk._graph.get_k_neighbors(note.nid) categories["self"].add(note.nid) try: # selected_nodes |= set(nx.dijkstra_path(zk._graph, zk.root, note.nid)) paths_from_root = set() for connection in nx.all_simple_paths(zk._graph, zk.root, note.nid): paths_from_root |= set(connection) categories["rootpath"] |= paths_from_root selected_nodes |= paths_from_root except nx.exception.NetworkXNoPath: logger.warning(f"No path from {zk.root} to {note.nid}") predecessors = set(zk._graph.predecessors(note.nid)) categories["predecessors"] |= predecessors selected_nodes |= predecessors descendants = set( nx.descendants_at_distance(zk._graph, note.nid, distance=1)) categories["descendants"] |= descendants selected_nodes |= descendants optional_nodes = set() for dist in range(2, 3): desc = set( nx.descendants_at_distance(zk._graph, note.nid, distance=dist)) categories["descendants"] |= desc optional_nodes |= desc for predecessor in zk._graph.predecessors(note.nid): sibl = set(zk._graph.successors(predecessor)) categories["siblings"] |= sibl optional_nodes |= sibl optional_nodes -= selected_nodes if len(selected_nodes) < 30: selected_nodes |= set( random.choices( list(optional_nodes), k=min(len(optional_nodes), 30 - len(selected_nodes)), )) def pick_color(note: Note): nid = note.nid if nid in categories["self"]: # red return "#fb8072" elif nid in categories["predecessors"]: # green return "#ccebc5" elif nid in categories["descendants"]: # yellow return "#ffed6f" elif nid in categories["siblings"]: # pink return "#fccde5" elif nid in categories["rootpath"]: # grayish return "#d9d9d9" else: return "red" out_lines = [] if len(selected_nodes) < 50: out_lines.append( '<script src="/static/js/vis-network.min.js"></script>\n') dgg = DotGraphGenerator(zk=zk) dgg.get_color = pick_color dotstr = dgg.graph_from_notes(selected_nodes) out_lines.append( _dotgraph_html.replace("{dotgraph}", dotstr).replace( "{height}", f"{400 + 20*len(selected_nodes)}px")) return out_lines
def tree_tensor_network_layer( beta, gamma, tree, tree_root, odd, initial_final=False, dag=False, extra_operators={} ): """Create tensors corresponding to one layer of QAOA Tree Tensor Network. Parameters ---------- beta: float The $\beta$ parameter of the mixing unitaries. gamma: float The $\gamma$ parameter of the Ising rotations. tree: NetworkX digraph The underlying tree of the Tree Tensor Network. tree_root: node The root of the underlying tree of the Tree Tensor Network. odd: bool Whether the layer is an even or odd one (even and odd layers have a different structure). initial_final: bool Whether the layer is either an initial or final layer. dag: bool Whether the layer is a dagger layer (that is, a layer implement part of $U^{\dagger}$ if $U$ is the QAOA unitary). extra_operators: dict A dictionary specifying the single-qubit operators to insert between $U$ and $U^{\dagger}$ is $U$ is the unitary implementing QAOA. In a (key, value) pair, the key is a qubit and the value is a Numpy array representing the single-qubit operator acting on this qubit. Returns ------- list A list of 3-tuples describing the TensorNetwork tensors constituting the layer. The elements of the 3-tuples are the following: - A TensorNetwork tensor. - The node of the underlying tree on which this tensor is based. - The successors of this base node in the underyling tree. """ tensors = [] if dag: beta = -beta gamma = -gamma for depth in range(int(odd), tree_tools.tree_depth(tree, tree_root), 2): for root in nx.descendants_at_distance(tree, tree_root, depth): successors = list(tree.successors(root)) ising_matrix = ising_rotation_matrix(gamma, [root] + successors, [(root, successor) for successor in successors]) extra_operators_matrix_factors = [] if odd: mixer_matrix_factors = [np.cos(beta / 2) * np.eye(2) - 1j * np.sin(beta / 2) * np.array([[0, 1], [1, 0]])] * (len(successors) + 1) extra_operators_matrix_factors = [extra_operators.get(node, np.eye(2)) for node in [root] + successors] elif root == tree_root: mixer_matrix_factors = [np.cos(beta / 2) * np.eye(2) - 1j * np.sin(beta / 2) * np.array([[0, 1], [1, 0]])] + [np.eye(2)] * len(successors) extra_operators_matrix_factors = [extra_operators.get(root, np.eye(2))] + [np.eye(2)] * len(successors) else: mixer_matrix_factors = [np.eye(2)] * (1 + len(successors)) extra_operators_matrix_factors = [np.eye(2)] * (1 + len(successors)) #print("qubits: {}".format([root] + successors, extra_operators_matrix_factors)) #print("factors: {}".format(extra_operators_matrix_factors)) mixer_matrix = reduce(np.kron, mixer_matrix_factors) extra_operators_matrix = reduce(np.kron, extra_operators_matrix_factors) if dag: matrix = ising_matrix @ mixer_matrix @ extra_operators_matrix else: matrix = extra_operators_matrix @ mixer_matrix @ ising_matrix if initial_final: if dag: matrix = reduce(np.kron, [np.ones(2) / np.sqrt(2)] * (len(successors) + 1)).T @ matrix else: matrix = matrix @ reduce(np.kron, [np.ones(2) / np.sqrt(2)] * (len(successors) + 1)) tensor = tn.Node(matrix.reshape((2,) * (len(successors) + 1))) tensors.append((tensor, root, successors)) else: tensor = tn.Node(matrix.reshape((2,) * 2 * (len(successors) + 1))) tensors.append((tensor, root, successors)) return tensors
argvs = sys.argv argc = len(argvs) if (argc < 2): print( 'Please give frovedis_server calling command as the first argument \n(e.g. "mpirun -np 2 /opt/nec/frovedis/ve/bin/frovedis_server")' ) quit() FrovedisServer.initialize(argvs[1]) frov_graph = fnx.read_edgelist(DATASET, nodetype=np.int32, delimiter=' ') fres = fnx.descendants_at_distance(frov_graph, src, distance) FrovedisServer.shut_down() except Exception as e: print("status=Exception: " + str(e)) sys.exit(1) #NetworkX try: nx_graph = nx.read_edgelist(DATASET, nodetype=np.int32, delimiter=' ') nres = nx.descendants_at_distance(nx_graph, src, distance) except Exception as e: print("status=Exception: " + str(e)) sys.exit(1) print(fres) print(nres) if len(fres - nres) == 0: print("status=Passed") else: print("status=Failed")
# -------- bfs demo -------- source = 1 distance = 4 frov_bfs_time = [] nx_bfs_time = [] result_matched = [] for i in range(len(frov_graph)): start_time = time.time() frov_res = fnx.descendants_at_distance(frov_graph[i], source, distance) frov_bfs_time.append(round(time.time() - start_time, 4)) #print(list(frov_res)[:5]) start_time = time.time() nx_res = nx.descendants_at_distance(nx_graph[i], source, distance) nx_bfs_time.append(round(time.time() - start_time, 4)) #print(list(nx_res)[:5]) result_matched.append("Yes" if len(frov_res - nx_res) == 0 else "No") bfs_df = pd.DataFrame( OrderedDict({ "dataset": list(input_graph_files.keys()), "frov_bfs_time": frov_bfs_time, "nx_bfs_time": nx_bfs_time, "result_matched": result_matched })) bfs_df["frov_speed_up"] = bfs_df["nx_bfs_time"] / bfs_df["frov_bfs_time"] print(bfs_df)
def children(self, node): return list(descendants_at_distance(self._graph, node, 1))
def subForest(self, node, distance=0): '''Return a forst of RootedTree by removing neigbhor of node in given distance''' distance += 1 children = nx.descendants_at_distance(self.directed, node, distance) return [self.subTree(child) for child in children]
def test_descendants_at_distance_missing_source(self): with pytest.raises(nx.NetworkXError): nx.descendants_at_distance(self.G, "abc", 0)
def test_descendants_at_distance(self): for distance, descendants in enumerate([{0}, {1}, {2, 3}, {4}]): assert nx.descendants_at_distance(self.G, 0, distance) == descendants
def path_to_node(self, G, source, target, rule='minimal'): """ Lay down path on G from source to target Possible rules: 'minimal' (default) only adds a new step if there exists a node at the same depth as source, such that labels(source) V labels(node) = labels(step) 'matching' creates all possible new steps, but only uses existing valid parents 'maximal' creates all possible new steps, and all possible valid parents """ source_cat = G.nodes('category')[source] targ_cat = G.nodes('category')[target] ds = len(source_cat) dt = len(targ_cat) steps = product(targ_cat - source_cat, [source_cat]) for s in steps: # we start by specifying the next step new_cat = set([s[0]]).union(s[1]) matching_nodes = [ G.nodes('category')[i] == new_cat for i in sorted(G) ] if np.any(matching_nodes): new_step = sorted(G)[np.where(matching_nodes)[0].item()] else: new_step = max(G) + 1 # print('%s->%s'%(source_cat,new_cat)) # find a spouse if it exists bachelors = nx.descendants_at_distance(G.reverse(), target, dt - ds) matching_nodes = [ G.nodes('category')[i].union(source_cat) == new_cat for i in bachelors ] if np.any(matching_nodes): # add spouses if they exist if new_step not in list(G): G.add_node(new_step, category=new_cat) for this_spouse in np.where( matching_nodes)[0]: # there are multiple parents G.add_edge(list(bachelors)[this_spouse], new_step) # print('%s+%s=%s'%(G.nodes('category')[list(bachelors)[this_spouse]],source_cat,new_cat)) elif rule == 'minimal': # don't make the child if there is no parent continue elif rule == 'maximal': # invent all possible parents if new_step not in list(G): G.add_node(new_step, category=new_cat) for sps in product(new_cat - source_cat, [source_cat]): new_spouse = max(G) + 1 G.add_node(new_spouse, category=set([sps[0]]).union(sps[1])) G.add_edge(new_spouse, new_step) if new_step not in list(G): G.add_node(new_step, category=new_cat) G.add_edge(source, new_step) # print('%s+%s=%s'%(G.nodes('category')[s],G.nodes('category')[source],new_cat)) if new_step != target: self.path_to_node(G, new_step, target, rule=rule)
#G.debug_print() print("Frovedis BFS edges: ", list(fnx.bfs_edges(G, source, depth_limit=depth))) print("NetworkX BFS edges: ", list(nx.bfs_edges(G_nx, source, depth_limit=depth))) print("Edges in Frovedis bfs_tree: ", fnx.bfs_tree(G, source, depth_limit=depth).number_of_edges()) print("Edges in NetworkX bfs_tree: ", nx.bfs_tree(G_nx, source, depth_limit=depth).number_of_edges()) print("Frovedis bfs_predecessors: ", list(fnx.bfs_predecessors(G, source, depth_limit=depth))) print("NetworkX bfs_predecessors: ", list(nx.bfs_predecessors(G_nx, source, depth_limit=depth))) print("Frovedis bfs_successors: ", list(fnx.bfs_successors(G, source, depth_limit=depth))) print("NetworkX bfs_successors: ", list(nx.bfs_successors(G_nx, source, depth_limit=depth))) print("Frovedis descendants at distance:", fnx.descendants_at_distance(G, source, distance=depth)) print("NetworkX descendants at distance:", nx.descendants_at_distance(G_nx, source, distance=depth)) # clean-up at the server side G.release() FrovedisServer.shut_down()