Neo4J,获得所有路径和最短路径

时间:2017-01-15 11:23:35

标签: neo4j nosql

我有20个节点和21个路径,它们应该代表一个迷宫。

我现在想要从头到尾找到所有可能的路径(有3个)。

我还希望找到重量最轻的路径,在最小的伤害量的情况下。

非常感谢任何有关正确语法和任何改进提示的帮助,

这是一个问题,我已经尝试过,没有理解并且失败了......

MATCH p=(a {name:"START"})-[:PATH*tall woods..guard]->(s{name:"Finish"}) RETURN p AS shortestPath, reduce(length=0, r in relationships(p) | length+r.length) AS totalLength order by totalLength

MATCH p=(a {name:"START"})-[:ROAD*tall woods..guard]->(s{name:"Finish"}) RETURN p AS shortestPath, reduce(length=0, r in relationships(p) | length+r.length) AS totalLength order by totalLength limit 1

我假设[:Path * tall woods..guard]错了,我应该用逗号或别的东西写出所有路径吗?

这是我的迷宫:

create(a:LABYRINTH {name:"START"})-[:PATH {name:"spiders", damage:1}]-> (b:LABYRINTH{name:"B"}),
(a)-[:PATH {name:"tall woods", damage:1}]->(c:LABYRINTH {name:"C"}),
(c)-[:PATH {name:"lizards", damage:1}]->(d:LABYRINTH {name:"D"}),
(c)-[:PATH {name:"gremlins", damage:3}]-> (e:LABYRINTH {name:"E"}),
(e)-[:PATH {name:"dark woods", damage:0}]->(f:LABYRINTH {name:"F"}),
(e)-[:PATH {name:"old bridge", damage:2}]->(g:LABYRINTH {name:"G"}),
(g)-[:PATH {name:"orc", damage:5}]->(i:LABYRINTH {name:"I"}),
(i)-[:PATH {name:"dead end", damage:0}]->(h: LABYRINTH {name:"H"}),
(i)-[:PATH {name:"dusty planes", damage:0}]->(j: LABYRINTH {name:"J"}),
(i)-[:PATH {name:"ape", damage:3}]->(k: LABYRINTH {name:"K"}),
(k)-[:PATH {name:"mob", damage:1}]->(q: LABYRINTH {name:"Q"}),
(g)-[:PATH {name:"woods", damage:0}]->(z: LABYRINTH {name:"Z"}),
(z)-[:PATH {name:"dead planes", damage:0}]->(k),
(z)-[:PATH {name:"desert", damage:1}]->(m: LABYRINTH {name:"M"}),
(m)-[:PATH {name:"gorilla", damage:0}]->(n: LABYRINTH {name:"N"}),
(m)-[:PATH {name:"bridge", damage:0}]->(l: LABYRINTH {name:"L"}),
(l)-[:PATH {name:"mud", damage:1}]->(o: LABYRINTH {name:"O"}),
(i)-[:PATH {name:"waters", damage:2}]->(r: LABYRINTH {name:"R"}),
(r)-[:PATH {name:"witch", damage:1}]->(p: LABYRINTH {name:"P"}),
(q)-[:PATH {name:"guard", damage:0}]->(s: LABYRINTH {name:"Finish"}),
(r)-[:PATH {name:"old witch", damage:1}]->(s)

1 个答案:

答案 0 :(得分:1)

使用variable length relationships时,需要使用整数来指定关系遍历的最小和最大数量(这些是可选的),您不能在此处提供属性值。

我强烈建议您仔细阅读开发人员指南,特别是当您遇到试图获取某些工作的问题时。快速检查变量关系可以很容易地揭示使用此功能的正确方法。

要查找所有可能的路径,您需要在开始和结束节点上匹配,然后使用它们之间的变量关系使用匹配:

MATCH (a:LABYRINTH {name:"START"}), (s:LABYRINTH {name:"Finish"})
MATCH p = (a)-[:PATH*]->(s)
RETURN p

就最短路径的最小权重而言,安装dijkstra function后最容易使用APOC Procedures。您需要提供开始和结束节点,关系类型和遍历方向的过滤器,以及用于权重的关系属性。

MATCH (start:LABYRINTH{name:'START'}), (end:LABYRINTH{name:'Finish'})
CALL apoc.algo.dijkstra(start, end, 'PATH>', 'damage') YIELD path, weight
RETURN path, weight

修改

在没有APOC程序的情况下回应如何做到这一点(虽然建议安装就像它一样容易,并且你获得了很多有用的功能),你可以做到这一点,但你需要制作自己评估体重。

你可以使用reduce()函数来做到这一点,你可以在路径中的关系集合中使用它来获得损坏的总和,然后根据该总和进行排序并获得损坏最小的路径

MATCH p=(:LABYRINTH {name:"START"})-[rels:PATH*]->(:LABYRINTH {name:"Finish"})
WITH p, REDUCE(weight=0, rel in rels | weight + rel.damage) as damage
RETURN p, damage 
ORDER BY damage ASC
LIMIT 1