我正在使用 Py2neo,但这可能并不重要,因为这很可能需要通过编写 Cypher 查询来完成。
本质上,我想在subgraph中找到一条最短路径,其中子图是整个图的大部分,但只有一小部分(百万分之一或更少)的边被移除。
例如,假设我有节点 A、B 和 C,以及边 (A->B)、(A->C)、(B->C)。当然,从 A 到 C 的最短路径是直接连接。但是,如果我想找到不使用该边的最短路径,则必须是 AB C。
此外,这将是用户可以在多用户 (Web) 应用程序中指定的内容。所以我不能真正改变数据库本身......如果这不是问题,我可能会在边缘“允许:真/假”上创建一个属性并将其设置为假,但这会扰乱应用程序的行为所有当前用户。
对此的一种变体是具有“不允许:sessionID1、sessionID230、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
很容易找到任意两个人之间的最短“友谊路径”,但是如果我们想找到不涉及特定友谊 rel(或特定友谊 rel 集)但不先修改数据库的最短友谊路径怎么办? 例如,我们想找到从 bob 到 joe 的最短友谊路径,其中我们暂时假设 bob 和 joe 自己不是朋友,alice 和 janet 也不是。