【问题标题】:finding shortest path that excludes particular edges?找到排除特定边缘的最短路径?
【发布时间】:2014-04-23 08:45:19
【问题描述】:

我正在使用 Py2neo,但这可能并不重要,因为这很可能需要通过编写 Cypher 查询来完成。

本质上,我想在 子图 中找到一条最短路径,其中子图占整个图的大部分,但删除了很小一部分(百万分之一或更少)的边。

例如,假设我有节点 A、B 和 C,以及边 (A->B)、(A->C)、(B->C)。当然,从 A 到 C 的最短路径是直接连接。但是,如果我想找到 使用该边的最短路径,它必须是 A B C。

此外,这将是用户可以在多用户 (Web) 应用程序中指定的内容。所以我不能真正改变数据库本身......如果这不是问题,我可以在边缘“允许:真/假”上创建一个属性并将其设置为假,但这会扰乱应用程序的行为所有当前用户。

对此的一种变体是使用“disallow: sessionID1, s​​essionID230, sessionID1010”,即实际存储哪些应用程序会话想要在边缘本身中排除该边缘,但这似乎也不理想。

当然,我实际上可以在 python 中实现 BFS,方法是根据需要从 neo4j 获取节点并将它们保留在队列中,而不是让 neo4j 进行搜索,但这肯定会慢得多,对吧?

有什么想法吗?谢谢

编辑:请求查看代码。

下面是我目前如何获得我首先在索引中查找的两个节点之间的最短路径。现在图像还有一个边缘列表(即唯一关系),在最短路径搜索中必须忽略。

from py2neo import neo4j

g = neo4j.GraphDatabaseService()

def shortest_path(a, b):
    a = g.get_indexed_node("worddex", "word", a)
    b = g.get_indexed_node("worddex", "word", b)
    if not a and b: return None
    query_string = "START beginning=node(%d), end=node(%d) MATCH p = shortestPath(beginning-[*..100]-end) RETURN p" % (a._id, b._id)
    result = neo4j.CypherQuery(g, query_string).execute()
    if not len(result): return None
    p = result[0].p
    ret = []
    for node in p.nodes:
        ret.append(node["word"])
    return ret

编辑 2:示例控制台:http://console.neo4j.org/r/3c1rgn

很容易找到任意两个人之间的最短“友谊路径”,但是如果我们想找到一条涉及特定友谊关系(或特定集合)的最短友谊路径怎么办?友谊rels),但没有先修改数据库?例如,我们想找到从 bob 到 joe 的最短友谊路径,其中我们暂时假设 bob 和 joe 自己不是朋友,alice 和 janet 也不是。

【问题讨论】:

  • 你的问题有点宽泛,形成查询并使用Neo4引擎执行计算几乎肯定比将数据从数据库中提取到图形结构中并使用python分析更好
  • @EdChum 我想会是这样。所以我的问题是,鉴于此,我怎样才能使用 Neo4j 引擎实现我的目标?

标签: python graph neo4j py2neo


【解决方案1】:

您不能在 cypher 中使用“allShortestPaths”选项并使用它来拒绝包含某些特定 rel 类型或使用 python 的节点类型的路径吗?我想这将取决于您想要限制结果的方式和参数,以及是否可以仅使用 cypher 以路径形式返回给 python 的内容来检测它们。

另一种方法是指示 Cypher 将所有可能的路径从一个节点返回到另一个节点(可以在此处的查询本身中应用一些智能限制)。

然后根据 Cypher 返回的路径集合,您可以运行一些 Python 代码来拒绝包含特定 rel 类型或您不感兴趣的节点类型的路径。然后您将得到一个集合符合您的验收标准的可能路径(最短条件除外)。然后,您可以简单地使用 python 计算路径的长度并使用最小的。

实际上,Cypher 自己可以为所有路径返回路径的长度。 之前已经问过这个问题,所以here is the question供您参考。这个问题的公认答案就是我所说的。

【讨论】:

  • ALL POSSIBLE PATHS 选项是迄今为止最好的选项,尽管在最短的 100 条或更多路径包含我想要拒绝的 rel 或节点的情况下,它似乎可能会严重损害性能。如果有办法告诉 neo4j 在搜索过程中忽略特定的 rel 或节点,看起来会更快,尽管这可能是不可能的。
  • 您能否填充一个快速的 neo4j 控制台并分享它?这将帮助我们实际运行一些查询,看看什么有效..
  • 添加为 EDIT 2 到原始帖子的底部。
  • 根据您在控制台上填写的数据,如果我们假设 bob 和 joe 不是朋友,那么就没有连接 bob 和 joe 的路径。没有路径,更不用说最短路径了...请您仔细检查数据吗?还是我错过了什么?
  • 更像是这样:假设从 Janet 到 Miles 的最短路径涉及从 bob 到 joe 的 rel。现在假设 bob 和 joe 不是朋友......找到从 Janet 到 Miles 的最短路径,并且没有 bob 和 joe 之间的链接......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多