【问题标题】:Neo4j. Dijkstra. Find paths including a set of nodes (graphalgo)新4j。迪杰斯特拉。查找包含一组节点的路径 (graphalgo)
【发布时间】:2018-02-28 13:02:28
【问题描述】:

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


    【解决方案1】:

    您将不得不暴力破解所有可能的路径。只要您不需要包含很多节点,就可以使用这种方法。这基本上是旅行商问题。 你可以做什么:

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

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

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

    【讨论】:

    • 感谢您的回答!我找到了更简单的方法来解决它。如果我的方法行不通,我会试试你的。
    • 我也想看看你的解决方案。所以,如果它有效,请分享你的。
    • 是的,等 5 分钟。我会将其发布为我的问题的答案。我不确定这是一个正确的解决方案,但它确实有效。
    • 添加了答案。
    【解决方案2】:

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

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

    【讨论】:

    • 我的图表由 55k 个节点和 120K 个关系组成,我在 2 秒内找到了路径。如果构建 .jar 并将其用作插件,它将在 ms 中工作。 Dijkstra 速度很快。
    • 我喜欢你的想法。我会考虑的。谢谢
    【解决方案3】:

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

          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))”。在 last sout 中,您会看到找到的路径。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-17
      • 2011-10-26
      • 2021-11-13
      • 1970-01-01
      相关资源
      最近更新 更多