Neo4j的。 Dijkstra算法。查找包含一组节点的路径(graphalgo)

问题描述 投票:1回答:3

现在我正在测试dijkstra(org.neo4j.graphalgo.impl.shortestpath。*)。您可以在下面看到的代码:

 Dijkstra<Double> dijkstra = new Dijkstra<>(0.0,
         startNode,
         endNode,             
         CommonEvaluators.doubleCostEvaluator("weight"),
         new DoubleAdder(),
         new DoubleComparator(),
         Direction.BOTH,
         RelationshipTypes.rel);

如何定义必须包含在路径中的节点?有任何想法吗?

java neo4j dijkstra
3个回答
1
投票

你将不得不暴力破坏所有可能的路径。只要您想要包含许多节点,就可以使用此方法。这基本上是旅游销售人员的问题。你可以做什么:

  • 查找节点的所有排列(以便以所有可能的方式排序节点)
  • 为从第一个节点到第二个节点的每个排列开始一条最短路径,依此类推
  • 比较所有路径的权重并采用最短路径

请记住,尽可能减少节点数量,因为TSP是NP难问题。所以不要接近10个节点来包含。

我已经在github上使用了一些代码请求了这个功能。 Here is my request.


1
投票

正如Yoshi所说,这是一个TSP。在您的解决方案中,当您浏览所有可能的路径时,您可能会遇到麻烦,因为大图上的数量会迅速增加。

我想要提高性能的想法是在你希望包含在最终路径中的每个节点之间运行一个Dijkstra,然后创建一个新的图形,只需将这些节点和新计算的距离作为权重,然后运行Dijkstra算法和所有节点的分析都包含在这个(相当)较小的图上的给定路径中。


0
投票

所以我找到了简单的解决方案。刚做了任何改变。不确定它是否正确但它有效。

      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());

因此,使用CostEvaluator,我发现了必须包含的点列表中至少有一个点的路径。要获得具有所有点的路径,我刚刚添加了“if(path.containsAll(listIncAll))”。在最后一次,你会看到找到的路径。

© www.soinside.com 2019 - 2024. All rights reserved.