In the answer to this question there is code that creates all trees with a certain number of nodes.
The problem is that I tried to create the corresponding adjacency matrix using a built-in function in networkx nx.to_numpy_array
but for some reason it's not working, the code is next:
#Function created by warped
import itertools
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
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
#This is what I added it to create the corresponding adjacency matrix
trees = make_all_trees(3) #This create all the graph trees with 3 nodes, so it creates 3 trees
adjaux = []
for i in trees:
adjaux.append(nx.to_numpy_array(i))
print(np.array(adjaux))
#Draws the graph
for p, tree in enumerate(trees):
plt.subplot(4,4, p+1)
nx.draw_networkx(tree)
plt.show()
The output is the following
#Adjacency matrix created
adjaux = [[[0. 1. 0.] [[0. 1. 1.] [[0. 1. 0.]
[1. 0. 1.] [1. 0. 0.] [1. 0. 1.]
[0. 1. 0.]] [1. 0. 0.]] [0. 1. 0.]]]
As you can see, although all the trees graph are correct and the first two adjacency matrix are correct, the last one is incorrect, the output should be:
adjaux = [[[0. 1. 0.] [[0. 1. 1.] [[0. 0. 1.]
[1. 0. 1.] [1. 0. 0.] [0. 0. 1.]
[0. 1. 0.]] [1. 0. 0.]] [1. 1. 0.]]]
I tried re-creating the code step by step, but I can't see what and why it's not working, all seems to be fine, so any help will be appreciated, thank you!
documentation of nx.to_numpy_array:
[...] nodelist (list, optional) – The rows and columns are ordered according to the nodes in nodelist. If nodelist is None, then the ordering is produced by G.nodes(). [...]
Checking the order for your graphs:
trees = make_all_trees(3)
for tree in trees:
print(tree.nodes())
#output:
[0, 1, 2] # first tree
[0, 1, 2] # second tree
[1, 2, 0] # third tree, node order is changed
So, the adjacency matrix is correct in all cases (the graphs are displayed correctly, so edges must be recorded correctly), but the order is messed up. You need to explicitly specify the order of nodes in the nodelist argument:
adjaux=[]
for tree in trees:
adjaux.append(nx.to_numpy_array(tree, nodelist=sorted(tree.nodes())))
for a in adjaux:
print('-'*10)
print(a)
----------
[[0. 1. 0.]
[1. 0. 1.]
[0. 1. 0.]]
----------
[[0. 1. 1.]
[1. 0. 0.]
[1. 0. 0.]]
----------
[[0. 0. 1.]
[0. 0. 1.]
[1. 1. 0.]]