PriorityQueue in C# doesn't work with custom comparer

518 Views Asked by At

Can someone help me understand why this doesn't work and how can make it work?

PriorityQueue<Candidate, int> pq = 
   new PriorityQueue<Candidate, int>(new EstimateCompare());
    
public class EstimateCompare: IComparer<Candidate>
{
    public int Compare(Candidate a, Candidate b)
    {
        int diff = a.estimateDistance -b.estimateDistance;
        return diff == 0 ? 0 : diff < 0 ? 1 : -1;
    }
}

Here is the error I get:

CS0535: 'EstimateCompare' does not implement interface member 'IComparer.Compare(int, int)' (in Solution.cs)

Tried using it like this and I get this error:

PriorityQueue<Candidate, int> pq = 
                    new PriorityQueue<Candidate, int>(new EstimateCompare());

public class EstimateCompare: IComparer<Candidate> {
      public int Compare(Candidate a, Candidate b) {
         return a.estimateDistance.CompareTo(b.estimateDistance);
     }

error CS1503: Argument 1: cannot convert from 'EstimateCompare' to 'System.Collections.Generic.IComparer?'

public class Candidate {
    int row;
    int col;
    int distanceSoFar;
    public int estimateDistance;
    
    public Candidate(int row, int col, int distanceSoFar, int estimateDistance) {
        this.row = row;
        this.col = col;
        this.distanceSoFar = distanceSoFar;
        this.estimateDistance = estimateDistance;
    }
}

Many Thanks!!

1

There are 1 best solutions below

0
fuglede On

The constructor you're using is PriorityQueue<TElement, TPriority>(IComparer<TPriority>), that is, TElement is Candidate, and TPriority is int, so the argument should be an instance of IComparer<int>, but EstimateCompare is an IComparer<Candidate>.

So for example, the example compiles if you instead used

PriorityQueue<Candidate, Candidate> pq = 
    new PriorityQueue<Candidate, Candidate>(new EstimateCompare());

But given what your implementation of Compare looks like, you probably don't want an IComparer at all, and you could instead do with your PriorityQueue<Candidate, int> and just use, say

pq.Enqueue(candidate, candidate.estimateDistance)

when adding elements to the queue.