Создание дерева данных с помощью networkx в python
Я пытаюсь создать дерево, которое имеет 1111 узлов и организовано так, что узел 1 имеет 10 детей (от 2 до 11), узел 2 имеет 10 детей (от 12 до 21) и так далее... таким образом, чтобы каждый узел имел 10 детей с 1 узлов на корневом уровне, имеющий 10 дочерних узлов, каждый дочерний узел имеет 10 детей, и каждый из этих 100 узлов 10 дочерних узлов каждого это 1000 конечных узлов. Общее количество узлов 1111.
import networkx as nx
G = nx.Graph()
L1 = [1]
L2 = [x for x in range(2,12)]
L3 = [x for x in range(12,112)]
L4 = [x for x in range(112,1112)]
G.add_node(1)
G.add_nodes_from(L1)
G.add_nodes_from(L2)
G.add_nodes_from(L3)
G.add_nodes_from(L4)
теперь я хочу добавить ребра, используя G.add_edges_from([(x,y) for x in L1 for y in L2])
что нормально для первый уровень, но как это сделать для других уровней?
3 ответов
вы можете достичь желаемого результата "из коробки" в одной строке:
import networkx as nx
G = nx.balanced_tree(10,10)
вы можете обобщить создание графика на произвольную глубину и произвольное количество детей для каждого внутреннего узла.
если вы начинаете нумерацию уровней от 0 -- то есть корневой узел представляет Уровень 0 -- то каждый уровень содержит nуровень узлы.
n-количество дочерних элементов на каждом внутреннем узле.
Например, в вашем случае с n = 10 последними узлами для уровней 0, 1, 2, 3 являются
100 = 1,
100 + 101 = 11,
100 + 101 + 102 = 111,
100 + 101 + 102 + 103 = 1111.
чтобы найти индексы дочерних элементов для данного узла, вы берете индекс последнего узла на этот уровень и добавить смещение.
Если данный узел является первым (самым левым) узлом на этом уровне, смещение равно 0.
Если его последний узел на этом уровне смещение (nуровень - 1) * n.
Тогда (nуровень - 1) - количество узлов-предшественников на этом уровне.
В общем случае смещение рассчитывается как [количество узлов-предшественников на этом уровне] * n.
это понятие охватывается кодом как offset = ulim + i * n + 1
.
Я добавил 1
чтобы иметь возможность цикл в следующем из 0 - (n-1)
вместо с 1 - n
.
import networkx as nx
n = 10 # the number of children for each node
depth = 3 # number of levels, starting from 0
G = nx.Graph()
G.add_node(1) # initialize root
ulim = 0
for level in range(depth): # loop over each level
nl = n**level # number of nodes on a given level
llim = ulim + 1 # index of first node on a given level
ulim = ulim + nl # index of last node on a given level
for i in range(nl): # loop over nodes (parents) on a given level
parent = llim + i
offset = ulim + i * n + 1 # index pointing to node just before first child
for j in range(n): # loop over children for a given node (parent)
child = offset + j
G.add_node(child)
G.add_edge(parent, child)
# show the results
print '{:d}-{:d}'.format(parent, child),
print ''
print '---------'
на depth = 3
и n = 3
это выход:
1-2 1-3 1-4
---------
2-5 2-6 2-7
3-8 3-9 3-10
4-11 4-12 4-13
---------
5-14 5-15 5-16
6-17 6-18 6-19
7-20 7-21 7-22
8-23 8-24 8-25
9-26 9-27 9-28
10-29 10-30 10-31
11-32 11-33 11-34
12-35 12-36 12-37
13-38 13-39 13-40
---------
понял ответ
import networkx as nx
G = nx.Graph()
L1 = [1]
L2 = [x for x in range(2,12)]
L3 = [x for x in range(12,112)]
L4 = [x for x in range(112,1112)]
G.add_node(1)
G.add_nodes_from(L1)
G.add_nodes_from(L2)
G.add_nodes_from(L3)
G.add_nodes_from(L4)
G.add_edges_from([(x,y) for x in L1 for y in L2])
temp2 = []
temp = []
temp2.extend(L4)
temp.extend(L3)
for i in range(1,11,1):
G.add_edges_from([x,temp.pop()] for x in L2)
G.add_edges_from([y,temp2.pop()] for y in L3)
print G.nodes()
print G.edges()
print G.number_of_nodes()
print G.number_of_edges()
print G.neighbors(1)
try:
diameter_of_myGraph =nx.shortest_path_length(G)
#print diameter_of_myGraph
except nx.NetworkXNoPath:
print 'No path'
try:
avg_distance_of_myGraph =nx.average_shortest_path_length(G)
print avg_distance_of_myGraph
except nx.NetworkXNoPath:
print 'No path'