def test_inverse(self): """Tests that the encoding and decoding functions are inverses.""" for T in nx.nonisomorphic_trees(4): T2 = nx.from_prufer_sequence(nx.to_prufer_sequence(T)) assert_nodes_equal(list(T), list(T2)) assert_edges_equal(list(T.edges()), list(T2.edges())) for seq in product(range(4), repeat=2): seq2 = nx.to_prufer_sequence(nx.from_prufer_sequence(seq)) assert list(seq) == seq2
def test_inverse(self): """Tests that the encoding and decoding functions are inverses. """ for T in nx.nonisomorphic_trees(4): T2 = nx.from_prufer_sequence(nx.to_prufer_sequence(T)) assert_equal(list(T), list(T2)) assert_equal(list(T.edges()), list(T2.edges())) for seq in product(range(4), repeat=2): seq2 = nx.to_prufer_sequence(nx.from_prufer_sequence(seq)) assert_equal(list(seq), seq2)
def test_decoding2(self): # Example from "An Optimal Algorithm for Prufer Codes". sequence = [2, 4, 0, 1, 3, 3] tree = nx.from_prufer_sequence(sequence) assert_nodes_equal(list(tree), list(range(8))) edges = [(0, 1), (0, 4), (1, 3), (2, 4), (2, 5), (3, 6), (3, 7)] assert_edges_equal(list(tree.edges()), edges)
def test_decoding2(self): # Example from "An Optimal Algorithm for Prufer Codes". sequence = [2, 4, 0, 1, 3, 3] tree = nx.from_prufer_sequence(sequence) assert_equal(list(tree), list(range(8))) edges = [(0, 1), (0, 4), (1, 3), (2, 4), (2, 5), (3, 6), (3, 7)] assert_equal(list(tree.edges()), edges)
def test_decoding(self): """Tests for decoding a tree from a Prüfer sequence.""" # Example from Wikipedia. sequence = [3, 3, 3, 4] tree = nx.from_prufer_sequence(sequence) assert_nodes_equal(list(tree), list(range(6))) edges = [(0, 3), (1, 3), (2, 3), (3, 4), (4, 5)] assert_edges_equal(list(tree.edges()), edges)
def test_decoding(self): """Tests for decoding a tree from a Prüfer sequence.""" # Example from Wikipedia. sequence = [3, 3, 3, 4] tree = nx.from_prufer_sequence(sequence) assert_equal(list(tree), list(range(6))) edges = [(0, 3), (1, 3), (2, 3), (3, 4), (4, 5)] assert_equal(list(tree.edges()), edges)
def test_creation_from_prufer(): sequence = [3, 3, 3, 4] t1 = Tree(sequence) t2 = nx.from_prufer_sequence(sequence) d = dict(enumerate(string.ascii_lowercase, 0)) t2 = nx.relabel_nodes(t2, d) assert set(t1.tree.nodes) == set(t2.nodes) assert set(t1.tree.edges) == set(t2.edges)
def gen_tree_index(node_num, device=None): device = device or getDevice() graph = nx.from_prufer_sequence( np.random.randint(low=0, high=node_num, size=[node_num - 2])) edge_index = torch.tensor(list(zip(*(graph.edges))), dtype=torch.long, device=device) edge_index = torch.cat([edge_index, edge_index[:, [1, 0]]], dim=-1) # edge_index, _ = coalesce(edge_index, None, node_num, node_num ) edge_index, _ = coalesce(edge_index, torch.zeros_like(edge_index)[0], node_num, node_num) return edge_index, node_num
def _generate_graph(self, n): sequence = [] for _ in range(n - 2): sequence.append(randint(0, n - 2)) G = from_prufer_sequence(sequence) del sequence m = self._edge_count_from_avg_degree(n, self._params['d']) max_num_edges = n * (n - 1) * 0.5 probability = (m - G.size()) / (max_num_edges - G.size()) for i in range(n): for j in range(i + 1, n): if (not G.has_edge(i, j) and uniform(0.0, 1.0) <= probability): G.add_edge(i, j) return G
def decode_tree(self, seq): tree = nx.Graph() start = 0 vl = [] for x in range(len(seq) - 2): if len(self.cluster[x]) == 2: tree.add_edge(self.cluster[x][0], self.cluster[x][1]) continue if len(self.cluster[x]) == 1: continue t_t = nx.from_prufer_sequence(seq[x]) for e in list(t_t.edges): tree.add_edge(self.cluster[x][e[0]], self.cluster[x][e[1]]) # print(self.cluster[x][e[0]],self.cluster[x][e[1]]) # vl.append(self.cluster[x][seq[-c_n+x]]) t_t = nx.from_prufer_sequence(seq[-2]) mseq = seq[-1] for e in list(t_t.edges): tree.add_edge(self.cluster[e[0]][mseq[e[0]]], self.cluster[e[1]][mseq[e[1]]]) # print(tree.edges) # print([self.distance[a,b] for a,b in tree.edges]) return tree
def __init__(self, my_input): if isinstance(my_input, list): prufer_sequence = my_input self.n = len(prufer_sequence) + 2 elif isinstance(my_input, int): self.n = my_input prufer_sequence = [ random.randint(0, self.n - 1) for i in range(self.n - 2) ] else: sys.exit("Incorrect input in the creation of a Tree.") T = nx.from_prufer_sequence(prufer_sequence) d = dict(enumerate(string.ascii_lowercase, 0)) self.prufer_sequence = prufer_sequence self.tree = nx.relabel_nodes(T, d) self.diameter = nx.diameter( self.tree) + 1 # = number of vertices in the diameter
def random_tree(n, seed=None): """Returns a uniformly random tree on `n` nodes. Parameters ---------- n : int A positive integer representing the number of nodes in the tree. seed : int A seed for the random number generator. Returns ------- NetworkX graph A tree, given as an undirected graph, whose nodes are numbers in the set {0, …, *n* - 1}. Raises ------ NetworkXPointlessConcept If `n` is zero (because the null graph is not a tree). Notes ----- The current implementation of this function generates a uniformly random Prüfer sequence then converts that to a tree via the :func:`~networkx.from_prufer_sequence` function. Since there is a bijection between Prüfer sequences of length *n* - 2 and trees on *n* nodes, the tree is chosen uniformly at random from the set of all trees on *n* nodes. """ if n == 0: raise nx.NetworkXPointlessConcept('the null graph is not a tree') # Cannot create a Prüfer sequence unless `n` is at least two. if n == 1: return nx.empty_graph(1) random.seed(seed) sequence = [random.choice(range(n)) for i in range(n - 2)] return nx.from_prufer_sequence(sequence)
def random_tree(n, seed=None, create_using=None): """Returns a uniformly random tree on `n` nodes. Parameters ---------- n : int A positive integer representing the number of nodes in the tree. seed : integer, random_state, or None (default) Indicator of random number generation state. See :ref:`Randomness<randomness>`. Returns ------- NetworkX graph A tree, given as an undirected graph, whose nodes are numbers in the set {0, …, *n* - 1}. Raises ------ NetworkXPointlessConcept If `n` is zero (because the null graph is not a tree). Notes ----- The current implementation of this function generates a uniformly random Prüfer sequence then converts that to a tree via the :func:`~networkx.from_prufer_sequence` function. Since there is a bijection between Prüfer sequences of length *n* - 2 and trees on *n* nodes, the tree is chosen uniformly at random from the set of all trees on *n* nodes. Example ------- >>> import networkx as nx >>> tree = random_tree(n=10, seed=0) >>> print(forest_str(tree, sources=[0])) ╙── 0 ├── 3 └── 4 ├── 6 │ ├── 1 │ ├── 2 │ └── 7 │ └── 8 │ └── 5 └── 9 >>> import networkx as nx >>> tree = random_tree(n=10, seed=0, create_using=nx.OrderedDiGraph) >>> print(forest_str(tree)) ╙── 0 ├─╼ 3 └─╼ 4 ├─╼ 6 │ ├─╼ 1 │ ├─╼ 2 │ └─╼ 7 │ └─╼ 8 │ └─╼ 5 └─╼ 9 """ if n == 0: raise nx.NetworkXPointlessConcept("the null graph is not a tree") # Cannot create a Prüfer sequence unless `n` is at least two. if n == 1: utree = nx.empty_graph(1) else: sequence = [seed.choice(range(n)) for i in range(n - 2)] utree = nx.from_prufer_sequence(sequence) if create_using is None: tree = utree else: # TODO: maybe a tree classmethod like # Graph.new, Graph.fresh, or something like that def new(cls_or_self): if hasattr(cls_or_self, "_adj"): # create_using is a NetworkX style Graph cls_or_self.clear() self = cls_or_self else: # try create_using as constructor self = cls_or_self() return self tree = new(create_using) if tree.is_directed(): # Use a arbitrary root node and dfs to define edge directions edges = nx.dfs_edges(utree, source=0) else: edges = utree.edges # Populate the specified graph type tree.add_nodes_from(utree.nodes) tree.add_edges_from(edges) return tree