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

时间:2018-02-28 13:02:29

标签: java neo4j dijkstra

现在我正在测试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);

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

3 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

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

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

答案 2 :(得分: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,我发现了必须包含的点列表中至少有一个点的路径。要获得具有所有点的路径,我刚刚添加了&#34; if(path.containsAll(listIncAll))&#34;。在最后一次,你会看到找到的路径。