def test_disconnected_graph(): # https://github.com/networkx/networkx/issues/1144 G = nx.Graph() G.add_edges_from([(0, 1), (1, 2), (2, 0), (3, 4)]) assert_false(nx.is_tree(G)) G = nx.DiGraph() G.add_edges_from([(0, 1), (1, 2), (2, 0), (3, 4)]) assert_false(nx.is_tree(G))
def add_edge(self, u, v): print('[euler_tour_forest] add_edge(%r, %r)' % (u, v)) if self.has_edge(u, v): return ru = self.find_root(u) rv = self.find_root(v) if ru is None: self.add_node(u) ru = u if rv is None: self.add_node(v) rv = v assert ru is not rv, ( 'u=%r, v=%r not disjoint, can only join disjoint edges' % (u, v)) assert ru in self.trees, 'ru must be a root node' assert rv in self.trees, 'rv must be a root node' subtree1 = self.trees[ru] subtree2 = self.trees[rv] del self.trees[rv] new_tree = nx.compose(subtree1, subtree2) new_tree.add_edge(u, v) self.trees[ru] = new_tree print(list(new_tree.nodes())) assert nx.is_connected(new_tree) assert nx.is_tree(new_tree)
def euler_tour(G, node=None, seen=None, visited=None): """ definition from http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.192.8615&rep=rep1&type=pdf Example: >>> # DISABLE_DOCTEST >>> from utool.experimental.euler_tour_tree_avl import * # NOQA >>> edges = [ >>> ('R', 'A'), ('R', 'B'), >>> ('B', 'C'), ('C', 'D'), ('C', 'E'), >>> ('B', 'F'), ('B', 'G'), >>> ] >>> G = nx.Graph(edges) >>> node = list(G.nodes())[0] >>> et1 = euler_tour(G, node) >>> et2 = euler_tour_dfs(G, node) """ if node is None: node = next(G.nodes()) if visited is None: assert nx.is_tree(G) visited = [] if seen is None: seen = set([]) visited.append(node) for c in G.neighbors(node): if c in seen: continue seen.add(c) euler_tour(G, c, seen, visited) visited.append(node) return visited
def question4(T, node1, node2): BSTG=nx.from_numpy_matrix(np.matrix(T)) if (nx.is_tree(BSTG) & check_sum(T)): path = nx.all_simple_paths(BSTG, node1, node2) return min(list(path)[0]) else: print ("This graph is not a binary search tree") return None
def inspectlabels(milestone,sent): for h,d in sent.edges(): if type(sent[h][d]['deprel']) == str: pass else: print(milestone,"ARLAMA",sent) if not nx.is_tree(sent): print("not tree")
def span_makes_subtree(self, initidx, endidx): G = nx.DiGraph() span_nodes = list(range(initidx,endidx+1)) span_words = [self.node[x]["form"] for x in span_nodes] G.add_nodes_from(span_nodes) for h,d in self.edges(): if h in span_nodes and d in span_nodes: G.add_edge(h,d) return nx.is_tree(G)
def test_default_flow_function_karate_club_graph(self): G = nx.karate_club_graph() nx.set_edge_attributes(G, 1, 'capacity') T = nx.gomory_hu_tree(G) assert_true(nx.is_tree(T)) for u, v in combinations(G, 2): cut_value, edge = self.minimum_edge_weight(T, u, v) assert_equal(nx.minimum_cut_value(G, u, v), cut_value)
def test_karate_club_graph_cutset(self): G = nx.karate_club_graph() nx.set_edge_attributes(G, 1, 'capacity') T = nx.gomory_hu_tree(G) assert_true(nx.is_tree(T)) u, v = 0, 33 cut_value, edge = self.minimum_edge_weight(T, u, v) cutset = self.compute_cutset(G, T, edge) assert_equal(cut_value, len(cutset))
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Check that G is a tree if not nx.is_tree(self.G): raise ValueError( f"G is not a tree with edges {self.edges}. " "If a tree is not required, use the generic TaskGraph class." )
def to_tree(cls, node: nx.DiGraph, ctx): """Check graph structure and build nested dictionary.""" if not nx.is_tree(node): # no cycles, single tree raise ValueError("Graph must represent a tree.") keep_uuid = getattr(node, "_wx_keep_uuid_name", False) root = build_tree(node, tuple(node.nodes)[0], keep_uuid=keep_uuid) return dict(root_node=root)
def _tree_layout( G: nx.classes.graph.Graph, root_vertex: Union[Hashable, None], scale: float, ) -> dict: result = {root_vertex: np.array([0, 0, 0])} if not nx.is_tree(G): raise ValueError("The tree layout must be used with trees") if root_vertex is None: raise ValueError("The tree layout requires the root_vertex parameter") def _recursive_position_for_row( G: nx.classes.graph.Graph, result: dict, two_rows_before: List[Hashable], last_row: List[Hashable], current_height: float, ): new_row = [] for v in last_row: for x in G.neighbors(v): if x not in two_rows_before: new_row.append(x) new_row_length = len(new_row) if new_row_length == 0: return if new_row_length == 1: result[new_row[0]] = np.array([0, current_height, 0]) else: for i in range(new_row_length): result[new_row[i]] = np.array( [-1 + 2 * i / (new_row_length - 1), current_height, 0] ) _recursive_position_for_row( G, result, two_rows_before=last_row, last_row=new_row, current_height=current_height + 1, ) _recursive_position_for_row( G, result, two_rows_before=[], last_row=[root_vertex], current_height=1 ) height = max(map(lambda v: result[v][1], result)) return { v: np.array([pos[0], 1 - 2 * pos[1] / height, pos[2]]) * scale / 2 for v, pos in result.items() }
def hierarchy_pos(G, root=None, width=1., vert_gap=0.2, vert_loc=0, xcenter=0.5): if not nx.is_tree(G): raise TypeError( 'cannot use hierarchy_pos on a graph that is not a tree') if root is None: if isinstance(G, nx.DiGraph): root = next(iter(nx.topological_sort( G))) #allows back compatibility with nx version 1.11 else: root = random.choice(list(G.nodes)) def _hierarchy_pos(G, root, width=1., vert_gap=0.2, vert_loc=0, xcenter=0.5, pos=None, parent=None): ''' see hierarchy_pos docstring for most arguments pos: a dict saying where all nodes go if they have been assigned parent: parent of this branch. - only affects it if non-directed ''' if pos is None: pos = {root: (xcenter, vert_loc)} else: pos[root] = (xcenter, vert_loc) children = list(G.neighbors(root)) if not isinstance(G, nx.DiGraph) and parent is not None: children.remove(parent) if len(children) != 0: dx = width / len(children) nextx = xcenter - width / 2 - dx / 2 for child in children: nextx += dx pos = _hierarchy_pos(G, child, width=dx, vert_gap=vert_gap, vert_loc=vert_loc - vert_gap, xcenter=nextx, pos=pos, parent=root) return pos return _hierarchy_pos(G, root, width, vert_gap, vert_loc, xcenter)
def test_les_miserables_graph_cutset(self): G = nx.les_miserables_graph() nx.set_edge_attributes(G, 1, 'capacity') for flow_func in flow_funcs: T = nx.gomory_hu_tree(G, flow_func=flow_func) assert_true(nx.is_tree(T)) for u, v in combinations(G, 2): cut_value, edge = self.minimum_edge_weight(T, u, v) assert_equal(nx.minimum_cut_value(G, u, v), cut_value)
def tree_or_forest(graph): if nx.is_tree(graph): print( "The Minimum Spanning Tree Generated from this Network is a Tree") elif nx.is_forest(graph): print( "The Minimum Spanning Tree Generated from this Network is a Forest" ) else: print("Neither a Tree nor Forest")
def test_davis_southern_women_graph(self): G = nx.davis_southern_women_graph() nx.set_edge_attributes(G, 'capacity', 1) for flow_func in flow_funcs: T = nx.gomory_hu_tree(G, flow_func=flow_func) assert_true(nx.is_tree(T)) for u, v in combinations(G, 2): cut_value, edge = self.minimum_edge_weight(T, u, v) assert_equal(nx.minimum_cut_value(G, u, v), cut_value)
def test_florentine_families_graph(self): G = nx.florentine_families_graph() nx.set_edge_attributes(G, 1, 'capacity') for flow_func in flow_funcs: T = nx.gomory_hu_tree(G, flow_func=flow_func) assert_true(nx.is_tree(T)) for u, v in combinations(G, 2): cut_value, edge = self.minimum_edge_weight(T, u, v) assert_equal(nx.minimum_cut_value(G, u, v), cut_value)
def orient_junction_tree(t: nx.Graph): """Make oriented Junction tree out of an unoriented Junction tree, preserving node and edge informations""" assert nx.is_tree(t), "Graph must have tree structure" oriented = nx.bfs_tree(t, list(t.nodes)[0]) for n in oriented.nodes: oriented.node[n].update(t.node[n]) for e in oriented.edges: oriented[e[0]][e[1]].update(t[e[0]][e[1]]) return oriented
def _validate_graph(self, graph): """Private: Validate a graph is suitable for visualizer.""" if not issubclass(type(graph), ScaffoldGraph): raise ValueError(f'{graph} must be a subclass of ScaffoldGraph') if self._requires_tree: if not nx.is_tree(graph) or nx.is_forest(graph): msg = '{} requires a tree/forest structured graph' msg.format(self.__class__.__name__) raise ValueError(msg) return graph
def test_random_DAG(): import networkx as nx # import matplotlib.pyplot as plt # from networkx.drawing.nx_pydot import graphviz_layout con_pattern = lambda imax: min(int(exponential(5)), imax - 1) for i in range(5, 50): W = random_DAG(i) G = nx.convert_matrix.from_numpy_matrix(W, parallel_edges=False, create_using=nx.DiGraph) assert nx.is_directed_acyclic_graph(G), "G must be a DAG!" assert nx.is_tree(G), "G must be a tree!"
def test_florentine_families_graph(self): G = nx.florentine_families_graph() nx.set_edge_attributes(G, 'capacity', 1) for flow_func in flow_funcs: T = nx.gomory_hu_tree(G, flow_func=flow_func) assert_true(nx.is_tree(T)) for u, v in combinations(G, 2): cut_value, edge = self.minimum_edge_weight(T, u, v) assert_equal(nx.minimum_cut_value(G, u, v), cut_value)
def main(): args = read_arguments() filename = args.filename nodes = {} edges = {} actors = {} roots = [] digraph = nx.DiGraph() doc_title = filename.replace('.ann', '') with open(filename, 'r') as file_: for line in file_: if line.startswith('T'): name, label, text = line.split('\t')[:3] nodes[name] = {'label': label.split(' ')[0], 'text': text} digraph.add_node(name, { 'label': label.split(' ')[0], 'text': text }) if 'major-claim' in label: roots.append(name) elif line.startswith('R'): name, label = line.split('\t')[:2] label, destination, origin = label.split(' ') origin = origin.replace('Arg2:', '') destination = destination.replace('Arg1:', '') edges[name] = { 'label': label, 'origin': origin, 'destination': destination } digraph.add_edge(origin, destination, {'label': label}) elif line.startswith('A'): _, attribute_name, source, attribute_value = line.split() if attribute_name == 'ACTOR': actors[source] = attribute_value nx.set_node_attributes(digraph, 'actor', actors) data = {'name': doc_title.replace('_', ' '), 'children': []} # Transform digraph into a forest using the major-claims as tree roots. for root in roots: descendants = nx.descendants(digraph, root) descendants.add(root) subgraph = digraph.subgraph(descendants) if not nx.is_tree(subgraph): print('Subgraph that is not a tree founded') continue data['children'].append( json_graph.tree_data(subgraph, root=root, attrs={ 'children': 'children', 'id': 'name', 'actor': 'actor' })) with open('{}.json'.format(doc_title), 'w') as jf: json.dump(data, jf)
def coverage_BFS_single_source(self, infectG, subInfectG, source_ture): # 进行所有点有向树构建,再进行层次遍历。针对每一层都进行传播点/全部的比例计算。 node_every_ratio = [] for node_every in list(subInfectG.nodes()): #进行BFS树构造, tree = nx.bfs_tree(infectG, source=node_every) #进行层次遍历。返回每一层顶点。 BFS_nodes = commons.BFS_nodes(tree, node_every, infectG) ratio_all = 0 for layer_node in BFS_nodes: infect_node_len = len( [x for x in layer_node if infectG.node[x]['SI'] == 2]) # print('infect_node_len',infect_node_len) infect_node_not = len( [x for x in layer_node if infectG.node[x]['SI'] == 1]) # print('infect_node_not', infect_node_not) infect_ratio = infect_node_len / len(layer_node) #感染点的比例 ratio_all += infect_ratio ratio_average = ratio_all / len(BFS_nodes) node_every_ratio.append([node_every, ratio_average]) node_every_ratio_sort = sorted(node_every_ratio, key=lambda x: x[1], reverse=True) print(node_every_ratio_sort) print( 'distacne', nx.shortest_path_length(infectG, source=node_every_ratio_sort[0][0], target=source_ture)) #以第一个点进行BFS树构建,然后单源定位。 # plot_main. plot_G_node_color(subInfectG,[1])(infectG, subInfectG, source_ture, [node_every_ratio_sort[0][0]]) print('isTree,', nx.is_tree(subInfectG)) subinfectG = nx.bfs_tree(subInfectG, source=node_every_ratio_sort[0][0]) print('isTree,', nx.is_tree(subinfectG)) count_number = 0 undirectG = subinfectG.to_undirected() result_node = self.revsitionAlgorithm_singlueSource(undirectG) return result_node
def _validate_hierachy(self, hierarchy) -> None: """ Validate active hierarchy returned for the cause_set_id. Some of our cause hierarchies are not true trees. They can have more than one root node and each node may have more than one parent. For these reasons we can't use traditional methods for tree recognition and validation for all the hierarchies and must create our own suite of validations to confirm the fitness of the hierarchies used in the machinery run. This method creates a networkx digraph from the cause hierarchy dataframe and uses it to check for duplicates and validate tree structure for hierarchies other than the reporting aggregates hierarchy. The digraph may become more useful as validations are added or we can get rid of it entirely. """ G = nx.DiGraph() errors = "" for index, row in hierarchy.iterrows(): if row.cause_id == row.parent_id and row.level == 0: continue parent_df = (hierarchy.loc[hierarchy.cause_id == row.parent_id]) if len(parent_df) > 1 or G.has_edge(row.parent_id, row.cause_id): errors += (f'Duplicates found for cause_id {row.cause_id}, ' f'parent_id {row.parent_id}.\n') elif parent_df.empty: errors += ( f'The hierarchy is missing information for parent_id ' f'{row.parent_id}.\n') else: parent_level = parent_df.level.iat[0] edge_weight = row.level - parent_level G.add_edge(u_of_edge=row.parent_id, v_of_edge=row.cause_id, weight=edge_weight) if edge_weight != 1: errors += ( f'A child cause should be 1 level below its parent. ' f'parent_id {row.parent_id} has level {parent_level}. ' f'cause_id {row.cause_id} has level {row.level}.\n') if (self.set_id != constants.CauseSetId.REPORTING_AGGREGATES and not nx.is_tree(G)): errors += ('The hierarchy is not a tree. nx.is_tree() ' 'returned False\n') if errors: msg = (f"There are issues with the hierarchy for cause_set_id " f"{self.set_id}, cause_set_version_id " f"{self.set_version_id}\n{errors}") logging.error(msg) raise RuntimeError(msg)
def is_valid_network(G, T): """ Checks whether T is a valid network of G. Args: G: networkx.Graph T: networkx.Graph Returns: bool: whether T is a valid network """ return nx.is_tree(T) and nx.is_dominating_set(G, T.nodes)
def tree_stats(graphs): ''' Tree Stats will return a dict containing 1. ratio of valid trees 2. depth distribution ''' total_graphs = len(graphs) total_trees = sum(1 for g in graphs if nx.is_tree(g)) total_dags = sum(1 for g in graphs if nx.is_directed_acyclic_graph(g)) longest_path = [ nx.dag_longest_path_length(g) for g in graphs if nx.is_tree(g) ] return { 'istree_ratio': total_trees / total_graphs, 'dag_ratio': total_dags / total_graphs, 'longest_path': longest_path }
def is_path(g): # we know it's connected leaves = 0 for nd in g.nodes(): if g.degree(nd) == 1: leaves += 1 elif g.degree(nd) != 2: return False if leaves > 2: return False return nx.is_tree(g) and leaves == 2
def fit(self, X, y=None, sample_weight=None): """Fit underlying classifiers. Parameters ---------- X : (sparse) array-like, shape = [n_samples, n_features] Data. y : (sparse) array-like, shape = [n_samples, ], [n_samples, n_classes] Multi-class targets. An indicator matrix turns on multilabel classification. sample_weight : array-like, shape (n_samples,), optional (default=None) Weights applied to individual samples (1. for unweighted). Returns ------- self """ X, y = check_X_y(X, y, accept_sparse='csr') check_classification_targets(y) if sample_weight is not None: check_consistent_length(y, sample_weight) # Check that parameter assignment is consistent self._check_parameters() # Initialize NetworkX Graph from input class hierarchy self.class_hierarchy_ = self.class_hierarchy or make_flat_hierarchy( list(np.unique(y)), root=self.root) self.graph_ = DiGraph(self.class_hierarchy_) self.is_tree_ = is_tree(self.graph_) self.classes_ = list(node for node in self.graph_.nodes() if node != self.root) self.logger.debug("fit() - self.classes_ = %s", self.classes_) # Recursively build training feature sets for each node in graph with self._progress(total=self.n_classes_ + 1, desc="Building features") as progress: self._recursive_build_features(X, y, node_id=self.root, progress=progress) # Recursively train base classifiers with self._progress(total=self.n_classes_ + 1, desc="Training base classifiers") as progress: self._recursive_train_local_classifiers(X, y, node_id=self.root, progress=progress) return self
def main(): import pprint droid = Droid("../assets/day15-input") g, m = spread(droid, ' ') oxygen_location = next(coords for coords, t in m.items() if t == 'O') path = nx.shortest_path(g, source=(0, 0), target=oxygen_location) print("part 1:", len(path) - 1) t = nx.bfs_tree(g, source=oxygen_location) assert nx.is_tree(t) print("part 2:", tree_height(t, oxygen_location) - 1)
def compute_graph(self, skel, location_attr="loc", connectivity=26): sz = self.image.shape mask = self.image_labeled * 0 if skel.shape[0] == 0: return None mask[skel[:, 0], skel[:, 1], skel[:, 2]] = 1 locs_flattened = skel[:, 0] * sz[0] * sz[1] + skel[:, 1] * sz[0] + skel[:, 2] sorted_idxs = np.argsort(locs_flattened) coords_sorted = skel[sorted_idxs, :] graph = grid_to_graph( self.image.shape[0], self.image.shape[1], self.image.shape[2], mask=mask, connectivity=connectivity, ) g = GeometricGraph() nodes = [( node_id, { location_attr: coord, "intensity": self.image_int[coord[0], coord[1], coord[2]], }, ) for node_id, coord in enumerate(coords_sorted)] g.add_nodes_from(nodes) edges = [(a, b) for a, b in zip(graph.row, graph.col) if a > b] g.add_edges_from(edges) if not nx.is_tree(g): g.remove_cycles() print("*Converted to Tree?**") print(nx.is_tree(g)) print(len(g.nodes)) return g
def test_tree_with_integration_test(swarm_with_tree): try: swarm_with_tree.run() except: hashes = swarm_with_tree.tree.hash_to_ids epoch = swarm_with_tree.epoch raise ValueError("%s epoch: %s" % (hashes, epoch)) assert networkx.is_tree(swarm_with_tree.tree.data) best_ix = swarm_with_tree.walkers.states.cum_rewards.argmax() best_id = swarm_with_tree.walkers.states.id_walkers[best_ix] path = swarm_with_tree.tree.get_branch(best_id, from_hash=True)
def hierarchy_pos(self, root=0, width=1.0, vert_gap=0.2, vert_loc=0, xcenter=0.5): """compute abstract node positions of the tree From Joel's answer at https://stackoverflow.com/a/29597209/2966723. Licensed under Creative Commons Attribution-Share Alike """ G = self.nxgraph if not nx.is_tree(G): # raise TypeError("cannot use hierarchy_pos on a graph that is not a tree") self.pos2d = nx.kamada_kawai_layout(G) return def _hierarchy_pos( G, root, width=1.0, vert_gap=0.2, vert_loc=0, xcenter=0.5, pos=None, parent=None, ): if pos is None: pos = {root: (xcenter, vert_loc)} else: pos[root] = (xcenter, vert_loc) children = list(G.neighbors(root)) if not isinstance(G, nx.DiGraph) and parent is not None: children.remove(parent) if len(children) != 0: dx = width / len(children) nextx = xcenter - width / 2 - dx / 2 for child in children: nextx += dx pos = _hierarchy_pos( G, child, width=dx, vert_gap=vert_gap, vert_loc=vert_loc - vert_gap, xcenter=nextx, pos=pos, parent=root, ) return pos self.pos2d = _hierarchy_pos(G, root, width, vert_gap, vert_loc, xcenter)
def hierarchy_pos(self): ''' Modification of Joel's answer at https://stackoverflow.com/a/29597209/2966723. Licensed under Creative Commons Attribution-Share Alike If the graph is a tree this will return the positions to plot this in a hierarchical layout. Returns a dictionary with the hierarchy positions for a vertical tree or a horizontal tree. ''' if not nx.is_tree(self.G): #NODES NAMES MUST BE ALL DIFFERENT or else it won't create a tree raise TypeError('cannot use hierarchy_pos on a graph that is not a tree') if self.root is None: if isinstance(self.G, nx.DiGraph): self.root = next(iter(nx.topological_sort(self.G))) #allows back compatibility with nx version 1.11 else: self.root = random.choice(list(self.G.nodes)) def _hierarchy_pos(G, root, spread, gap, root_x, root_y, pos=None, parent=None): if pos is None: pos = {root:(root_x, root_y)} else: pos[root] = (root_x, root_y) children = list(G.neighbors(root)) if not isinstance(G, nx.DiGraph) and parent is not None: children.remove(parent) if len(children)!=0: sp = spread/len(children) #sp divides the spread by all children nextxV = root_x - spread/2 - sp/2 nextxH = root_y + spread/2 + sp/2 for child in children: if self.orientation == 'v': nextxV += sp #Next horizontal position for a Vertical graph pos = _hierarchy_pos(G,child, spread=sp, gap=gap, root_x=nextxV,root_y=root_y-gap, pos=pos, parent = root) elif self.orientation == 'h': nextxH -= sp #Next horizontal position for a Horizontal graph pos = _hierarchy_pos(G,child, spread=sp, gap=gap, root_y=nextxH,root_x=root_x+gap, pos=pos, parent = root) else: raise Exception("Not a valid command for variable orientation! \n\ A string is needed with the value 'v' for a vertical graph (top-down) or \n\ value 'h' for horizontal graph (left-right). Default is 'v'.") return pos return _hierarchy_pos(self.G, self.root, self.spread, self.gap, self.root_x, self.root_y, self.pos, self.parent)
def verify_decomp(g, decomp, width, length): sys.stderr.write("\nChecking decomposition\n") sys.stderr.flush() if not nx.is_tree(decomp): raise Exception("Decomposition is not tree") if set(decomp.nodes(data=True)[0][1]['component']) != set(g.nodes()): s = str(set(g.nodes()) - set(decomp.nodes(data=True)[0][1]['component'])) raise Exception("All nodes are not covered" + s) for curr in decomp.nodes(): tor = len(decomp[curr]) vertices = set() children = len(decomp[curr]) component = set(decomp.nodes(data=True)[curr][1]['component']) for node in decomp[curr]: # print decomp.nodes(data=True)[node][1] # exit(0) nodecomp = set(decomp.nodes(data=True)[node][1]['component']) if not nodecomp <= component: s = "Parent node missing vertices " + str(nodecomp) + str(component) raise Exception(s) vertices = vertices.union(nodecomp) for node1 in decomp[curr]: if node1 == node: continue node1comp = set(decomp.nodes(data=True)[node1][1]['component']) if node1comp & nodecomp: s = 'Appearing in multiple branches ' + str(node1comp) + str(nodecomp) raise Exception(s) if decomp.nodes(data=True)[curr][1]['level'] < length-1: if len(set(component) - vertices) + len(decomp[curr]) + 1 > width: raise Exception("Higher torso size for bag %i than width %i" % (curr, width)) elif len(set(component) - vertices) + len(decomp[curr]) > width: raise Exception("Higher torso size for bag %i than width %i" % (curr, width)) incident_edges = list() for e in g.edges(list(vertices)): if not (e[0] in component and e[1] in component): incident_edges.append(e) # try: # incident_edges.remove(e) # sys.stderr.write("\ndeleted edge %s\n"%str(e)) # except: # try: # incident_edges.remove((e[1],e[0])) # sys.stderr.write("\ndeleted edge %s\n" % str(e[1],e[0])) # except: # sys.stderr.write("\nskipped edge %s\n"%str(e)) # pass if len(incident_edges) > width: raise Exception("Higher adhesion than width") sys.stderr.write("Correct decomposition\n") sys.stderr.flush()
def _checkTree(self, checkTree, graph): """ Raises an AssertionError if the DFS tree is not actually a tree. As we add all nodes from the original graph in the tree during initialization, this test fails when the tree is not an acyclic connected graph. """ if not checkTree: return for n in self._tree: assert self._tree.nodes[n]['visited'] assert nx.is_tree(self._tree)
def is_tree(request): """Function for determination is graph tree or no This function is getting a graph and response: "1" -- it is a tree, "0" -- it is not a tree. """ raw_data = request.GET.dict() graph_data = json.loads(raw_data["graph"]) matrix = np.matrix(cn.to_matrix(graph_data)) graph = create_graph(matrix, graph_data) data = {"result": int(nx.is_tree(graph))} return JsonResponse(data)
def make_tree(self, ast: nx.DiGraph, root=None): if root is None: assert nx.is_tree(ast) for node in ast.nodes: if not list(ast.predecessors(node)): root = node break assert root is not None return self._make_tree( root, ast )
def pairwise_dists(G): ''' Given adjacency matrix A, Return: D: np array with same shape as A, s.t. D[i, j] is shortest distance from i to j ''' if nx.is_tree(G): yield from pairwise_tree_distance(G) else: for s, tdt in nx.all_pairs_dijkstra_path_length(G).items(): for t, dt in tdt.items(): yield (s, t), dt
def stamp_and_approve(self): '''Mandatory method to validate and seal the execution tree such that it can be enacted by an agent Raises ------ ValueError If the execution units do not form a tree ''' if not nx.is_tree(self.tree): raise ValueError('The plan graph is not structured like a tree') self.tree_root_id = self._get_root_index(self.tree)
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 hierarchy_pos(G, root=None, width=.5, vert_gap=0.2, vert_loc=0, xcenter=0.5): ''' From Joel's answer at https://stackoverflow.com/a/29597209/2966723. ''' if not nx.is_tree(G): raise TypeError( 'cannot use hierarchy_pos on a graph that is not a tree') if root is None: if isinstance(G, nx.DiGraph): root = next(iter(nx.topological_sort( G))) #allows back compatibility with nx version 1.11 else: root = random.choice(list(G.nodes)) def _hierarchy_pos(G, root, width=1., vert_gap=0.2, vert_loc=0, xcenter=0.5, pos=None, parent=None): if pos is None: pos = {root: (xcenter, vert_loc)} else: pos[root] = (xcenter, vert_loc) children = list(G.neighbors(root)) if not isinstance(G, nx.DiGraph) and parent is not None: children.remove(parent) if len(children) != 0: dx = width / len(children) nextx = xcenter - width / 2 - dx / 2 for child in children: nextx += dx pos = _hierarchy_pos(G, child, width=dx, vert_gap=vert_gap, vert_loc=vert_loc - vert_gap, xcenter=nextx, pos=pos, parent=root) return pos return _hierarchy_pos(G, root, width, vert_gap, vert_loc, xcenter)
def default(self, obj): if isinstance(obj, np.ndarray): return obj.tolist() elif isinstance(obj, np.generic): return obj.item() elif isinstance(obj, nx.Graph) or isinstance(obj, nx.DiGraph): if nx.is_tree(obj): # NOTE: the root must be the first node added. otherwise it won't work return json_graph.tree_data(obj, obj.nodes_iter().next()) else: return json_graph.node_link_data(obj) elif isinstance(obj, pd.DataFrame): return obj.to_dict(orient='records') return json.JSONEncoder.default(self, obj)
def _graphml2nx(fname): g=nx.DiGraph() def _attrdict(node): attrs=node.attributes() return {key:attrs[key].value for key in attrs if key not in attr_blacklist} parser=GraphMLParser() imported_graph=parser.parse(fname) edges=[(edge.node1.id, edge.node2.id) for edge in imported_graph.edges()] nodes=[(node.id, _attrdict(node)) for node in imported_graph.nodes()] g.add_edges_from(edges) g.add_nodes_from(nodes) assert(nx.is_tree(g)) assert(nx.is_directed(g)) return g
def default(self, obj): if isinstance(obj, np.ndarray): return obj.tolist() elif isinstance(obj, np.generic): return obj.item() elif isinstance(obj, nx.Graph) or isinstance(obj, nx.DiGraph): if nx.is_tree(obj) and 'root' in obj.graph: # NOTE: there must be a root graph attribute, or the root must be the first node added. # otherwise it won't work return json_graph.tree_data(obj, obj.graph['root']) else: return json_graph.node_link_data(obj) elif isinstance(obj, pd.DataFrame): return obj.to_dict(orient='records') return json.JSONEncoder.default(self, obj)
def test_wikipedia_example(self): # Example from https://en.wikipedia.org/wiki/Gomory%E2%80%93Hu_tree G = nx.Graph() G.add_weighted_edges_from(( (0, 1, 1), (0, 2, 7), (1, 2, 1), (1, 3, 3), (1, 4, 2), (2, 4, 4), (3, 4, 1), (3, 5, 6), (4, 5, 2), )) for flow_func in flow_funcs: T = nx.gomory_hu_tree(G, capacity='weight', flow_func=flow_func) assert_true(nx.is_tree(T)) for u, v in combinations(G, 2): cut_value, edge = self.minimum_edge_weight(T, u, v) assert_equal(nx.minimum_cut_value(G, u, v, capacity='weight'), cut_value)
def check_spanning_tree(tree): '''Check that a graph is a spanning tree. Parameters ---------- tree : networkx graph ''' nodes = np.array(tree.nodes()) n_nodes = len(nodes) edges = np.array(tree.edges()) n_edges = len(edges) # check number of edges if not n_nodes - 1 == n_edges: raise ValueError('Incorrect number of edes in graph.') # check that graph is a tree if not nx.is_tree(tree): raise TypeError('Must input a tree.')
def modif_free_mwe_labels(sent,most_common_label_filler): for h,d in sent.edges(): if sent[h][d]["deprel"] in freemwes: head_over_mwe = sent.head_of(h) overall_mwe_function = sent[head_over_mwe][h]['deprel'] if type(overall_mwe_function) == str: if "_" in overall_mwe_function or overall_mwe_function.startswith("mwe"): pass else: sent[h][d]["deprel"] = sent[h][d]["deprel"]+"_rmwe_"+most_common_label_filler[overall_mwe_function] else: #pass print("MUCHO WRONG",h,d,overall_mwe_function) print(sent, sent.edges(),nx.is_tree(sent)) return sent
def to_dict_tree(digraph, root): import networkx as nx """ Convert a networkx.DiGraph to a tree. (king, (governor,(editor,)), (state,(collapse,),(head,)(lord,))) """ assert nx.is_tree(digraph) str2node = {root: []} for parent, child in nx.traversal.dfs_edges(digraph, root): score = digraph.edge[parent][child]['score'] childnode = {child: [], 'score': score} children = str2node[parent] children.append(childnode) str2node[child] = childnode[child] return {root: str2node[root]}
def optimal_placement(tree, budget): """ Place `budget` sensors on a tree in an optimal way. Parameters ---------- tree : networkx.Graph A tree (undirected) on which to place the sensors. budget : int The sensor budget, i.e. the number of nodes that can be chosen as sensors Returns ------- (perr, obs) : tuple `perr` is the error probability, and `obs` a tuple containing the sensors. """ #one single sensor is useless assert budget >= 2 assert nx.is_tree(tree) leaves = utilities.find_leaves(tree) if budget >= len(leaves): return (0, tuple(leaves)) #define a non-leaf root arbitrarily root = random.choice(filter(lambda x: x not in leaves, tree.nodes())) directed = nx.dfs_tree(tree, source=root) #dir DFS tree from source #compute the subtree sizes for x in directed: directed.node[x]['size'] = utilities.size_subtree(directed, x) utilities.size_subtree.cache_clear() #add the budget and the root to the tree as an attribute directed.graph['root'] = root directed.graph['budget'] = budget #place the sensors using the DP algorithm err, obs = _opt(directed, root, budget) _optc.cache_clear() _opt.cache_clear() return (float(err) / len(tree), obs)
def is_forest(G): """Return True if the input graph is a forest Parameters ---------- G : NetworkX Graph An undirected graph. Returns ------- True if the input graph is a forest Notes ----- For undirected graphs only. """ for graph in nx.connected_component_subgraphs(G): if not nx.is_tree(graph): return False return True
def test_is_tree(self): assert_true(nx.is_tree(self.T2)) assert_true(nx.is_tree(self.T3)) assert_true(nx.is_tree(self.T5))
def find_root(G): """Returns root node ID for the Graph.""" if not nx.is_tree(G): return None return nx.topological_sort(G)[0]
def _keep_fused_form(self,posPreferenceDicts): # For a span A,B and external tokens C, such as A > B > C, we have to # Make A the head of the span # Attach C-level tokens to A #Remove B-level tokens, which are the subtokens of the fused form della: de la if self.graph["multi_tokens"] == {}: return spanheads = [] spanhead_fused_token_dict = {} # This double iteration is overkill, one could skip the spanhead identification # but in this way we avoid modifying the tree as we read it for fusedform_idx in sorted(self.graph["multi_tokens"]): fusedform_start, fusedform_end = self.graph["multi_tokens"][fusedform_idx]["id"] fuseform_span = list(range(fusedform_start,fusedform_end+1)) spanhead = self._choose_spanhead_from_heuristics(fuseform_span,posPreferenceDicts) #if not spanhead: # spanhead = self._choose_spanhead_from_heuristics(fuseform_span,posPreferenceDicts) spanheads.append(spanhead) spanhead_fused_token_dict[spanhead] = fusedform_idx bottom_up_order = [x for x in nx.topological_sort(self) if x in spanheads] for spanhead in bottom_up_order: fusedform_idx = spanhead_fused_token_dict[spanhead] fusedform = self.graph["multi_tokens"][fusedform_idx]["form"] fusedform_start, fusedform_end = self.graph["multi_tokens"][fusedform_idx]["id"] fuseform_span = list(range(fusedform_start,fusedform_end+1)) if spanhead: #Step 1: Replace form of head span (A) with fusedtoken form -- in this way we keep the lemma and features if any self.node[spanhead]["form"] = fusedform # 2- Reattach C-level (external dependents) to A #print(fuseform_span,spanhead) internal_dependents = set(fuseform_span) - set([spanhead]) external_dependents = [nx.bfs_successors(self,x) for x in internal_dependents] for depdict in external_dependents: for localhead in depdict: for ext_dep in depdict[localhead]: deprel = self[localhead][ext_dep]["deprel"] self.remove_edge(localhead,ext_dep) self.add_edge(spanhead,ext_dep,deprel=deprel) #3- Remove B-level tokens for int_dep in internal_dependents: self.remove_edge(self.head_of(int_dep),int_dep) self.remove_node(int_dep) #4 reconstruct tree at the very end new_index_dict = {} for new_node_index, old_node_idex in enumerate(sorted(self.nodes())): new_index_dict[old_node_idex] = new_node_index T = DependencyTree() # Transfer DiGraph, to replace self for n in sorted(self.nodes()): T.add_node(new_index_dict[n],self.node[n]) for h, d in self.edges(): T.add_edge(new_index_dict[h],new_index_dict[d],deprel=self[h][d]["deprel"]) #4A Quick removal of edges and nodes self.__init__() #4B Rewriting the Deptree in Self # TODO There must a more elegant way to rewrite self -- self= T for instance? for n in sorted(T.nodes()): self.add_node(n,T.node[n]) for h,d in T.edges(): self.add_edge(h,d,T[h][d]) # 5. remove all fused forms form the multi_tokens field self.graph["multi_tokens"] = {} if not nx.is_tree(self): print("Not a tree after fused-form heuristics:",self.get_sentence_as_string())
def from_dict(self, data): # Check that the dict has the expected keys if not criros.utils.has_keys(data, ['nodes','properties','root','title']): self.logger.logdebug('Dict does not have the expected keys') return False # Create a graph and check that it's a tree graph = nx.DiGraph() nodes = dict() blacklist = [] # Process the nodes for identifier, spec in data['nodes'].items(): # Get the children of the current node if spec.has_key('child'): self.children[identifier].append(spec['child']) elif spec.has_key('children'): self.children[identifier] = spec['children'] # Check spec has the expected fields if not criros.utils.has_keys(spec, ['id','name','properties','title']): self.logger.logdebug( 'Node [{0}] does not have the expected keys'.format(identifier) ) blacklist += self.children[identifier] continue # Check soundness if identifier != spec['id']: self.logger.logdebug( 'Identifier miss-match {0} != {1}'.format(identifier, spec['id']) ) blacklist += self.children[identifier] continue # Skip blacklisted nodes if identifier in blacklist: self.logger.logdebug( 'Skiping blacklisted node {0}:{1}'.format(spec['title'], identifier) ) blacklist += self.children[identifier] continue # Get node class and initialize it nodeclass = get_class_from_str(spec['name']) if nodeclass is None: self.logger.logdebug( 'Node {0}:{1} has unknown node class: {2}'.format(spec['title'], identifier, spec['name']) ) blacklist += self.children[identifier] continue if behave.core.Action not in inspect.getmro(nodeclass): self.logger.logdebug( 'Node {0}:{1} has invalid node class: {2}'.format(spec['title'], identifier, spec['name']) ) self.logger.logdebug( 'It must inherit from any of these: (Action, Composite, Decorator)' ) blacklist += self.children[identifier] continue nodes[identifier] = nodeclass(identifier, title=spec['title'], properties=spec['properties']) # Populate the graph for child in self.children[identifier]: graph.add_edge(identifier, child) if len(graph) == 0: self.logger.logdebug( 'Failed parsing dict. Empty graph' ) return False if not nx.is_tree(graph): self.logger.logdebug( 'Failed parsing dict. Graph must be a tree' ) return False for identifier in nodes.keys(): # Add the children for the nodes that were created for child_id in self.children[identifier]: if child_id in nodes.keys(): # Depending on the type of class we add children or specify the child if behave.core.Composite in inspect.getmro( type(nodes[identifier]) ): nodes[identifier].add_child( nodes[child_id] ) elif behave.core.Decorator in inspect.getmro( type(nodes[identifier]) ): nodes[identifier].set_child( nodes[child_id] ) else: self.logger.logdebug( 'Node {0}:{1} has invalid node class: {2}'.format(spec['title'], identifier, spec['name']) ) self.logger.logdebug( 'To have children it must inherit from any of these: (Composite, Decorator)' ) # Store details in self.graph as well graph.node[identifier] = data['nodes'][identifier]['properties'] graph.node[identifier]['children'] = self.children[identifier] graph.node[identifier]['class'] = nodes[identifier].name graph.node[identifier]['category'] = nodes[identifier].category graph.node[identifier]['title'] = nodes[identifier].title graph.node[identifier]['label'] = nodes[identifier].label graph.node[identifier]['shape'] = nodes[identifier].shape # Set-up the class if data.has_key('id'): self.identifier = data['id'] self.root = data['root'] self.graph = graph self.nodes = nodes self.initialized = True return True
def test_dag_nontree(): G = nx.DiGraph() G.add_edges_from([(0,1), (0,2), (1,2)]) assert_false(nx.is_tree(G)) assert_true(nx.is_directed_acyclic_graph(G))
def test_is_not_tree(self): assert_false(nx.is_tree(self.N4)) assert_false(nx.is_tree(self.N5)) assert_false(nx.is_tree(self.N6))
# Create G and H G = nx.Graph() H = nx.Graph() G.add_nodes_from([1,2,3,4,5,6,7]) G.add_edge(1,2) G.add_edge(1,3) G.add_edge(2,4) G.add_edge(2,5) G.add_edge(3,6) G.add_edge(3,7) H.add_nodes_from([8,9,10]) H.add_edge(8,9) H.add_edge(8,10) print nx.is_tree(G) print nx.is_tree(H) print subtree_isomorphism(G, H) G = nx.Graph() G.add_nodes_from([1,2,3,4,5]) G.add_edge(1,2) G.add_edge(2,3) G.add_edge(3,4) G.add_edge(4,5) print nx.is_tree(G) print nx.is_tree(H) print subtree_isomorphism(G, H)
def to_nested_tuple(T, root, canonical_form=False): """Returns a nested tuple representation of the given tree. The nested tuple representation of a tree is defined recursively. The tree with one node and no edges is represented by the empty tuple, ``()``. A tree with ``k`` subtrees is represented by a tuple of length ``k`` in which each element is the nested tuple representation of a subtree. Parameters ---------- T : NetworkX graph An undirected graph object representing a tree. root : node The node in ``T`` to interpret as the root of the tree. canonical_form : bool If ``True``, each tuple is sorted so that the function returns a canonical form for rooted trees. This means "lighter" subtrees will appear as nested tuples before "heavier" subtrees. In this way, each isomorphic rooted tree has the same nested tuple representation. Returns ------- tuple A nested tuple representation of the tree. Notes ----- This function is *not* the inverse of :func:`from_nested_tuple`; the only guarantee is that the rooted trees are isomorphic. See also -------- from_nested_tuple to_prufer_sequence Examples -------- The tree need not be a balanced binary tree:: >>> T = nx.Graph() >>> T.add_edges_from([(0, 1), (0, 2), (0, 3)]) >>> T.add_edges_from([(1, 4), (1, 5)]) >>> T.add_edges_from([(3, 6), (3, 7)]) >>> root = 0 >>> nx.to_nested_tuple(T, root) (((), ()), (), ((), ())) Continuing the above example, if ``canonical_form`` is ``True``, the nested tuples will be sorted:: >>> nx.to_nested_tuple(T, root, canonical_form=True) ((), ((), ()), ((), ())) Even the path graph can be interpreted as a tree:: >>> T = nx.path_graph(4) >>> root = 0 >>> nx.to_nested_tuple(T, root) ((((),),),) """ def _make_tuple(T, root, _parent): """Recursively compute the nested tuple representation of the given rooted tree. ``_parent`` is the parent node of ``root`` in the supertree in which ``T`` is a subtree, or ``None`` if ``root`` is the root of the supertree. This argument is used to determine which neighbors of ``root`` are children and which is the parent. """ # Get the neighbors of `root` that are not the parent node. We # are guaranteed that `root` is always in `T` by construction. children = set(T[root]) - {_parent} if len(children) == 0: return () nested = (_make_tuple(T, v, root) for v in children) if canonical_form: nested = sorted(nested) return tuple(nested) # Do some sanity checks on the input. if not nx.is_tree(T): raise nx.NotATree('provided graph is not a tree') if root not in T: raise nx.NodeNotFound('Graph {} contains no node {}'.format(T, root)) return _make_tuple(T, root, None)
def to_prufer_sequence(T): r"""Returns the Prüfer sequence of the given tree. A *Prüfer sequence* is a list of *n* - 2 numbers between 0 and *n* - 1, inclusive. The tree corresponding to a given Prüfer sequence can be recovered by repeatedly joining a node in the sequence with a node with the smallest potential degree according to the sequence. Parameters ---------- T : NetworkX graph An undirected graph object representing a tree. Returns ------- list The Prüfer sequence of the given tree. Raises ------ NetworkXPointlessConcept If the number of nodes in `T` is less than two. NotATree If `T` is not a tree. KeyError If the set of nodes in `T` is not {0, …, *n* - 1}. Notes ----- There is a bijection from labeled trees to Prüfer sequences. This function is the inverse of the :func:`from_prufer_sequence` function. Sometimes Prüfer sequences use nodes labeled from 1 to *n* instead of from 0 to *n* - 1. This function requires nodes to be labeled in the latter form. You can use :func:`~networkx.relabel_nodes` to relabel the nodes of your tree to the appropriate format. This implementation is from [1]_ and has a running time of $O(n \log n)$. See also -------- to_nested_tuple from_prufer_sequence References ---------- .. [1] Wang, Xiaodong, Lei Wang, and Yingjie Wu. "An optimal algorithm for Prufer codes." *Journal of Software Engineering and Applications* 2.02 (2009): 111. <http://dx.doi.org/10.4236/jsea.2009.22016> Examples -------- There is a bijection between Prüfer sequences and labeled trees, so this function is the inverse of the :func:`from_prufer_sequence` function: >>> edges = [(0, 3), (1, 3), (2, 3), (3, 4), (4, 5)] >>> tree = nx.Graph(edges) >>> sequence = nx.to_prufer_sequence(tree) >>> sequence [3, 3, 3, 4] >>> tree2 = nx.from_prufer_sequence(sequence) >>> list(tree2.edges()) == edges True """ # Perform some sanity checks on the input. n = len(T) if n < 2: msg = 'Prüfer sequence undefined for trees with fewer than two nodes' raise nx.NetworkXPointlessConcept(msg) if not nx.is_tree(T): raise nx.NotATree('provided graph is not a tree') if set(T) != set(range(n)): raise KeyError('tree must have node labels {0, ..., n - 1}') degree = dict(T.degree()) def parents(u): return next(v for v in T[u] if degree[v] > 1) index = u = min(k for k in range(n) if degree[k] == 1) result = [] for i in range(n - 2): v = parents(u) result.append(v) degree[v] -= 1 if v < index and degree[v] == 1: u = v else: index = u = min(k for k in range(index + 1, n) if degree[k] == 1) return result
import networkx as nx import matplotlib.pyplot as plt T=nx.DiGraph() N=11 T.add_nodes_from(range(6)) T.add_edges_from(zip( range(0,N,2), range(1,N,2))) T.add_edges_from(zip( range(0,N-1,2), range(2,N,2))) print T.edges() assert nx.is_tree(T) nx.draw(T) #nx.draw_spectral(T) plt.show()
def test_multicycle(): G = nx.MultiDiGraph() G.add_edges_from([(0,1), (0,1)]) assert_false(nx.is_tree(G)) assert_true(nx.is_directed_acyclic_graph(G))