Простые запросы пути к большим графикам

У меня есть вопрос о больших графических данных. Предположим, что у нас есть большой граф с почти 100 миллионами ребер и около 5 миллионов узлов, в этом случае какая лучшая известная вам платформа анализа графов может дать все простые пути длин ‹ = k (для k = 3,4 ,5) между любыми двумя заданными узлами. Основная проблема заключается в скорости получения этих путей. Другое дело, что граф является направленным, но мы бы хотели, чтобы программа игнорировала направления при вычислении путей, но по-прежнему возвращала фактически направленные ребра, как только обнаружит эти пути.

Например:

a -> c ‹- d -> b является допустимым путем между узлами 'a' и 'b' длины 3.

Заранее спасибо.


person mgokhanbakal    schedule 30.01.2015    source источник
comment
Как вы думаете, смогу ли я справиться с этой операцией с сетевым пакетом NetworkX python, используя суперкомпьютер? Спасибо   -  person mgokhanbakal    schedule 30.01.2015
comment
А как насчет пакета graph-tool? У кого-нибудь есть знания об этом? Это лучший инструмент для того, что я упомянул выше? Спасибо.   -  person mgokhanbakal    schedule 05.02.2015


Ответы (2)


Так что это способ сделать это в networkx. Это примерно основано на решении, которое я дал здесь< /а>. Я предполагаю, что a->b и a<-b - это два разных пути, которые вам нужны. Я собираюсь вернуть это как список списков. Каждый подсписок представляет собой (упорядоченные) ребра пути.

import networkx as nx
import itertools

def getPaths(G,source,target, maxLength, excludeSet=None):
    #print source, target, maxLength, excludeSet
    if excludeSet== None:
        excludeSet = set([source])
    else:
        excludeSet.add(source)# won't allow a path starting at source to go through source again.
    if maxLength == 0:
        excludeSet.remove(source)
        return []
    else:
        if G.has_edge(source,target):
            paths=[[(source,target)]]
        else:
            paths = []
        if G.has_edge(target,source):
            paths.append([(target,source)])
        #neighbors_iter is a big iterator that will give (neighbor,edge) for each successor of source and then for each predecessor of source.

        neighbors_iter = itertools.chain(((neighbor,(source,neighbor)) for neighbor in G.successors_iter(source) if neighbor != target),((neighbor,(neighbor,source)) for neighbor in G.predecessors_iter(source) if neighbor != target))

        #note that if a neighbor is both a predecessor and a successor, it shows up twice in this iteration.  

        paths.extend( [[edge] + path for (neighbor,edge) in neighbors_iter if neighbor not in excludeSet for path in getPaths(G,neighbor,target,maxLength-1,excludeSet)] )

        excludeSet.remove(source) #when we move back up the recursion, don't want to exclude this source any more

        return paths

G=nx.DiGraph()
G.add_edges_from([(1,2),(2,3),(1,3),(1,4),(3,4),(4,3)])

print getPaths(G,1,3,2)

>[[(1, 3)], [(1, 2), (2, 3)], [(1, 4), (4, 3)], [(1, 4), (3, 4)]]

Я ожидаю, что, изменив алгоритм dijkstra в networkx, вы получите более эффективный алгоритм (обратите внимание, что алгоритм dijkstra имеет отсечку, но по умолчанию он будет возвращать только кратчайший путь и будет следовать направлению края) .

Вот альтернативная версия всего paths.extend: paths.extend( [[edge] + путь для (neighbor,edge) в Neighbor_iter, если сосед не в excludeSet для пути в getPaths(G,neighbor,target,maxLength-1, excludeSet), если len(path)>0 ] )

person Joel    schedule 31.01.2015
comment
Спасибо, это очень близко к тому, что я искал. - person mgokhanbakal; 04.02.2015
comment
Приведенный выше код также дает пути, которые не имеют ни исходного узла, ни целевого узла. Однако мне нужны пути, содержащие исходный узел и целевой узел. - person mgokhanbakal; 11.02.2015
comment
Я не уверен, что ты имеешь в виду. В примере, который я привел, запрашивались все пути от 1 до 3 длиной не более 2. Все пути, которые он возвращал, начинались с 1 и заканчивались на 3, игнорируя направление края. - person Joel; 12.02.2015
comment
Я попробовал это с немного большим графом, но некоторые из путей не имеют целевого узла, даже если они удовлетворяют заданной длине пути. - person mgokhanbakal; 13.02.2015
comment
Исправил. Баг был связан с тем, что в одном месте я возвращал [[]], а не []. Таким образом, он возвращал список, содержащий пустой путь, а затем с удовольствием добавлял ребра к пустому пути, думая, что это путь, ведущий к цели. - person Joel; 14.02.2015

Я бы рекомендовал использовать Gephi, простой в обращении и освоении.

Если вы его нашли, Neo4j выполнит ваше требование, немного написав код.

person user 12321    schedule 30.01.2015
comment
На самом деле я знаю Gephi, но я ищу что-то еще, например платформу (например, NetworkX, Jung, Pajek и т. д.), которую я могу использовать в качестве API-интерфейса интеллектуального анализа графов для настройки своих требований. - person mgokhanbakal; 30.01.2015