我试图弄清楚是否有某种方法可以根据关系总和得到两个节点之间的最短距离,给出这个例子: neo4j image example
上面的图片代码:
CREATE (some_point_1:Point {title:'Some Point 1'})
CREATE (some_point_2:Point {title:'Some Point 2'})
CREATE (some_point_3:Point {title:'Some Point 3'})
CREATE (some_point_4:Point {title:'Some Point 4'})
CREATE (some_point_5:Point {title:'Some Point 5'})
CREATE (some_point_6:Point {title:'Some Point 6'})
CREATE (some_point_1)-[:distance {value:100}]->(some_point_2)
CREATE (some_point_2)-[:distance {value:150}]->(some_point_4)
CREATE (some_point_1)-[:distance {value:200}]->(some_point_3)
CREATE (some_point_3)-[:distance {value:300}]->(some_point_4)
CREATE (some_point_2)-[:distance {value:500}]->(some_point_5)
CREATE (some_point_4)-[:distance {value:300}]->(some_point_5)
CREATE (some_point_5)-[:distance {value:300}]->(some_point_6)
CREATE (some_point_6)-[:distance {value:300}]->(some_point_1)
在此示例中,最短路径应为: some_point_1> some_point_2> some_point_4> some_point_5(100 + 150 + 300 = 550)
Cypher可以这样吗?
答案 0 :(得分:7)
Cypher中的shortestPath
函数没有考虑关系属性的累积,因此:
MATCH (start:Point {title: 'Some Point 1'}), (end:Point {title: 'Some Point 5'})
MATCH p=shortestPath((start)-[:distance*]->(end))
RETURN p
会根据路径中的关系数找到从start
到end
的最短路径。
你可以减少距离的总和:
MATCH (start:Point {title: 'Some Point 1'}), (end:Point {title: 'Some Point 5'})
MATCH p=(start)-[:distance*]->(end)
WITH p,reduce(s = 0, r IN rels(p) | s + r.value) AS dist
RETURN p, dist ORDER BY dist DESC
但问题是您需要计算从start
到end
的所有路径的总距离。为了提高效率,您希望使用Dijkstra's algorithm或A *等图表搜索算法,这两种算法都在Neo4j's Java API中实现。
在Neo4j 3.0中,这些算法通过APOC procedure library在Cypher中公开。安装APOC后,您可以从Cypher调用该程序:
MATCH (start:Point {title: 'Some Point 1'}), (end:Point {title: 'Some Point 5'})
CALL apoc.algo.dijkstra(start, end, 'distance', 'value') YIELD path, weight
RETURN path, weight
答案 1 :(得分:1)
Cypher有一个shortestPath()函数,结合谓词和一些试错法可能会做你想要的。
但是为了节省时间,它更容易使用neo4j APOC Procedures,其中包括加权的dijkstra最短路径算法,该算法应该非常适合您想要的内容。
我尚未使用它,但我认为语法(在startNode和endNode上匹配后,使用您的关系名称和用于权重的属性)就像
CALL apoc.algo.dijkstra(startNode, endNode, 'distance', 'value')
YIELD path, weight
至于考虑方向,维基文档并没有完全说出来,但看起来像是<或者>我认为,它被添加到关系标签的适当末尾,因此'距离>'如果你想让它尊重方向,可能是更正确的参数。