Я работаю над той же проблемой подсчета количества треугольников на неориентированном графике, и решение Wisty работает очень хорошо в моем случае. Я немного его изменил, поэтому учитываются только неориентированные треугольники.
#### function for counting undirected cycles
def generate_triangles(nodes):
visited_ids = set() # mark visited node
for node_a_id in nodes:
temp_visited = set() # to get undirected triangles
for node_b_id in nodes[node_a_id]:
if node_b_id == node_a_id:
raise ValueError # to prevent self-loops, if your graph allows self-loops then you don't need this condition
if node_b_id in visited_ids:
continue
for node_c_id in nodes[node_b_id]:
if node_c_id in visited_ids:
continue
if node_c_id in temp_visited:
continue
if node_a_id in nodes[node_c_id]:
yield(node_a_id, node_b_id, node_c_id)
else:
continue
temp_visited.add(node_b_id)
visited_ids.add(node_a_id)
Конечно, вам нужно использовать словарь, например
#### Test cycles ####
nodes = {}
nodes[0] = [1, 2, 3]
nodes[1] = [0, 2]
nodes[2] = [0, 1, 3]
nodes[3] = [1]
cycles = list(generate_triangles(nodes))
print cycles
Используя код Wisty, найденные треугольники будут
[(0, 1, 2), (0, 2, 1), (0, 3, 1), (1, 2, 3)]
, который считал треугольник (0, 1, 2) и (0, 2, 1) как два разных треугольника. С измененным кодом они считаются только одним треугольником.
Я использовал это с относительно небольшим словарем из 100 ключей, и каждый ключ в среднем имеет 50 значений.