Dijkstra算法中使用的优先级队列的比较器类实现?

时间:2013-08-06 23:19:32

标签: java collections priority-queue comparator comparable

我试图从CLRS实现Dijsktra算法 - 算法简介一书,但是,我在实现具有Comparator接口的优先级队列方面遇到了麻烦。这是我的Vertex课程,你可以看到;

public class Vertex {

    public boolean explored;
    public int vertexID;
    public LinkedList<Vertex> adjacencyList;
    public LinkedList<Edge> edgeSet;
    public int shortestDistance;
    public Vertex predecessor;

    public Vertex(int vertexID){

        this.vertexID = vertexID;
        this.explored = false;
        this.adjacencyList = new LinkedList<>();
        this.edgeSet = new LinkedList<>();
        this.shortestDistance = Integer.MAX_VALUE;
        this.predecessor = null;
    }
}

因此,最初shortestDistance属性声明为Integer.MAX_VALUE。此外,您可以看到从Comparator实现的类用于优先级队列。

public class WeightComparator implements Comparator<Vertex> {

    @Override
    public int compare(Vertex o1, Vertex o2) {

        return Math.min(o1.shortestDistance, o2.shortestDistance);
    }
}

我确信由于我的一些测试,整个实现没有任何逻辑错误,但是,在某些测试中它失败了。我用这个语句创建了对队列的引用

PriorityQueue<Vertex> queue = new PriorityQueue<>(N, weightComparator);

其中N是队列的大小。所以,如果我对它的工作方式有误,请纠正我。当你poll一个项目时,它会删除优先级最低的项目?希望能够清楚地理解我的问题,如果有人可以提供帮助,我将非常感激。所以,谢谢

2 个答案:

答案 0 :(得分:6)

Math.min为您提供两个较小的值。将其作为比较值返回是错误的。

compare返回值&lt; 0表示第一个值小于第二个值,但如果返回Math.Min(5, 3),则会得到3,即> 0,这意味着比较器将告诉它3> 5.哪个错了。

您正在寻找的是:

public int compare(Vertex o1, Vertex o2) {
    return Integer.compare(o1.shortestDistance, o2.shortestDistance);
}

答案 1 :(得分:2)

除非shortestDistance可以为负数,否则您的比较器永远不会返回负数。因此,这不是一个正确的实施。

从概念上讲,基元的比较器应该返回一个减法:

return o1.shortestDistance-o2.shortestDistance;

或者反过来,如果你想降序。但是你需要注意溢出问题。