Question

I plan to use PriorityQueue as a min heap for 5 elements, each element is a tuple declared as following:

 public class Tuple implements Comparator<Tuple> {
    public final int x;
    public final double y;

    public Tuple(int x, double y) {
        this.x = x;
        this.y = y;
    }

    public Tuple() {
        this.x = 0;
        this.y = 0;
    }

    @Override
    public int compare(Tuple o1, Tuple o2) {
        return (int) (o1.y - o2.y);
    }
}

Then, I declare my heap as

 PriorityQueue<Tuple> heap = new PriorityQueue<Tuple>(5, new Tuple());
 int capacity = 5;

Then, I add element with following code:

 if (capacity != 0) {
            if (score > 0) {
                Tuple tmp = new Tuple(i, score);
                heap.add(tmp);
                capacity -= 1;
            }
        } else {
            if (score > heap.peek().y) {
                OutPutPriorityQueue(heap);
                Tuple tmp = new Tuple(i, score);
                heap.remove();
                heap.add(tmp);
                OutPutPriorityQueue(heap);
            }
        }

in which, score is a double calculated elsewhere and OutPutPriorityQueue is declared as following:

 public void OutPutPriorityQueue(PriorityQueue<Tuple> heap){
    Tuple [] temp = new Tuple[5];
    for (int i=0;i<5;i++){
        temp[i] = heap.poll();
        System.out.print(temp[i].y+"\t");
    }
    System.out.println();
    for (int i=0; i<5; i++){
        heap.add(temp[i]);
    }
}

Sorry that I have listed too much codes here, but this is the first time I use PriorityQueue, I am not sure where it goes wrong and the logistic of code should be simple enough.

Then my problem is that, the output of my function OutPutPriorityQueue, which is supposed to print elements according to an order, print the elements in basically an arbitrary way, here is some sample:

 0.5549890273805606 0.6479515952918626  0.8593378488473195  0.53232731034541    1.0
 1.0    0.8593378488473195  0.53232731034541    0.8593378488473195  0.6479515952918626
 1.0    0.6479515952918626  0.8593378488473195  0.53232731034541    0.8593378488473195
 0.8593378488473195 1.6093378488473196  0.53232731034541    0.8593378488473195  0.6479515952918626 
 0.8593378488473195 0.6479515952918626  0.8593378488473195  0.53232731034541    1.6093378488473196
 1.6093378488473196 1.28601715282334    0.53232731034541    0.8593378488473195  0.6479515952918626

These numbers are difficult to read, but its behaviors can be summarized as following:

  1. every remove() and add() remove the head one, move the 5th one to head and insert a new one at second place.
  2. line 2n-1 should be exactly the same as line 2n, but they are different. the 2nd one (newest one) is swapped with 5th one
  3. it seems that there is no order defined in this queue, but I do define a compare() and pass it in.

I have no idea why this is happening, I hope someone can help me.
Do I use compare() correctly? or something else?

Many thanks!!

Was it helpful?

Solution

Not getting into the specifics of your queue the first thing I would do is change the comparator. Stay away from the cast and use the comparator supplied with Double.

public static int compare(double d1, double d2)

From the API: Returns - the value 0 if d1 is numerically equal to d2; a value less than 0 if d1 is numerically less than d2; and a value greater than 0 if d1 is numerically greater than d2.

The compare you have is error prone at bets may be causing an issue for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top