Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Priority Queue Comparator

I have defined my own compare function for a priority queue, however the compare function needs information of an array. The problem is that when the values of the array changed, it did not affect the compare function. How do I deal with this? Code example:

import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {
    public static final int INF = 100;
    public static int[] F = new int[201];

    public static void main(String[] args){

        PriorityQueue<Integer> Q = new PriorityQueue<Integer>(201, 
            new Comparator<Integer>(){
                public int compare(Integer a, Integer b){
                    if (F[a] > F[b]) return 1;
                    if (F[a] == F[b]) return 0;
                    return -1;
                }
            });

            Arrays.fill(F, INF);
            F[0] = 0; F[1] = 1; F[2] = 2;
            for (int i = 0; i < 201; i ++) Q.add(i);
            System.out.println(Q.peek()); // Prints 0, because F[0] is the smallest
            F[0] = 10;
            System.out.println(Q.peek()); // Still prints 0 ... OMG
        }
   }
like image 208
Charles Gao Avatar asked Feb 06 '13 20:02

Charles Gao


People also ask

Can we use Comparator in PriorityQueue?

Note : This type of Priority queue is preferred in scenarios where customized ordering is required, i.e when one wants a different sorting order, then one can define its own way of comparing instances. Comparator can be implemented if there is a more complex comparing algorithm, e.g. multiple fields and so on.

How does Comparator work in Java PriorityQueue?

The comparator() method of PriorityQueue() class returns the comparator that is used to order the elements of this queue, or returns null if the elements of this queue are sorted according to natural ordering.

How do you implement a comparable PriorityQueue?

Since a priority queue needs to compare its elements and order them accordingly, the user defined class must implement the Comparable interface, or you must provide a Comparator while creating the priority queue. Otherwise, the priority queue will throw a ClassCastException when you add new objects to it.

What is PriorityQueue Java?

In this tutorial, we will learn about the PriorityQueue class of the Java collections framework with the help of examples. The PriorityQueue class provides the functionality of the heap data structure. It implements the Queue interface. Unlike normal queues, priority queue elements are retrieved in sorted order.


2 Answers

Your comparator is only getting called when you modify the queue (that is, when you add your items). After that, the queue has no idea something caused the order to change, which is why it remains the same.

It is quite confusing to have a comparator like this. If you have two values, A and B, and A>B at some point, everybody would expect A to stay bigger than B. I think your usage of a priority queue for this problem is wrong.

like image 125
zmbq Avatar answered Sep 22 '22 12:09

zmbq


So, essentially, you are changing your comparison criteria on the fly, and that's just not the functionality that priority queue contracts offer. Note that this might seem to work on some cases (e.g. a heap might sort some of the items when removing or inserting another item) but since you have no guarantees, it's just not a valid approach.

What you could do is, every time you change your arrays, you get all the elements out, and put them back in. This is of course very expensive ( O(n*log(n))) so you should probably try to work around your design to avoid changing the array values at all.

like image 39
Miquel Avatar answered Sep 20 '22 12:09

Miquel