Python 查找排除特定边的最短路径?

Python 查找排除特定边的最短路径?,python,graph,neo4j,py2neo,Python,Graph,Neo4j,Py2neo,我使用的是Py2neo,但这可能并不重要,因为这很可能需要通过编写一个密码查询来完成 本质上,我想在一个子图中找到一条最短路径,其中子图是整个图的大部分,但删除的边很少(百万分之一或更少) 例如,假设我有节点A、B和C以及边(A->B)、(A->C)、(B->C)。当然,从A到C的最短路径是通过直接连接。但是,如果我想找到不使用该边的最短路径,它必须是一个B-C 此外,这也是用户可以在多用户(web)应用程序中指定的内容。因此,我无法真正改变数据库本身……如果这不是问题,我可能会在边缘上创建一个

我使用的是Py2neo,但这可能并不重要,因为这很可能需要通过编写一个密码查询来完成

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

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

此外,这也是用户可以在多用户(web)应用程序中指定的内容。因此,我无法真正改变数据库本身……如果这不是问题,我可能会在边缘上创建一个属性“allow:true/false”,并将其设置为false,但这会影响所有当前用户的应用程序行为

另一种变体是“不允许:sessionID1、sessionID230、sessionid010”,即在边缘本身中实际存储要排除该边缘的应用程序会话,但这似乎并不理想

当然,我实际上可以在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:示例控制台:

在任何两个人之间很容易找到最短的“友谊路径”,但如果我们想找到一条不涉及特定friendshi rel(或特定的一组friendshi rel)但不首先修改数据库的最短友谊路径,该怎么办?e、 例如,我们想找到从bob到joe的最短友谊路径,其中我们暂时假设bob和joe本身不是朋友,alice和janet也不是朋友。

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

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

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

事实上,所有路径的路径长度都可以由Cypher本身返回。
这已经被问过了,请参考。这个问题的公认答案就是我所说的。

你的问题有点宽泛,几乎可以肯定,形成查询并使用Neo4引擎执行计算比将数据从数据库中提取到图形结构并使用python@EdChum我想情况就是这样。因此,我的问题是,鉴于此,我如何使用Neo4j引擎实现我的目标?所有可能的路径选项是最好的,尽管在最短的100条或更多路径包含我想要拒绝的rel或节点的情况下,它似乎会对性能造成相当大的影响。如果有一种方法可以告诉neo4j在搜索过程中忽略特定的rel或节点,这似乎会更快,尽管这可能是不可能的。您是否可以填充一个快速的neo4j控制台并共享它?这将有助于我们实际运行一些查询,并查看什么是有效的..作为EDIT 2添加到原始帖子的底部。根据您在控制台上填充的数据,如果我们假设bob和joe不是朋友,则bob和joe之间没有连接路径。没有路,更不用说最短的路了。。。请你再核对一下数据好吗?或者我遗漏了什么?更像是这样:假设从珍妮特到迈尔斯的最短路径包括从鲍勃到乔的关系。现在假设bob和joe不是朋友…找到从Janet到Miles的最短路径,而bob和joe之间没有联系。。。。