我正在使用Py2neo,但这可能并不重要,因为这很可能需要通过编写Cypher查询来完成。
基本上,我想在子图中找到一条最短路径,其中子图是整个图的大部分,但是去掉了边的一小部分(百万分之一或更少)。 / p>
例如,假设我有节点A,B和C,以及边缘(A-> B),(A-> C),(B-> C)。当然,从A到C的最短路径是通过直接连接。但是,如果我想找到没有使用该边缘的最短路径,那么它必须是A B C.
此外,这将是用户可以在多用户(Web)应用程序中指定的内容。所以我无法真正改变数据库本身...如果这不是一个问题,我可以在边缘创建一个属性"允许:true / false"并将其设置为false,但这会使所有当前用户的应用程序行为混乱。
对此的一种变化是禁止使用: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
很容易找到最短的友谊路径"在任何两个人之间,但如果我们想要找到不会涉及特定的friendshi rel(或特定的友谊rels)的最短友谊路径,但是不首先修改数据库呢?例如,我们希望找到从鲍勃到乔的最短友谊路径,其中我们暂时认为鲍勃和乔不是朋友本人,也不是爱丽丝和珍妮特。
答案 0 :(得分:2)
你不能使用' allShortestPaths' cypher中的选项并使用它来使用python拒绝包含某些特定rel类型或节点类型的路径?我想这将取决于你想要限制结果的方式和参数,以及是否只能使用cypher以路径的形式返回python来检测它们。
另一种方法是指示Cypher将所有可能的路径从一个节点返回到另一个节点(这里可以在查询中应用一些智能限制)。
然后根据Cypher返回的路径集合,您可以运行一些Python代码来拒绝包含您不感兴趣的特定rel类型或节点类型的路径。然后您将留下一个集合适合您的验收标准的可能路径(最短的条件除外)。然后,您可以使用python简单地计算路径的长度,并使用最小的。
实际上,Cypher本身可以为所有路径返回路径的长度。 之前已经提到过,here is the question供您参考。这个问题的公认答案就是我所说的。