Java Neo4j。迪杰斯特拉。查找包含一组节点的路径(graphalgo)
现在我正在测试dijkstra(org.neo4j.graphalgo.impl.shortestpath.*)。您可以在下面看到的代码:Java Neo4j。迪杰斯特拉。查找包含一组节点的路径(graphalgo),java,neo4j,dijkstra,Java,Neo4j,Dijkstra,现在我正在测试dijkstra(org.neo4j.graphalgo.impl.shortestpath.*)。您可以在下面看到的代码: Dijkstra<Double> dijkstra = new Dijkstra<>(0.0, startNode, endNode, CommonEvaluators.doubleCostEvaluator("weight"), ne
Dijkstra<Double> dijkstra = new Dijkstra<>(0.0,
startNode,
endNode,
CommonEvaluators.doubleCostEvaluator("weight"),
new DoubleAdder(),
new DoubleComparator(),
Direction.BOTH,
RelationshipTypes.rel);
Dijkstra Dijkstra=新的Dijkstra(0.0,
startNode,
结束节点,
共同评价者。双重成本评价者(“权重”),
新的双加法器(),
新的双比较器(),
方向,两者,
关系类型(rel);
如何定义必须包含在路径中的节点?有什么想法吗?你必须对所有可能的路径进行暴力攻击。只要不需要包含太多的节点,就可以使用这种方法。这基本上是旅行推销员的问题。 您可以做什么:
- 查找节点的所有排列(以便以所有可能的方式排列节点)
- 为从第一个节点到第二个节点的每个排列开始一条最短路径,依此类推
- 比较所有路径的长度,选择最短的路径
所以我找到了一个简单的解决方案。只是做了些改变。不确定它是否正确,但它是有效的
Dijkstra<Double> dijkstra = new Dijkstra<>(0.0,
startPoint,
endPoint,
new CostEvaluator<Double>() {
@Override
public Double getCost(final Relationship relationship, Direction direction) {
if (listIncAll.contains(relationship.getStartNode()) || listIncAll.contains(relationship.getEndNode())) {
return 0.0;
}else {
return relationship.getProperty("weight");
}
}
},
new DoubleAdder(),
new DoubleComparator(),
Direction.BOTH,
RelationshipTypes.rel);
Map<List<PropertyContainer>, Double> pathMap = new HashMap<>();
for (List<PropertyContainer> path : dijkstra.getPaths()) {
if (path.containsAll(listIncAll)) {
double fullWeight = 0;
Iterator<PropertyContainer> i = path.iterator();
while (i.hasNext()){
i.next();
if (i.hasNext()) {
Relationship r = (Relationship) i.next();
fullWeight += r.getProperty("weight");
}
}
pathMap.put(path,fullWeight);
}
}
System.out.println(pathMap.entrySet().stream().sorted((k1, k2) -> -k2.getValue().
compareTo(k1.getValue())).findFirst().get().getKey());
Dijkstra Dijkstra=新的Dijkstra(0.0,
起点,
终点,
新成本评估器(){
@凌驾
公共双getCost(最终关系、方向){
if(listIncAll.contains(relationship.getStartNode())| | listIncAll.contains(relationship.getEndNode()){
返回0.0;
}否则{
返回关系。getProperty(“权重”);
}
}
},
新的双加法器(),
新的双比较器(),
方向,两者,
关系类型(rel);
Map pathMap=newhashmap();
for(列表路径:dijkstra.getpath()){
if(路径containsAll(列表调用)){
双倍全重=0;
迭代器i=path.Iterator();
while(i.hasNext()){
i、 next();
if(i.hasNext()){
关系r=(关系)i.next();
全重+=r.getProperty(“重量”);
}
}
路径图。放置(路径,全重);
}
}
System.out.println(pathMap.entrySet().stream().sorted((k1,k2)->-k2.getValue()。
比较(k1.getValue()).findFirst().get().getKey());
因此,使用CostEvaluator,我从必须包含的点列表中找到了至少有一个点的路径。为了获得包含所有点的路径,我刚刚添加了“if(path.containsAll(listIncAll))”。在最后一个窗口中,您将看到找到的路径。正如Yoshi所说,这是一个TSP。在您的解决方案中,当通过所有可能的路径时,您可能会遇到麻烦,因为在大图上数量会快速增加
我的想法可能是提高性能,在您希望包含在最终路径中的每个节点之间运行Dijkstra,然后创建一个新的图形,仅将这些节点和新计算的距离作为权重,然后运行Dijkstra算法,并分析是否所有节点都包含在该路径上的给定路径中(相当多)更小的图表。谢谢你的回答!我找到了更简单的解决方法。如果我的方法不起作用,我会试试你的。我也想看看你的解决方案。所以,如果可行,请分享你的解决方案。是的,等5分钟。我会把它作为我问题的答案发布。我不确定这是一个正确的解决方案,但它有效。添加了一个答案。我的图表由55k点组成es和120K关系,我在2秒内找到路径。如果build.jar并将其用作插件,它将在Dijkstra女士中工作。我喜欢你的想法。我会考虑的。谢谢