【问题标题】:Simple path queries on large graphs大图上的简单路径查询
【发布时间】:2015-01-30 16:29:10
【问题描述】:

我有一个关于大型图形数据的问题。假设我们有一个包含近 1 亿条边和大约 500 万个节点的大型图,在这种情况下,您所知道的最好的图挖掘平台可以提供所有长度

例如:

a -> c b 是节点“a”和“b”之间长度为 3 的有效路径。

提前致谢。

【问题讨论】:

  • 你觉得我用NetworkX python网络包用超级电脑可以处理这个操作吗?谢谢
  • 图形工具包呢?有没有人有这方面的知识?它是我上面提到的最好的工具吗?谢谢。

标签: data-mining networkx jung spark-graphx large-data


【解决方案1】:

所以这是在networkx中实现的一种方式。它大致基于我给here的解决方案。我假设a->ba<-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)]]

我希望通过修改 networkx 中的 dijkstra 算法,您会得到一个更高效的算法(请注意,dijkstra 算法有一个截止点,但默认情况下它只会返回最短路径,并且会遵循边缘方向)。

这是整个 paths.extend 的替代版本: 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) if len(path)>0 ] )

【讨论】:

  • 谢谢,这与我想要的非常接近。
  • 上面的代码还给出了既没有源节点也没有目标节点的路径。但是,我需要包含源节点和目标节点的路径。
  • 我不确定你的意思。我给出的示例要求从 1 到 3 的所有路径,长度最多为 2。它返回的所有路径都从 1 开始,到 3 结束,忽略边缘方向。
  • 我尝试了一个更大的图,但有些路径没有目标节点,即使它们满足给定的路径长度。
  • 已更正。错误与我在一个地方返回[[]] 而不是[] 的事实有关。所以它返回一个包含空路径的列表,然后很高兴地向空路径添加边,认为它是到达目标的路径。
【解决方案2】:

我建议使用易于处理和学习的Gephi

如果你找到了它,Neo4j 将通过一点编码来满足你的要求。

【讨论】:

  • 其实我知道 Gephi,但我正在寻找其他类似平台(例如 NetworkX、Jung、Pajek 等)的东西,我可以将其用作图形挖掘 API 来定制我的需求。跨度>
猜你喜欢
  • 1970-01-01
  • 2021-09-20
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
  • 2022-08-08
  • 2022-01-14
  • 1970-01-01
  • 2014-06-14
相关资源
最近更新 更多