def node_scores_from_tree(tree, r, prize_key='r', cost_key='c', score_func=log_x_density): """ return the score of each node """ assert nx.is_arborescence(tree) ret = {} def aux(n): if tree.out_degree(n) == 0: # leaf, ignore return tree.node[n][prize_key], 0 else: prize_sum, cost_sum = 0, 0 for c in tree.neighbors(n): prize, cost = aux(c) prize_sum += prize cost_sum += cost cost_sum += tree[n][c][cost_key] prize_sum += tree.node[n][prize_key] ret[n] = score_func(prize_sum, cost_sum) return prize_sum, cost_sum aux(r) return ret
def treat_cycles(self): """Find and treat cycles in a TSD diagram. Returns: (list): The unique tree TSDs associated to a non-tree TSD. """ graphs = [self.graph] tree_graphs = [] cycles_left = True while cycles_left: for gr_index, graph in reversed_enumerate(graphs): graphs += disentangle_cycle(graph, find_cycle(graph)) del graphs[gr_index] cycles_left = False for graph_indx, graph in reversed_enumerate(graphs): if nx.is_arborescence(graph): tree_graphs.append(graph) del graphs[graph_indx] else: cycles_left = True tree_graphs_uniq = [] for t_graph in tree_graphs: for t_graph_uniq in tree_graphs_uniq: if nx.edges(t_graph) == nx.edges(t_graph_uniq): break # If the TSD is a new one else: tree_graphs_uniq.append(t_graph) return tree_graphs_uniq
def test_notarborescence1(): # Not an arborescence due to not spanning. G = nx.MultiDiGraph() G.add_nodes_from(range(10)) G.add_edges_from([(0,1),(0,2),(1,3),(5,6)]) assert_true(nx.is_branching(G)) assert_false(nx.is_arborescence(G))
def test_notbranching1(): # Acyclic violation. G = nx.MultiDiGraph() G.add_nodes_from(range(10)) G.add_edges_from([(0, 1), (1, 0)]) assert not nx.is_branching(G) assert not nx.is_arborescence(G)
def binarize(t): """Make an arborescence binary branching. Every interior node v with more than two children is split into r-1 copies labeled (v,0), ..., (v,r-2). """ if not networkx.is_arborescence(t): raise ValueError("t must be an arborescence") t1 = networkx.DiGraph(**t.graph) def visit(node): children = t.successors(node) if len(children) > 2: prev = visit(children[0]) for i, child in enumerate(children[1:]): new = (node, i) t1.add_node(new, **t.node[node]) t1.add_edge(new, prev) t1.add_edge(new, visit(child), **t.edge[node][child]) prev = new return prev else: t1.add_node(node, **t.node[node]) for child in children: t1.add_edge(node, visit(child), **t.edge[node][child]) return node t1.graph['root'] = visit(t.graph['root']) return t1
def test_notarborescence2(): # Not an arborescence due to in-degree violation. G = nx.MultiDiGraph() nx.add_path(G, range(5)) G.add_edge(6, 4) assert_false(nx.is_branching(G)) assert_false(nx.is_arborescence(G))
def test_notarborescence1(): # Not an arborescence due to not spanning. G = nx.MultiDiGraph() G.add_nodes_from(range(10)) G.add_edges_from([(0, 1), (0, 2), (1, 3), (5, 6)]) assert nx.is_branching(G) assert not nx.is_arborescence(G)
def test_notarborescence2(): # Not an arborescence due to in-degree violation. G = nx.MultiDiGraph() nx.add_path(G, range(5)) G.add_edge(6, 4) assert not nx.is_branching(G) assert not nx.is_arborescence(G)
def treeConverter(self): # getting root root = [ n for n in self.Graph.nodes() if len(list(self.Graph.predecessors(n))) == 0 ][0] self.root = root is_treee = nx.is_tree(self.Graph) is_arb = nx.is_arborescence(self.Graph) if not is_arb: logging.info( "Arborescence is not possible due to in-bound and out-bound edges. Therefore converting to tree using BFS." ) self.DAG2Tree() else: logging.info("Converting dag to tree") arb_graph = nx.minimum_spanning_arborescence(self.Graph) if nx.is_tree(arb_graph): logging.info( "Converted to tree! But some information is lost...") nx.write_edgelist(arb_graph, self.edgelist_file) self.removeParantheses(self.edgelist_file) nx.write_graphml(arb_graph, self.gml_file) self.Graph = arb_graph
def node_scores_from_tree( tree, r, prize_key='r', cost_key='c', score_func=log_x_density): """ return the score of each node """ assert nx.is_arborescence(tree) ret = {} def aux(n): if tree.out_degree(n) == 0: # leaf, ignore return tree.node[n][prize_key], 0 else: prize_sum, cost_sum = 0, 0 for c in tree.neighbors(n): prize, cost = aux(c) prize_sum += prize cost_sum += cost cost_sum += tree[n][c][cost_key] prize_sum += tree.node[n][prize_key] ret[n] = score_func(prize_sum, cost_sum) return prize_sum, cost_sum aux(r) return ret
def test_notbranching2(): # In-degree violation. G = nx.MultiDiGraph() G.add_nodes_from(range(10)) G.add_edges_from([(0, 1), (0, 2), (3, 2)]) assert not nx.is_branching(G) assert not nx.is_arborescence(G)
def test_notbranching1(): # Acyclic violation. G = nx.MultiDiGraph() G.add_nodes_from(range(10)) G.add_edges_from([(0,1),(1,0)]) assert_false(nx.is_branching(G)) assert_false(nx.is_arborescence(G))
def test_notbranching2(): # In-degree violation. G = nx.MultiDiGraph() G.add_nodes_from(range(10)) G.add_edges_from([(0,1),(0,2),(3,2)]) assert_false(nx.is_branching(G)) assert_false(nx.is_arborescence(G))
def tree_leaf_number(tree): """ :param tree: tree :return: the numbre of nodes of the tree """ if not(nx.is_arborescence(tree)): raise ValueError('this should be an arborescence') #erreur return(len([x for x in tree.nodes() if tree.out_degree(x)==0 and tree.in_degree(x)==1]))
def checkDFR(self, preAdd=0): totalAlphas = float(self._pToTheE)**(len(self._list[0]._nodesList) * self._numCopies) - preAdd startTime = time.time() curTime = time.time() print("Checking if ", self._numCopies, "-DFR") print("q = ", self._pToTheE) print("Number of alphas to check: ", totalAlphas) print("Progress: ") sys.stdout.write("0%") if nx.is_arborescence(self._list[0]._base_graph): print("No Top Nodes") return True alphasCount = 0 for i in range(preAdd): self.addAlpha(False) self.updateN() while (self.addAlpha()): # Let's print our current progress: alphasCount += 1 curTime = time.time() sys.stdout.write("\r") sys.stdout.flush() sys.stdout.write("AlphaCount: " + str(alphasCount).zfill(5) + " (" + str(round(alphasCount * 100 / totalAlphas, 2)) + "%)") curTime = time.time() elapsedTime = round(curTime - startTime, 1) sys.stdout.write(", ElapsedTime: " + str(elapsedTime)) aveTimePerAlpha = round(elapsedTime / alphasCount, 3) sys.stdout.write(", AveTimePerAlpha: " + str(aveTimePerAlpha)) remainingTime = floor(aveTimePerAlpha * (totalAlphas - alphasCount)) sys.stdout.write(", TimeRemaining(est): " + str(remainingTime).zfill(6) + " ") #sys.stdout.write(str( alphasCount*100/totalAlphas ) + "%" ) if not self.alphaSumCongruences(): continue #if you checked all the deltas and none of them worked, return False if not self.checkAllDeltas(): print("\nFound some alphas that did not work: \n") self.display() print("Total time: ", floor(time.time() - startTime)) return False #if you've gone through all the alphas, then it's DFR print("\nChecked all the alphas. Found no counterexamples. ") print("Total time: ", floor(time.time() - startTime)) return True
def test_single_root(self): """Tests that a directed acyclic graph with a single degree zero node produces an arborescence. """ G = nx.DiGraph([(0, 1), (0, 2), (1, 3), (2, 3)]) B = nx.dag_to_branching(G) expected = nx.DiGraph([(0, 1), (1, 3), (0, 2), (2, 4)]) assert nx.is_arborescence(B) assert nx.is_isomorphic(B, expected)
def test_single_root(self): """Tests that a directed acyclic graph with a single degree zero node produces an arborescence. """ G = nx.DiGraph([(0, 1), (0, 2), (1, 3), (2, 3)]) B = nx.dag_to_branching(G) expected = nx.DiGraph([(0, 1), (1, 3), (0, 2), (2, 4)]) assert_true(nx.is_arborescence(B)) assert_true(nx.is_isomorphic(B, expected))
def determine_soma_type(graph): assert nx.is_arborescence(graph), "graph must be an acyclic directed tree\n" \ "see http://networkx.readthedocs.io/en/networkx-1.11/reference/algorithms.tree.html" rootNodes = [n for n, d in graph.in_degree().items() if d == 0] assert len(rootNodes) == 1, "graph has more than one roots" rootNode = rootNodes[0] if graph.node[rootNode]["type"] == 1: # Collect, along with that of the root, IDs of all nodes that have a # continuous path to the root that consists only of soma nodes. somaConnectedNodeIDs = [] for parentNode, childNodeList in nx.dfs_successors( graph, rootNode).items(): parentType = graph.node[parentNode]["type"] for childNode in childNodeList: childType = graph.node[childNode]["type"] if parentType == 1 and childType == 1: somaConnectedNodeIDs.append(childNode) # if there are zero or one child(ren) of the root that are of type 1 => 1-point soma if len(somaConnectedNodeIDs) in [0, 1]: return 0 if len(somaConnectedNodeIDs) == 2: # if there are two children of the root that are of type 1 => 3-point soma if graph.predecessors(somaConnectedNodeIDs[0])[0] is rootNode and \ graph.predecessors(somaConnectedNodeIDs[1])[0] is rootNode: return 1 # if there are two non-child nodes connected to the root that are of type 1 => multiple cylinder soma else: return 2 # if there are more than two nodes connected to the root of type 1 => multiple cylinder soma elif len(somaConnectedNodeIDs) > 2: return 2 # if root type is not 1 => no soma else: return 3
def parse_consensus( axon: Path, dendrite: Path, transform: Path, offset=np.array([0, 0, 0]), resolution=np.array([1, 1, 1]), transpose=[0, 1, 2], ): axon_graph = parse_swc(axon, transform, offset, resolution, transpose) assert nx.is_arborescence(axon_graph), "Axon graph is not an arborescence!" dendrite_graph = parse_swc(dendrite, transform, offset, resolution, transpose) assert nx.is_arborescence( dendrite_graph), "Dendrite graph is not an arborescence!" consensus_graph = merge_graphs(axon_graph, dendrite_graph) consensus_graph.graph["spacing"] = resolution consensus_graph.graph["origin"] = offset return consensus_graph
def test_bs_ensure_result_is_tree(self): params = pkl.load( open(make_path('test/data/quota_test_cases/params.pkl')))[0] root = params['roots'][0] preprune_secs = params['preprune_secs'] mg = IU.get_topic_meta_graph_from_synthetic( make_path('test/data/quota_test_cases/interactions.json'), preprune_secs) dag = IU.get_rooted_subgraph_within_timespan(mg, root, preprune_secs) t = charikar_algo(dag, root, dag.nodes(), k=20, level=2) assert_true(nx.is_arborescence(t))
def test_multiple_roots(self): """Tests that a directed acyclic graph with multiple degree zero nodes creates an arborescence with multiple (weakly) connected components. """ G = nx.DiGraph([(0, 1), (0, 2), (1, 3), (2, 3), (5, 2)]) B = nx.dag_to_branching(G) expected = nx.DiGraph([(0, 1), (1, 3), (0, 2), (2, 4), (5, 6), (6, 7)]) assert_true(nx.is_branching(B)) assert_false(nx.is_arborescence(B)) assert_true(nx.is_isomorphic(B, expected))
def test_multiple_roots(self): """Tests that a directed acyclic graph with multiple degree zero nodes creates an arborescence with multiple (weakly) connected components. """ G = nx.DiGraph([(0, 1), (0, 2), (1, 3), (2, 3), (5, 2)]) B = nx.dag_to_branching(G) expected = nx.DiGraph([(0, 1), (1, 3), (0, 2), (2, 4), (5, 6), (6, 7)]) assert nx.is_branching(B) assert not nx.is_arborescence(B) assert nx.is_isomorphic(B, expected)
def PROCESS_CONFIG(config): if config['data']['tree'] is not None: tree = config['data']['tree'] if type(tree) not in (nx.DiGraph, nx.MultiDiGraph, nx.OrderedDiGraph, nx.OrderedMultiDiGraph): raise Exception('Circle Pack needs a directed networkx graph as input data.') if not nx.is_arborescence(tree): raise Exception('Circle Pack needs a tree as input.') if 'root' not in tree.graph: raise Exception('Circle Pack needs a \'root\' attribute in the graph.')
def tree(self): rslt = {} rslt['is_tree'] = nx.is_tree(self.graph) rslt['is_forest'] = nx.is_forest(self.graph) if self.directed == 'directed': rslt['is_arborescence'] = nx.is_arborescence(self.graph) rslt['is_branching'] = nx.is_branching(self.graph) fname_tree = self.DIR + '/tree.json' with open(fname_tree, "w") as f: json.dump(rslt, f, cls=SetEncoder, indent=2) print(fname_tree)
def to_bracket_notation(tree): def aux(node): nbrs = sorted(tree.neighbors(node)) if len(nbrs) == 0: return '{%s}' % node else: return '{%s%s}' % (node, ''.join([aux(n) for n in nbrs])) if tree.number_of_nodes() == 0: return '{}' else: assert nx.is_arborescence(tree), tree.nodes() return aux(get_roots(tree)[0])
def calc_tree(node_i, r, dag, U, gen_tree_func, gen_tree_kws, print_summary, should_binarize_dag=False): print('root', r) logger.info('nodes procssed {}'.format(node_i)) if len(dag.edges()) == 0: logger.debug("empty rooted sub graph") assert dag.number_of_nodes() == 1 return dag if gen_tree_kws.get('dijkstra'): logger.debug('applying dijkstra') dag = remove_edges_via_dijkstra( dag, source=r, weight=IU.EDGE_COST_KEY ) if should_binarize_dag: logger.debug('binarizing dag...') dag = binarize_dag(dag, IU.VERTEX_REWARD_KEY, IU.EDGE_COST_KEY, dummy_node_name_prefix="d_") logger.debug('generating tree ') print(dag.number_of_nodes()) tree = gen_tree_func(dag, r, U) if should_binarize_dag: tree = unbinarize_dag(tree, edge_weight_key=IU.EDGE_COST_KEY) if len(tree.edges()) == 0: logger.debug("empty event tree") if print_summary: logger.debug('tree summary:\n{}'.format(get_summary(tree))) # post checking if tree.number_of_edges() == 0: assert tree.number_of_nodes() == 1, '#roots={}'.format( tree.number_of_nodes() ) else: assert nx.is_arborescence(tree), 'not a tree' return tree
def to_bracket_notation(tree): def aux(node): nbrs = sorted(tree.neighbors(node)) if len(nbrs) == 0: return '{%s}' % node else: return '{%s%s}' % ( node, ''.join([aux(n) for n in nbrs]) ) if tree.number_of_nodes() == 0: return '{}' else: assert nx.is_arborescence(tree), tree.nodes() return aux(get_roots(tree)[0])
def calc_tree(node_i, r, dag, U, gen_tree_func, gen_tree_kws, print_summary, should_binarize_dag=False): print('root', r) logger.info('nodes procssed {}'.format(node_i)) if len(dag.edges()) == 0: logger.debug("empty rooted sub graph") assert dag.number_of_nodes() == 1 return dag if gen_tree_kws.get('dijkstra'): logger.debug('applying dijkstra') dag = remove_edges_via_dijkstra(dag, source=r, weight=IU.EDGE_COST_KEY) if should_binarize_dag: logger.debug('binarizing dag...') dag = binarize_dag(dag, IU.VERTEX_REWARD_KEY, IU.EDGE_COST_KEY, dummy_node_name_prefix="d_") logger.debug('generating tree ') print(dag.number_of_nodes()) tree = gen_tree_func(dag, r, U) if should_binarize_dag: tree = unbinarize_dag(tree, edge_weight_key=IU.EDGE_COST_KEY) if len(tree.edges()) == 0: logger.debug("empty event tree") if print_summary: logger.debug('tree summary:\n{}'.format(get_summary(tree))) # post checking if tree.number_of_edges() == 0: assert tree.number_of_nodes() == 1, '#roots={}'.format( tree.number_of_nodes()) else: assert nx.is_arborescence(tree), 'not a tree' return tree
def test_bs_ensure_result_is_tree(self): params = pkl.load( open(make_path('test/data/quota_test_cases/params.pkl')) )[0] root = params['roots'][0] preprune_secs = params['preprune_secs'] mg = IU.get_topic_meta_graph_from_synthetic( make_path('test/data/quota_test_cases/interactions.json'), preprune_secs ) dag = IU.get_rooted_subgraph_within_timespan( mg, root, preprune_secs ) t = charikar_algo(dag, root, dag.nodes(), k=20, level=2) assert_true(nx.is_arborescence(t))
def test_gen_event_with_known_tree_structure(): event_size = 100 participants_n = 10 event = gen_event_with_known_tree_structure( event_size=event_size, participants=range(participants_n), start_time=10, end_time=110, event_topic_param=random_topic(10, topic_noise=0.0001)[0], topic_noise=1, alpha=1.0, tau=0.8, forward_proba=0.3, reply_proba=0.5, create_new_proba=0.2 ) for n in event.nodes_iter(): sid, rid = event.node[n]['sender_id'], event.node[n]['recipient_ids'][0] assert_true(sid != rid) for s, t in event.edges_iter(): sid1, rid1 = event.node[s]['sender_id'], event.node[s]['recipient_ids'][0] sid2, rid2 = event.node[t]['sender_id'], event.node[t]['recipient_ids'][0] c_type = event[s][t]['c_type'] if c_type == 'r': assert_equal(sid1, rid2) assert_equal(sid2, rid1) elif c_type == 'f': assert_equal(rid1, sid2) assert_true(rid2 != sid1) else: assert_equal(sid1, sid2) interactions = [event.node[n] for n in event.nodes_iter()] g = IU.get_meta_graph( interactions, decompose_interactions=False, remove_singleton=True, given_topics=True, convert_time=False ) assert_equal(1, len(get_roots(g))) assert_equal(event_size, len(interactions)) assert_true(nx.is_arborescence(event))
def maximum_tree(G, root=0, step=0): """ :param G: graph of type networkx Graph :param root: the root node :param step: this function being recursive, the step tells us how deep we are with the recursion. :return: a maximum spanning tree of the graph G, of type network Graph. """ G = prepare(G, root) P = greedy(G, root) if nx.is_arborescence(P): return P else: # there is a cycle C = nx.find_cycle(P, orientation='ignore') G, dictionary_cleanup = cleanup(G, root) G_contracted, dictionary = contract(G, C, root=root, step=step) T_contracted = maximum_tree(G_contracted, root=root, step=step + 1) T_expanded = expand(T_contracted, C, dictionary, root=root, step=step) T_expanded = uncleanup(T_expanded, dictionary_cleanup, root=root) return T_expanded
def __init__(self, bmbpt_diag): """Generate a tsd diagram out of a BMBPT one. Args: bmbpt_diag (BmbptFeynmanDiagram): The BMBPT graph used to be turned into a TSD. """ adg.diag.Diagram.__init__(self, time_structure_graph(bmbpt_diag)) self.tags = [bmbpt_diag.unique_id] self.perms = {bmbpt_diag.unique_id: {i: i for i in range(len(self.graph))}} self.equivalent_trees = [] if nx.is_arborescence(self.graph): self.is_tree = True self.expr = "\\frac{1}{%s}" % tree_time_structure_den(self.graph) self.resum = self.resummation_power() else: self.is_tree = False self.expr = "" self.resum = 0
def subtree(T=nx.DiGraph(), src="", D=[]): """ Sous arbre :param T: :param src: :param D: :return: """ tcopy = T.copy() w = tcopy.graph mytree = nx.DiGraph(wavelength=w['wavelength']) # L'arbre à construire) nodes_set = set([src] + D) edges_set = set() for i in D: path = nx.shortest_path(tcopy, src, i) edges_i_set = set() for i in range(0, len(path) - 1): edges_i_set.update({(path[i], path[i + 1])}) edges_set.update(edges_i_set) nodes_list = list(nodes_set) edges_list = list(edges_set) print(edges_list) mytree.add_nodes_from(nodes_list) mytree.add_edges_from(edges_list) for n in mytree.nodes(): if n in T.nodes(): mytree.nodes[n]['node_data'] = T.nodes[n]['node_data'] for e in edges_list: try: mytree[e[0]][e[1]]['edge_data'] = T[e[0]][e[1]]['edge_data'] except: print("ERREUR!!!") print("Nodes", mytree.nodes(data=True)) print('Edges', mytree.edges(data=True)) print('Wavelength', mytree.graph) print("ARBORESCENCE", nx.is_arborescence(mytree)) return mytree
def print_is_of_type_attrs(graph): print("\n====== is of type X? ======") print("Directed? ->", "Yes" if nx.is_directed(graph) else "No") print("Directed acyclic? ->", "Yes" if nx.is_directed_acyclic_graph(graph) else "No") print("Weighted? ->", "Yes" if nx.is_weighted(graph) else "No") if nx.is_directed(graph): print("Aperiodic? ->", "Yes" if nx.is_aperiodic(graph) else "No") print("Arborescence? ->", "Yes" if nx.is_arborescence(graph) else "No") print("Weakly Connected? ->", "Yes" if nx.is_weakly_connected(graph) else "No") print("Semi Connected? ->", "Yes" if nx.is_semiconnected(graph) else "No") print("Strongly Connected? ->", "Yes" if nx.is_strongly_connected(graph) else "No") else: print("Connected? ->", "Yes" if nx.is_connected(graph) else "No") print("Bi-connected? ->", "Yes" if nx.is_biconnected(graph) else "No") if not graph.is_multigraph(): print("Chordal? -> ", "Yes" if nx.is_chordal(graph) else "No") print("Forest? -> ", "Yes" if nx.is_chordal(graph) else "No") print("Distance regular? -> ", "Yes" if nx.is_distance_regular(graph) else "No") print("Eulerian? -> ", "Yes" if nx.is_eulerian(graph) else "No") print("Strongly regular? -> ", "Yes" if nx.is_strongly_regular(graph) else "No") print("Tree? -> ", "Yes" if nx.is_tree(graph) else "No")
def merge_graphs(axon: nx.DiGraph, dendrite: nx.DiGraph) -> nx.DiGraph: axon = nx.convert_node_labels_to_integers(axon, ordering="sorted") for node, node_attrs in axon.nodes.items(): node_attrs["neuron_part"] = 1 next_node_id = len(axon.nodes) dendrite = nx.convert_node_labels_to_integers(dendrite, ordering="sorted", first_label=next_node_id) nx.relabel.relabel_nodes(dendrite, {next_node_id: 0}, copy=False) for node, node_attrs in dendrite.nodes.items(): node_attrs["neuron_part"] = 0 if node == 0 else 2 consensus_graph = nx.compose(axon, dendrite) for node, node_attrs in consensus_graph.nodes.items(): assert "neuron_part" in node_attrs assert nx.is_arborescence( consensus_graph), "Consensus graph is not an arborescence!" assert all( np.isclose(axon.nodes[0]["location"], consensus_graph.nodes[0]["location"])) return consensus_graph
def ScenarioTreeModelFromNetworkX( tree, node_name_attribute=None, edge_probability_attribute='probability', stage_names=None, scenario_name_attribute=None): """ Create a scenario tree model from a networkx tree. The height of the tree must be at least 1 (meaning at least 2 stages). Optional Arguments: - node_name_attribute: By default, node names are the same as the node hash in the networkx tree. This keyword can be set to the name of some property of nodes in the graph that will be used for their name in the PySP scenario tree. - edge_probability_attribute: Can be set to the name of some property of edges in the graph that defines the conditional probability of that branch (default: 'probability'). If this keyword is set to None, then all branches leaving a node are assigned equal conditional probabilities. - stage_names: Can define a list of stage names to use (assumed in time order). The length of this list much match the number of stages in the tree. - scenario_name_attribute: By default, scenario names are the same as the leaf-node hash in the networkx tree. This keyword can be set to the name of some property of leaf-nodes in the graph that will be used for their corresponding scenario in the PySP scenario tree. Examples: - A 2-stage scenario tree with 10 scenarios: G = networkx.DiGraph() G.add_node("Root") N = 10 for i in range(N): node_name = "Leaf"+str(i) G.add_node(node_name) G.add_edge("Root",node_name,probability=1.0/N) model = ScenarioTreeModelFromNetworkX(G) - A 4-stage scenario tree with 125 scenarios: branching_factor = 5 height = 3 G = networkx.balanced_tree( branching_factory, height, networkx.DiGraph()) model = ScenarioTreeModelFromNetworkX( G, edge_probability_attribute=None) """ if not has_networkx: raise ValueError("networkx module is not available") if not networkx.is_tree(tree): raise TypeError( "object is not a tree (see networkx.is_tree)") if not networkx.is_directed(tree): raise TypeError( "object is not directed (see networkx.is_directed)") if not networkx.is_branching(tree): raise TypeError( "object is not a branching (see networkx.is_branching") if not networkx.is_arborescence(tree): raise TypeError("Object must be a directed, rooted tree " "in which all edges point away from the " "root (see networkx.is_arborescence)") root = [u for u,d in tree.in_degree().items() if d == 0] assert len(root) == 1 root = root[0] num_stages = networkx.eccentricity(tree, v=root) + 1 if num_stages < 2: raise ValueError( "The number of stages must be at least 2") m = CreateAbstractScenarioTreeModel() if stage_names is not None: unique_stage_names = set() for cnt, stage_name in enumerate(stage_names,1): m.Stages.add(stage_name) unique_stage_names.add(stage_name) if cnt != num_stages: raise ValueError( "incorrect number of stages names (%s), should be %s" % (cnt, num_stages)) if len(unique_stage_names) != cnt: raise ValueError("all stage names were not unique") else: for i in range(num_stages): m.Stages.add('Stage'+str(i+1)) node_to_name = {} node_to_scenario = {} def _setup(u, succ): if node_name_attribute is not None: if node_name_attribute not in tree.node[u]: raise KeyError( "node '%s' missing name attribute: '%s'" % (u, node_name_attribute)) node_name = tree.node[u][node_name_attribute] else: node_name = u node_to_name[u] = node_name m.Nodes.add(node_name) if u in succ: for v in succ[u]: _setup(v, succ) else: # a leaf node if scenario_name_attribute is not None: if scenario_name_attribute not in tree.node[u]: raise KeyError( "node '%s' missing attribute: '%s'" % (u, scenario_name_attribute)) scenario_name = tree.node[u][scenario_name_attribute] else: scenario_name = u node_to_scenario[u] = scenario_name m.Scenarios.add(scenario_name) _setup(root, networkx.dfs_successors(tree, root)) m = m.create_instance() def _add_node(u, stage, succ, pred): if node_name_attribute is not None: if node_name_attribute not in tree.node[u]: raise KeyError( "node '%s' missing name attribute: '%s'" % (u, node_name_attribute)) node_name = tree.node[u][node_name_attribute] else: node_name = u m.NodeStage[node_name] = m.Stages[stage] if u == root: m.ConditionalProbability[node_name] = 1.0 else: assert u in pred edge = tree.edge[pred[u]][u] probability = None if edge_probability_attribute is not None: if edge_probability_attribute not in edge: raise KeyError( "edge '(%s, %s)' missing probability attribute: '%s'" % (pred[u], u, edge_probability_attribute)) probability = edge[edge_probability_attribute] else: probability = 1.0/len(succ[pred[u]]) m.ConditionalProbability[node_name] = probability if u in succ: child_names = [] for v in succ[u]: child_names.append( _add_node(v, stage+1, succ, pred)) total_probability = 0.0 for child_name in child_names: m.Children[node_name].add(child_name) total_probability += \ value(m.ConditionalProbability[child_name]) if abs(total_probability - 1.0) > 1e-5: raise ValueError( "edge probabilities leaving node '%s' " "do not sum to 1 (total=%r)" % (u, total_probability)) else: # a leaf node scenario_name = node_to_scenario[u] m.ScenarioLeafNode[scenario_name] = node_name m.Children[node_name].clear() return node_name _add_node(root, 1, networkx.dfs_successors(tree, root), networkx.dfs_predecessors(tree, root)) return m
def test_path(): G = nx.DiGraph() nx.add_path(G, range(5)) assert_true(nx.is_branching(G)) assert_true(nx.is_arborescence(G))
def test_emptybranch(): G = nx.DiGraph() G.add_nodes_from(range(10)) assert_true(nx.is_branching(G)) assert_false(nx.is_arborescence(G))
def decompose( self, topology: nx.Graph = None ) -> Iterator[Union[CNot, XPow, YPow, ZPow]]: """ Returns a Circuit corresponding to the exponential of the Pauli algebra element object, i.e. exp[-1.0j * alpha * element] If a qubit topology is provided then the returned circuit will respect the qubit connectivity, adding swaps as necessary. """ # Kudos: Adapted from pyquil. The topological network is novel. circ = Circuit() element = self.element alpha = self.alpha if element.is_identity() or element.is_zero(): return circ # pragma: no cover # TESTME # Check that all terms commute groups = pauli_commuting_sets(element) if len(groups) != 1: raise ValueError("Pauli terms do not all commute") for qbs, ops, coeff in element: if not np.isclose(complex(coeff).imag, 0.0): raise ValueError("Pauli term coefficients must be real") theta = complex(coeff).real * alpha if len(ops) == 0: continue # TODO: 1-qubit terms special case active_qubits = set() change_to_z_basis = Circuit() for qubit, op in zip(qbs, ops): active_qubits.add(qubit) if op == "X": change_to_z_basis += Y(qubit)**-0.5 elif op == "Y": change_to_z_basis += X(qubit)**0.5 if topology is not None: if not nx.is_directed(topology) or not nx.is_arborescence( topology): # An 'arborescence' is a directed tree active_topology = steiner_tree(topology, active_qubits) center = nx.center(active_topology)[0] active_topology = nx.dfs_tree(active_topology, center) else: active_topology = topology else: active_topology = nx.DiGraph() nx.add_path(active_topology, reversed(list(active_qubits))) cnot_seq = Circuit() order = list(reversed(list(nx.topological_sort(active_topology)))) for q0 in order[:-1]: q1 = list(active_topology.pred[q0])[0] if q1 not in active_qubits: cnot_seq += Swap(q0, q1) active_qubits.add(q1) else: cnot_seq += CNot(q0, q1) circ += change_to_z_basis circ += cnot_seq circ += Z(order[-1])**(2 * theta / np.pi) circ += cnot_seq.H circ += change_to_z_basis.H # end term loop yield from circ # type: ignore
# build graphs G = nx.DiGraph() G.add_edges_from(relations) # go through components, positive filter of non-tree families graphs = list() for family in nx.weakly_connected_components(G): fam = {'nodes': [], 'edges': []} # build individual family separately F = nx.DiGraph() for lemma in family: for parent in rels[lemma]: F.add_edge(parent, lemma) # check treenes of family, print non-tree graphs if not nx.is_tree(F) or not nx.is_arborescence(F): # filter our already annotated families if any([True for l in F.nodes if l in annotated]): continue for node in F.nodes: fam['nodes'].append({'data': {'id': node}}) for target, source in F.edges: fam['edges'].append({ 'data': { 'source': source, 'target': target, 'intoTree': 'solid' } }) graphs.append(fam)
def test_path(): G = nx.DiGraph() G.add_path(range(5)) assert_true(nx.is_branching(G)) assert_true(nx.is_arborescence(G))
def test_emptybranch(): G = nx.DiGraph() G.add_nodes_from(range(10)) assert nx.is_branching(G) assert not nx.is_arborescence(G)
def test_path(): G = nx.DiGraph() nx.add_path(G, range(5)) assert nx.is_branching(G) assert nx.is_arborescence(G)