Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm to find non-dominated pairs

Given are pairs of integers (a1,b1),...,(an,bn). Pair i is "dominated" by pair j if ai < aj and bi < bj. What is an algorithm to quickly determine the list of pairs that are not dominated by any other pair?

We can check all the pairs, and for each pair, check whether it is dominated by any other pair by going through all the pairs again. This algorithm is order n^2. Is there an algorithm of order n or n log n?

like image 202
John Avatar asked Oct 14 '12 02:10

John


2 Answers

We can find the non-dominated pairs in O(n log n) time.

Sort the pairs by decreasing order of a_i and then iterate over the pairs. Also, keep track of the maximum b value seen so far, b_max. At each step, if the next (a_i,b_i) pair has a b value greater than b_max, append it to the answer list and update b_max. The final answer list will be the non-dominated pairs.

Correctness: a pair is dominated if and only if some pair has a larger a value and a larger b. When we consider a pair, we are comparing its b value precisely to the maximum b value among pairs with larger a’s, so we add a pair to the list if and only if it is not dominated.

Runtime: sorting the pairs by a value takes O(n log n) time. The iteration takes O(n) time, so the overall runtime is O(n log n).

like image 110
Paul S. Avatar answered Sep 24 '22 22:09

Paul S.


if I understand it correctly, a not dominated pair is one such that either a or b are greater or equal to the maximum value for a and b respectively.

So you just need to find such max values (a for loop O(n)) for both a and b, then execute another loop to find any couple satisfying the condition above stated. in summary, O(n) time complexity.

A small example in Java, returning an ArrayList of indexes for 'not dominated' pairs:

    ArrayList<Integer>findUndominatedPairIndexes(int[][]arrayOfPairs)
    {
        ArrayList<Integer>result=new ArrayList<Integer>();
        int maxX=Integer.MIN_VALUE;
        int maxY=Integer.MIN_VALUE;
        int i=arrayOfPairs.length;
        /**
         * get the max value
         */
        for(;--i>=0;)
        {
            int x=arrayOfPairs[i][0];
            int y=arrayOfPairs[i][1];
            if (x>maxX)
            {
                maxX=x;
            }
            if (y>maxY)
            {
                maxY=y;
            }
        }
        for(i=arrayOfPairs.length;--i>=0;)
        {
            int[] pair=arrayOfPairs[i];
            if (pair[0]>=maxX||pair[1]>=maxY)
            {
                result.add(new Integer(i));
            }

        }
        return result;
    }
like image 23
andrea Avatar answered Sep 25 '22 22:09

andrea