How can I get all the tree graphs given a certain numbers of nodes? Networkx

夙愿已清 提交于 2021-01-29 12:34:41

问题


I was wondering is there a way to obtain all the different trees using Networkx? It's a known fact that the number of trees with n nodes is n^(n-2) (using Cayley's Formula) so if there is 3 nodes, then it has 3 tree graphs, if it has 4 nodes then it has 16 trees and so on. What I want is to code all the trees using the prufer sequence, I know that Networkx has a function to create random trees, but there is a chance I can get duplicates, all I can think of is use Numpy so I can find all the unique elements in a list, here is my code:

import numpy as np
import networkx as nx

n = 3  #Number of nodes
aux = []
prufer = []

for i in range(10):
    aux.append(nx.random_tree(n))    

for j in aux:
    prufer.append(nx.to_prufer_sequence(j))

arr = np.array(prufer)
newarr = np.unique(arr, axis = 0)

The problem here it's that I generated 10 random trees, but in the end I only want 3 but when I want to find all the trees using 4 nodes I don't want to generate 50 if I'm only going to use 16. Is there a way I can do this more efficiently? Thank you!


回答1:


This might be a bit bruteforcy, and there might be built-in functionality or a more elegant approach that I am missing, but it certainly is better than randomly generating the trees: You can use itertools to generate pairwise combinations and filter out duplicates and self-pointing loops:

import itertools

def make_all_trees(nodes):
    # generate all pairwise combinations of nodes
    edges =  [a for a in itertools.product(range(nodes), range(nodes))]

    # use sets to lose..
    # ..symmetric edges: (0,1), (1,0) => keep only (0,1) 
    edges = list(set([tuple(set(e)) for e in edges]))
    # ..and self-loops: (0,0)
    edges = [e for e in edges if len(e)>1]

    trees = []
    # generate all graphs that have nodes-1 edges
    for o in itertools.combinations(edges, nodes-1):
        #make sure that all nodes are in the edgelist:
        flattened = [item for sublist in o for item in sublist]

        if len(set(flattened)) == nodes:
            G = nx.Graph()
            G.add_edges_from(o)
            # make sure all nodes are connected
            if len(list(nx.connected_components(G)))==1:
                trees.append(G)

    return trees

testcases:

 len(make_all_trees(3)): 3
 len(make_all_trees(4)): 16
 len(make_all_trees(5)): 125

all 4 node trees:

trees = make_all_trees(4)

for p, tree in enumerate(trees):
    plt.subplot(4,4,p+1)
    nx.draw_networkx(tree)
plt.show()



来源:https://stackoverflow.com/questions/62116491/how-can-i-get-all-the-tree-graphs-given-a-certain-numbers-of-nodes-networkx

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!