使用JGrapht在有向边加权图中找出负循环

时间:2016-08-03 23:20:37

标签: java directed-graph jgrapht

是否可以使用JGrapht在有向边加权图中找到负循环?我查看了Javadocs并发现我可以使用CycleDetector来检测周期,但不是特定的负周期。 CycleDetector找到周期,但是如果不以某种方式探索它们,你无法判断它们是否是否定的。谢谢!

2 个答案:

答案 0 :(得分:2)

您可以尝试使用BellmanFordShortestPath,但是如果您查找从一个顶点到自身的路径,它将找不到循环,因为每个顶点都以权重0隐式连接到自身。

DefaultDirectedWeightedGraph<String, DefaultWeightedEdge> directedGraph = new DefaultDirectedWeightedGraph<>(DefaultWeightedEdge.class);

...

BellmanFordShortestPath<String, DefaultWeightedEdge> algorithm = new BellmanFordShortestPath(graph);

GraphPath<String, DefaultWeightedEdge> path = algorithm.getPath(node1, node1);

int length = path.getLength(); // returns 0
double weight = path.getWeight(); // returns 0.0

我能找到的最好的是org.jgrapht.alg.cycle中的算法,这些算法可以为您提供所有周期,然后您必须计算周期内路径的总重量。

private boolean hasNegativeLoop(DefaultDirectedWeightedGraph<String, DefaultWeightedEdge> graph){
    SzwarcfiterLauerSimpleCycles<String, DefaultWeightedEdge> cycleDetector = new SzwarcfiterLauerSimpleCycles<>(graph);

    List<List<String>> cycles = cycleDetector.findSimpleCycles();

    for (List<String> cycle : cycles){
        double cycleWeight = getCycleWeight(graph, cycle);

        if(cycleWeight < 0) return true;
    }

    return false;
}

private double getCycleWeight(DefaultDirectedWeightedGraph<String, DefaultWeightedEdge> graph, List<String> cycle) {
    double totalWeight = 0;

    for(int i = 1; i < cycle.size(); i++){
        double weight = graph.getEdgeWeight(graph.getEdge(cycle.get(i-1), cycle.get(i)));

        totalWeight += weight;
    }

    double weightBackToStart = graph.getEdgeWeight(graph.getEdge(cycle.get(cycle.size()-1), cycle.get(0)));

    return totalWeight + weightBackToStart;
}

与Bellman Ford负循环检测相比,这种方式效率更低,但可以作为实施的参考。

答案 1 :(得分:1)

一般情况下,您可以使用BellmanFordShortestPath来检查图表中的负循环,尽管不存在最短路径只会告诉您是否存在至少一个负循环。我没有正确看待JgraphT中的BellmanFordShortestPath实现,因此我无法为您提供代码。

除此之外,在https://cs.stackexchange.com/questions/6919/getting-negative-cycle-using-bellman-ford中有一篇简洁的论文。 该论文的工作链接应为:

https://www.semanticscholar.org/paper/Negative-Weight-Cycle-Algorithms-Huang/dc1391024d74f736aa7a9c24191a35e822589516/pdf

所以如果其他所有方法都失败了,你至少可以使用像DefaultDirectedWeightedGraph

这样的JgraphT图来自己实现一个工作算法