如何在Neo4j中找到跳数最少的最短路径?

时间:2016-04-12 20:59:46

标签: graph neo4j cypher

我建模图形,其中节点是位置,边缘表示您可以从一个地方到另一个地方。

这是为了让你可以从一个地方到另一个地方的所有路线, 并且你可以通过不同的路线从一个地方到另一个地方,所以我想要一个查询,它返回最短的路径和最小的路线变化。

例如,我想从A到D,我有两条可能的路径:

(place {name: "A"})-[:FOLLOWS{route:""R1}]->(place{name: "B" })-[:FOLLOWS{route:""R4}]->(place{name:"C"})-[:FOLLOWS{route:""R2}]->(place{name:"D"})

(place {name: "A"})-[:FOLLOWS{route:""R1}]->(place{name: "B" })-[:FOLLOWS{route:""R1}]->(place{name:"F"})-[:FOLLOWS{route:""R2}]->(place{name:"D"})

在前两条路径中,两者的大小相同,但我希望得到第二条路径,即路径变化最小的路径。

谢谢。

5 个答案:

答案 0 :(得分:4)

@DevBennett的答案获得最短路径,其中路由更改次数最少

要获得最小路径不同路径,这就是字面上要求的问题(但可能不是提问者实际想要的那样),您可以使用此查询:

MATCH p=ALLSHORTESTPATHS((a:Place {name: "A"})-[:FOLLOWS*]->(d:Place{name:"D"}))
UNWIND RELATIONSHIPS(p) AS rel 
WITH p, COUNT(DISTINCT rel.route) AS nRoutes 
RETURN p, nRoutes 
ORDER BY nRoutes 
LIMIT 1;

答案 1 :(得分:4)

这样的事情:

MATCH 
    (a:place {name: "A"}) WITH a
MATCH
    (d:place {name: "D"}) WITH a,d 
MATCH
    p = allShortestPaths  ( (a)-[:FOLLOWS*..100]->(d) )
WITH 
    nodes(p) as places, relationships(p) as paths
UNWIND
    paths as path
WITH
    places, paths, collect(distinct path.route) as segments
RETURN
    places, paths, segments, size(segments) as cost
ORDER BY
    cost ASC
LIMIT 1

答案 2 :(得分:4)

来吧,你只能对3个答案感到满意:)

MATCH (a:Place {name:"A"}), (d:Place {name:"D"})
MATCH p=allShortestPaths((a)-[*]->(d))
RETURN p, 
size(filter(x in range(0, size(rels(p))) 
       WHERE (rels(p)[x]).route <> (rels(p)[x-1]).route)) + length(p) as score
ORDER BY score ASC

答案 3 :(得分:2)

我认为这将满足您的需求。它找到了所有最短的路径。然后它处理每一个以计算路线变化的数量。然后,它按最少的路径更改对结果集进行排序,并将结果集限制为第一次出现。

// find all of the shortest paths that match the beginning and ending nodes
match p=allShortestPaths((a:Place {name: 'A'})-[:FOLLOWS*]->(d:Place {name: 'D'}))

// carry forward the path, the relationships in the path and a range that represents the second to last relationships in the path 
with p,relationships(p) as rel, range(1,length(p)-1) as index

// use reduce to process the route attribute on the relationship to accumulate the changes
with p, rel, index, reduce (num_chg = 0, i in index | num_chg + 
    case when (rel[i]).route = (rel[i-1]).route then 0 else 1 end ) as changes

// return the path and the number of route changes
return p, changes

// only return the path with the fewest route change
order by changes
limit 1

答案 4 :(得分:0)

答案使用&#34; AllShortestPaths&#34;错了。

如果图表如下图所示怎么办?

Example of Graph 那么,使用AllShortestPaths函数的查询结果将是&#34; A-E-D&#34;而不是&#34; A-B-C-D&#34; ...