Для подсчета треугольников
- диктовочный доступ
G[u][v]
работает с данными ребра в графе G
, поэтому ключи в dict G[u]
не являются (в общем)все остальные узлы на графе;хотя ключи в dict G
включают в себя все узлы графа. Если вы хотите использовать эту форму индексации, вам, вероятно, будет лучше сгенерировать матрицу смежности, которая имеет nxnэлементы для n-узлового графа.Тогда все запросы A[i][j]
для i в диапазоне [0, n] будут действительными;и возвращаемое значение будет 0, если нет ребра.
также посмотрите на itertools, которые сделают ваш код чище ..
for i,j,k in itertools.combinations(xrange(n), 3):
# a generator of all unique combinations of [0,1,2,3,4]
# this already excludes the cases where i==j, i==k j==k
print(i,j,k)
хотя будьте осторожны, потому что в этом пакете есть различные функции, которые очень похожи.
Вот некоторый код, который подсчитывает количество треугольников здесь
import networkx as nx
import matplotlib.pyplot as plt
import itertools
T1 = []
T2 = []
n = 7
p = 0.2
reps = 1000
for r in xrange(reps):
G = nx.gnp_random_graph(n, p)
A = nx.adj_matrix(G);
t = 0;
for (i,j,k) in itertools.combinations(xrange(n), 3):
# a generator of all unique 3-combinations of [0,1,2,...,n]
if i==k or i==j or j==k:
print ("Found a duplicate node!", i,j,k)
continue # just skip it -- shouldn't happen
if A[i,j] and A[j,k] and A[i,k]:
t += 1
T1.append(t);
# let's check we agree with networkx built-in
tr = nx.triangles(G)
T2.append(sum(tr.values()))
T2 = [t /3.0 for t in T2]; # divide all through by 3, since this is a count of the nodes of each triangle and not the number of triangles.
plt.figure(1); plt.clf()
plt.hist([T1, T2], 20)
Здесь вы видите, чтоколичество треугольников одинаково (я поместил логарифмическую шкалу на ось y, поскольку частоты более высоких значений треугольника довольно низкие).
Для подсчета степеней
Похоже, вам нужна более четкая картина того, какую степень вы хотите вычислить: - Этонеориентированный граф, что означает, что если между u и v есть ребро, то оба эти узла должны быть по крайней мере в степени-1.Ваше вычисление учитывает ребра только один раз.
Во-вторых, графики, которые вы создаете, не имеют много ребер, особенно для меньших.При p = 0,2 доля 3-узловых графов без каких-либо ребер составляет 51%, и даже 5-узловые графы не будут иметь ребер 11% времени.Таким образом, пустой список не свидетельствует о сбое.
Средний уровень очень легко проверить, используя атрибуты графика:
2*G.number_of_edges() / float(G.number_of_nodes())
или встроенную степень для узла-калькулятор.
sum([d for (n, d) in nx.degree(G)]) / float(G.number_of_nodes())