shortest path between 2 nodes through waypoints in neo4j

两盒软妹~` 提交于 2021-02-08 10:12:53

问题


I have a graph in neo4j where a node represents a city and a relationship represents roads connecting the cities. The relationships are weighted and have a property called 'distance'. I want to find the shortest (least weighted path) between two cities A and B. This is easily done using Dijkstra's algorithm. The tricky part is that I have a set of cities which are to be covered in the path from A to B. In other words, the path from A to B should cover all the waypoints, the order doesn't matter. Something like providing a source, destination and list of waypoints and optimize:true in Google API. I have tried this using Cypher with the below query-

match(s:City{ID:"A"})
match(f:City{ID:"B"})
match (n:City) where n.name in ['City1','City2','City3','City4']
with collect(n) as wps 
match path=allshortestPaths((s)-[:ROADWAY*..9]->(f))
where ALL ( n in wps WHERE n in nodes(path) ) with path, 
reduce(d=0, rel IN relationships(path)| d+rel.displacement) as             
totaldistance,Extract (n in nodes(path)| n.name) as cities 
return cities, totaldistance, tofloat(totaldistance) as TD order by 
totaldistance

But this didn't work. Maybe because the path wasn't passing through all the waypoints. I am also trying to use A* or Dijkstra (using Neo4j Traversal) but not sure how to visit all the waypoints.

Thanks in advance!!


回答1:


Try using ANY rather ALL.

From the neo4j documentation

All - Tests whether a predicate holds for all elements of this list.

whereas

Any - Tests whether a predicate holds for at least one element in the list.

match(s:City{ID:"A"})
match(f:City{ID:"B"})
match (n:City) where n.name in ['City1','City2','City3','City4']
with collect(n) as wps 
match path=allshortestPaths((s)-[:ROADWAY*..9]->(f))
where ANY ( n in wps WHERE n in nodes(path) ) with path, 
reduce(d=0, rel IN relationships(path)| d+rel.displacement) as             
totaldistance,Extract (n in nodes(path)| n.name) as cities 
return cities, totaldistance, tofloat(totaldistance) as TD order by 
totaldistance

Edit - We can change this to ensure that all cities are included by combining multiple ANY in the where clause:

match(s:City{ID:"A"})
match(f:City{ID:"B"})
with collect(n) as wps 
match path=allshortestPaths((s)-[:ROADWAY*..9]->(f))
where ANY ( n in nodes(wps) WHERE n.name = 'City1' ) AND
      ANY ( n in nodes(wps) WHERE n.name = 'City2) 
with path, 
reduce(d=0, rel IN relationships(path)| d+rel.displacement) as             
totaldistance,Extract (n in nodes(path)| n.name) as cities 
return cities, totaldistance, tofloat(totaldistance) as TD order by 
totaldistance


来源:https://stackoverflow.com/questions/45808063/shortest-path-between-2-nodes-through-waypoints-in-neo4j

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!