【问题标题】:Efficient query in Cypher (as in Neo4J) to find union of shortest pathsCypher 中的有效查询(如在 Neo4J 中)以查找最短路径的联合
【发布时间】:2020-01-05 10:01:38
【问题描述】:

我正在寻找一个高效的 Cypher 查询来查找在图中的节点子集上定义的子图,定义为该子集中节点之间最短路径的并集。

目前,我拥有的是:

from neo4j import GraphDatabase
gdb = GraphDatabase.driver(address)
with gdb.session() as session:


    query = "MATCH path=shortestPath((n1)-[*1..{0}]->(n2)) ".format(max_path_length)
    query += "where n1.Name in {0} and c2.Name in {0} and n1.Name<>n2.Name ".format(list(nodes))
    query += "return rels(path)"

    paths = list(session.run(query).data())

edges = set().union(*(set(path['rels(path)']) for path in paths))
graph = nx.Graph(list(edges))

现在,此代码可以工作 - 但效率低下,它分别计算任意两个节点之间的最短路径,而许多路径相交(正如人们在“子图”的实际用例中所期望的那样)。

我不知道计算这个的有效算法;是否有一个 - 在 Cypher 中实现?

相关问题:
Extract subgraph from Neo4j graph with Cypher 展示了如何通过使用“WITH”语句定义节点列表来节省一点语法,但它并没有说可以提高性能(也许不可能)。Extract subgraph in neo4j 处理围绕单个来源的子图 - 如果它适用于我的案例,我不太明白如何(将接受一个解释该答案如何帮助我的案例的答案)

已编辑:我也接受返回包含给定节点的(或)最小子图的解决方案;我没有问它,因为它看起来像一个更难的问题,而且我没有代码示例。如果我错了,而且实际上更容易,我会接受。

【问题讨论】:

  • 不是任何边缘都在某个“最短路径”上吗?也就是说,每条边都是其相邻节点之间的最短路径。所以你的图只是给定节点列表的诱导子图。我错过了什么吗?
  • 我正在寻找给定子集中节点之间最短路径的边
  • 你能解释一下为什么要找到每对节点之间的最短路径吗?我觉得你必须以不同的方式处理这个问题。最小权重生成树之类的解决方案,甚至不同的遍历算法可能会更有帮助。
  • @NonameCurious 在 Neo4j/Cypher 中找到最小权重生成树是否更短/更容易?

标签: python neo4j cypher networkx


【解决方案1】:

您是否查看过 Neo4j 图算法库中的 all pairs shortest pathminimum weight spanning tree 算法?所有对最短路径返回每对节点的距离,而不是路径,因此它可能无法满足您的需要。

【讨论】:

  • 如果前者返回距离,而不是图形结构,那确实不是我要找的。至于后者,如果我理解正确,它将单个节点作为源并找到所有可到达的节点,这也不是我想要的。
  • 你在这两个方面都是正确的,所以我们必须继续思考。在您的编辑中,您说您将接受一个包含所选 noes 的最小子图。该子图是否需要是单个连接组件?
  • 如果可能的话,是的。如果不是,则不相交的节点集是一个(微不足道的)解决方案。但我认识到,如果原始图未连接,则解决方案可能不是单个连接组件。
  • 假设如果原始图是连通的,我希望解决方案也是。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
相关资源
最近更新 更多