Neo4j最短路径,两个方向相互依赖

时间:2014-03-17 14:13:05

标签: graph neo4j shortest-path

我设置了一个带有函数...

的图表
create (a:station {name:"a"}),
(b:station {name:"b"}),
(c:station {name:"c"}),
(d:station {name:"d"}),
(e:station {name:"e"}),
(f:station {name:"f"}),
(a)-[:CONNECTS_TO {time:8}]->(b),
(a)-[:CONNECTS_TO {time:4}]->(c),
(a)-[:CONNECTS_TO {time:10}]->(d),
(b)-[:CONNECTS_TO {time:3}]->(c),
(b)-[:CONNECTS_TO {time:9}]->(e),
(c)-[:CONNECTS_TO {time:40}]->(f),
(d)-[:CONNECTS_TO {time:5}]->(e),
(e)-[:CONNECTS_TO {time:3}]->(f)

并使用函数

START startStation=node:node_auto_index(name = "a"), endStation=node:node_auto_index(name = "f")
MATCH p =(startStation)-[r*]->(endStation)
WITH extract(x IN rels(p)| x.time) AS Times, length(p) AS `Number of Stops`, reduce(totalTime = 0, x IN rels(p)| totalTime + x.time) AS `Total Time`, extract(x IN nodes(p)| x.name) AS Route
RETURN Route, Times, `Total Time`, `Number of Stops`
ORDER BY `Total Time`

然后返回结果......

+-------------------------------------------------------------+
| Route             | Times    | Total Time | Number of Stops |
+-------------------------------------------------------------+
| ["a","d","e","f"] | [10,5,3] | 18         | 3               |
| ["a","b","e","f"] | [8,9,3]  | 20         | 3               |
| ["a","c","f"]     | [4,40]   | 44         | 2               |
| ["a","b","c","f"] | [8,3,40] | 51         | 3               |
+-------------------------------------------------------------+

除了因为它是一个有向图并且没有来自c -> b的路径它没有返回(例如)[a, c, b, e, f]这是一个长度为4的有效路径之外,这很好。 / p>

所以,如果我添加反向路径......

MATCH (START)-[r:CONNECTS_TO]->(END )
CREATE UNIQUE (START)<-[:CONNECTS_TO { time:r.time }]-(END )

再次运行查询我得到...(路径长度为1..4)...

+---------------------------------------------------------------------+
| Route                 | Times        | Total Time | Number of Stops |
+---------------------------------------------------------------------+
| ["a","d","e","f"]     | [10,5,3]     | 18         | 3               |
| ["a","c","b","e","f"] | [4,3,9,3]    | 19         | 4               |
| ["a","b","e","f"]     | [8,9,3]      | 20         | 3               |
| ["a","c","f"]         | [4,40]       | 44         | 2               |
| ["a","c","b","c","f"] | [4,3,3,40]   | 50         | 4               |
| ["a","c","f","e","f"] | [4,40,3,3]   | 50         | 4               |
| ["a","b","c","f"]     | [8,3,40]     | 51         | 3               |
| ["a","b","a","c","f"] | [8,8,4,40]   | 60         | 4               |
| ["a","d","a","c","f"] | [10,10,4,40] | 64         | 4               |
+---------------------------------------------------------------------+

这包括路径[a, c, b, e, f],但它还包括使用[a, c, b, c, f]两次的c和使用[a, c, f, e, f](目的地?!)两次的f

有没有一种过滤路径的方法,所以每条路径只包含一次相同的节点?

1 个答案:

答案 0 :(得分:1)

你可以在事后做过滤,但这可能不是最快的事。

这样的事情:

START startStation=node:node_auto_index(name = "a"), endStation=node:node_auto_index(name = "f")
MATCH p = (startStation)-[r*..4]->(endStation)

WHERE length(reduce (a=[startStation], n IN nodes(p) | CASE WHEN n IN a THEN a ELSE a + n END)) = length(nodes(p))

WITH extract(x IN rels(p)| x.time) AS Times, length(p) AS `Number of Stops`, reduce(totalTime = 0, x IN rels(p)| totalTime + x.time) AS `Total Time`, extract(x IN nodes(p)| x.name) AS Route
RETURN Route, Times, `Total Time`, `Number of Stops`
ORDER BY `Total Time`

我创建了一个GraphGist,其中包含您的问题和答案,作为可执行的实时文档。

见这里:Neo4j shortest path with rels in both directions