Java - 在Comparator中排序以在Priority Queue中使用

时间:2014-09-14 19:47:53

标签: java priority-queue comparator

我对如何根据比较器中的实现确定优先级队列的排序方式感到困惑。在这里,我想基于降序FScore进行排序,这意味着最低FScore将位于队列的顶部。我不确定我是否正确地做到了这一点(我将其用于A *算法)。

private class puzzleStateComparator implements Comparator<PuzzleState> {

    @Override
    public int compare(PuzzleState o1, PuzzleState o2) {
        //TODO

        int[] goalState = FastPuzzleSolver.this.initialState.getStateArray();

        int o1GScore = PuzzlePropertyUtility.numBlocksOutOfPlace(o1.getStateArray(), goalState);
        int o2GScore = PuzzlePropertyUtility.numBlocksOutOfPlace(o2.getStateArray(), goalState);

        int o1HScore = PuzzlePropertyUtility.calcManhattanDistanceSum(o1.getStateArray(), goalState);
        int o2HScore = PuzzlePropertyUtility.calcManhattanDistanceSum(o2.getStateArray(), goalState);

        int o1FScore = o1GScore + o1HScore;
        int o2FScore = o2GScore + o2HScore;

        return o1FScore - o2FScore;


    }

3 个答案:

答案 0 :(得分:3)

重要的是,比较两个整数的正确方法是:

//ascending order
return Integer.compare( o1Fscore, o2Fscore );

//descending order
return Integer.compare( o2Fscore, o1Fscore );

将整数与减法进行比较可能会导致上溢/下溢问题。

如果您使用的是java.util.PriorityQueue,那么您肯定需要降序版本,因为API文档说:

  

此队列的头部是最少元素   指定的排序。如果多个元素绑定最小值,则   头是这些元素之一 - 关系是任意打破的。该   队列检索操作poll,remove,peek和element访问   队列头部的元素。

完全不考虑:如果PuzzleState是不可变的(因为它可能应该是),那么每个州只计算一次G和H分数是值得的。

答案 1 :(得分:0)

我不知道你是如何通过PuzzlePropertyUtility计算这些值的,但是如果你想要降序,你需要将返回值恢复为

 return o2FScore - o1FScore ;

答案 2 :(得分:0)

要以相反的顺序对队列进行排序,您应该将第二个输入与第一个输入进行比较。在你的情况下,它将是:

return o2FScore - o1FScore;