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

Graph 如何在Neo4j中找到跳数最少的最短路径?,graph,neo4j,cypher,Graph,Neo4j,Cypher,Im建模一个图,其中节点是位置,边表示可以从一个位置移动到另一个位置 这就是你可以从一个地方到另一个地方的所有路线, 你可以通过不同的路线从一个地方到另一个地方,所以我需要一个查询,它能返回最短的路径,路线变化最小 例如,我想从A到D,我有两条可能的路径: (place {name: "A"})-[:FOLLOWS{route:""R1}]->(place{name: "B" })-[:FOLLOWS{route:""R4}]->(place{name:"C"})-[:FOLLOWS

Im建模一个图,其中节点是位置,边表示可以从一个位置移动到另一个位置

这就是你可以从一个地方到另一个地方的所有路线, 你可以通过不同的路线从一个地方到另一个地方,所以我需要一个查询,它能返回最短的路径,路线变化最小

例如,我想从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"})
在前两条路径中,两条路径的大小相同,但我想得到第二条路径,即路线更改最少的路径


谢谢。

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

// 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

@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;
大概是这样的:

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

得了吧,只有3个答案你不会高兴的:)

匹配(a:Place{name:“a”}),(d:Place{name:“d”})
匹配p=所有最短路径((a)-[*]->(d))
返回p,
大小(过滤器(范围内的x)(0,大小(rels(p)))
其中(rels(p)[x])。路线(rels(p)[x-1])。路线))+长度(p)作为分数
按分数排序ASC
使用“所有最短路径”的答案是错误的

如果图表看起来像下图怎么办


好的,使用AllShortestPaths函数的查询结果将是“A-E-D”,而不是“A-B-C-D”…

只有当我更改此项时,才会按照我想要的方式工作:p=AllShortestPaths((A)-[:followers*]->(D))。谢谢。实际上我想要最少数量的路线更改,因为在一条路径中,我可以有两条路线,但在每一条边上都要进行更改。无论如何,我意识到我提出了两个问题:)对不起,误解了。这也很有帮助。谢谢。这是一个很棒的问题,我从答案中学到了不少。我喜欢这个问题——希望我能想出那个问题。对不起,我刚刚登录,我没有足够的“声誉”来评论:p
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