def append_to(self: T, new_parent: T) -> T: """Move this node (and its subtree) to be the last child of the new_parent. This requires modifying all of the subtree's identifiers.""" prev_parent = self.parent() if not prev_parent: raise AssertionError("Can't move a node with no parent") # remove from previous position self.tree.remove_edge(prev_parent.identifier, self.identifier) # add to new position old_prefix = self.identifier self.model.type_emblem = new_parent.next_emblem(self.node_type) new_prefix = ( new_parent.identifier + '__' + self.node_type + '_' + self.type_emblem ) self.tree.add_edge(new_parent.identifier, self.identifier, sort_order=new_parent.next_sort_order()) # relabel label_mapping = {} for node in self.walk(): old_label = node.identifier node.model.identifier = new_prefix + old_label[len(old_prefix):] label_mapping[old_label] = node.model.identifier relabel_nodes(self.tree, label_mapping, copy=False) return self.jump_to(label_mapping[self.identifier])
def remove_intra_cq_redundancy(nx_cq_graph): import networkx as nx while True: # must transform into UNDIRECTED graphs for computation of endomorphisms! core_endomorphism = compute_core_endomorphism( nx_cq_graph.to_undirected()) if core_endomorphism is None: return nx_cq_graph else: from networkx import relabel relabel.relabel_nodes(nx_cq_graph, core_endomorphism, copy=False)
def grid_graph(dim, periodic=False): """Returns the *n*-dimensional grid graph. The dimension *n* is the length of the list `dim` and the size in each dimension is the value of the corresponding list element. Parameters ---------- dim : list or tuple of numbers or iterables of nodes 'dim' is a tuple or list with, for each dimension, either a number that is the size of that dimension or an iterable of nodes for that dimension. The dimension of the grid_graph is the length of `dim`. periodic : bool or iterable If `periodic` is True, all dimensions are periodic. If False all dimensions are not periodic. If `periodic` is iterable, it should yield `dim` bool values each of which indicates whether the corresponding axis is periodic. Returns ------- NetworkX graph The (possibly periodic) grid graph of the specified dimensions. Examples -------- To produce a 2 by 3 by 4 grid graph, a graph on 24 nodes: >>> from networkx import grid_graph >>> G = grid_graph(dim=(2, 3, 4)) >>> len(G) 24 >>> G = grid_graph(dim=(range(7, 9), range(3, 6))) >>> len(G) 6 """ from networkx.algorithms.operators.product import cartesian_product if not dim: return empty_graph(0) if iterable(periodic): func = (cycle_graph if p else path_graph for p in periodic) else: func = repeat(cycle_graph if periodic else path_graph) G = next(func)(dim[0]) for current_dim in dim[1:]: Gnew = next(func)(current_dim) G = cartesian_product(Gnew, G) # graph G is done but has labels of the form (1, (2, (3, 1))) so relabel H = relabel_nodes(G, flatten) return H
def grid_graph(dim, periodic=False): """Returns the *n*-dimensional grid graph. The dimension *n* is the length of the list `dim` and the size in each dimension is the value of the corresponding list element. Parameters ---------- dim : list or tuple of numbers or iterables of nodes 'dim' is a tuple or list with, for each dimension, either a number that is the size of that dimension or an iterable of nodes for that dimension. The dimension of the grid_graph is the length of `dim`. periodic : bool If `periodic is True` the nodes on the grid boundaries are joined to the corresponding nodes on the opposite grid boundaries. Returns ------- NetworkX graph The (possibly periodic) grid graph of the specified dimensions. Examples -------- To produce a 2 by 3 by 4 grid graph, a graph on 24 nodes:: >>> G = grid_graph(dim=[2, 3, 4]) >>> len(G) 24 >>> G = grid_graph(dim=[range(7, 9), range(3, 6)]) >>> len(G) 6 """ dlabel = "%s" % dim if not dim: G = empty_graph(0) G.name = "grid_graph(%s)" % dlabel return G func = cycle_graph if periodic else path_graph G = func(dim[0]) for current_dim in dim[1:]: # order matters: copy before it is cleared during the creation of Gnew Gold = G.copy() Gnew = func(current_dim) # explicit: create_using = None # This is so that we get a new graph of Gnew's class. G = cartesian_product(Gnew, Gold) # graph G is done but has labels of the form (1, (2, (3, 1))) so relabel H = relabel_nodes(G, flatten) H.name = "grid_graph(%s)" % dlabel return H
def grid_graph(dim, periodic=False): """Returns the *n*-dimensional grid graph. The dimension *n* is the length of the list `dim` and the size in each dimension is the value of the corresponding list element. Parameters ---------- dim : list or tuple of numbers or iterables of nodes 'dim' is a tuple or list with, for each dimension, either a number that is the size of that dimension or an iterable of nodes for that dimension. The dimension of the grid_graph is the length of `dim`. periodic : bool If `periodic is True` the nodes on the grid boundaries are joined to the corresponding nodes on the opposite grid boundaries. Returns ------- NetworkX graph The (possibly periodic) grid graph of the specified dimensions. Examples -------- To produce a 2 by 3 by 4 grid graph, a graph on 24 nodes: >>> from networkx import grid_graph >>> G = grid_graph(dim=[2, 3, 4]) >>> len(G) 24 >>> G = grid_graph(dim=[range(7, 9), range(3, 6)]) >>> len(G) 6 """ dlabel = "%s" % dim if not dim: return empty_graph(0) func = cycle_graph if periodic else path_graph G = func(dim[0]) for current_dim in dim[1:]: Gnew = func(current_dim) G = cartesian_product(Gnew, G) # graph G is done but has labels of the form (1, (2, (3, 1))) so relabel H = relabel_nodes(G, flatten) return H
def get_json(self): from networkx.readwrite import json_graph from networkx.relabel import relabel_nodes import json mod_trees = [] for t in self.trees: mapping = dict() for n in t.node.keys(): if isinstance(n, Course): mapping[n] = n.__unicode__() mod_tree = relabel_nodes(t, mapping) mod_trees.append(mod_tree) n_depth = max([self.max_depth(t) for t in self.trees]) n_width = 0 for nbd in [self.nodes_by_depth(t) for t in self.trees]: nbd_max = max([len(d) for d in nbd]) n_width += nbd_max return json.dumps({'trees': [json.loads(json_graph.dumps(mt)) for mt in mod_trees], 'n_depth': n_depth, 'n_width': n_width})