Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maximum non-overlapping intervals in a interval tree

Given a list of intervals of time, I need to find the set of maximum non-overlapping intervals.

For example,

if we have the following intervals:

[0600, 0830], [0800, 0900], [0900, 1100], [0900, 1130], 
[1030, 1400], [1230, 1400]

Also it is given that time have to be in the range [0000, 2400].

The maximum non-overlapping set of intervals is [0600, 0830], [0900, 1130], [1230, 1400].

I understand that maximum set packing is NP-Complete. I want to confirm if my problem (with intervals containing only start and end time) is also NP-Complete.

And if so, is there a way to find an optimal solution in exponential time, but with smarter preprocessing and pruning data. Or if there is a relatively easy to implement fixed parameter tractable algorithm. I don't want to go for an approximation algorithm.

like image 517
shobhu Avatar asked Nov 08 '13 02:11

shobhu


People also ask

How do you find non-overlapping intervals?

Below are the steps: Sort the given set of intervals according to starting time. Traverse all the set of intervals and check whether the consecutive intervals overlaps or not. If the intervals(say interval a & interval b) doesn't overlap then the set of pairs form by [a.end, b.start] is the non-overlapping interval.

What is non-overlapping class interval?

(ii) Nonoverlapping Class Intervals: If the values of a variable in a collection of data are positive integers less than or equal to 50, we can group the data in five nonoverlapping intervals: 1 – 10, 11 – 20, 21 – 30, 31 – 40, 41 – 50. These are the groups of values of the variable.

How do you find overlapping time intervals?

Following is complete algorithm. 1) Sort all intervals in increasing order of start time. This step takes O(nLogn) time. 2) In the sorted array, if start time of an interval is less than end of previous interval, then there is an overlap.

What is meant by overlapping intervals?

Let's take the following overlapping intervals example to explain the idea: If both ranges have at least one common point, then we say that they're overlapping. In other words, we say that two ranges and are overlapping if: On the other hand, non-overlapping ranges don't have any points in common.


1 Answers

This is not a NP-Complete problem. I can think of an O(n * log(n)) algorithm using dynamic programming to solve this problem.

Suppose we have n intervals. Suppose the given range is S (in your case, S = [0000, 2400]). Either suppose all intervals are within S, or eliminate all intervals not within S in linear time.

  1. Pre-process:

    • Sort all intervals by their begin points. Suppose we get an array A[n] of n intervals.
      • This step takes O(n * log(n)) time
    • For all end points of intervals, find the index of the smallest begin point that follows after it. Suppose we get an array Next[n] of n integers.
      • If such begin point does not exist for the end point of interval i, we may assign n to Next[i].
      • We can do this in O(n * log(n)) time by enumerating n end points of all intervals, and use a binary search to find the answer. Maybe there exists linear approach to solve this, but it doesn't matter, because the previous step already take O(n * log(n)) time.
  2. DP:

    • Suppose the maximum non-overlapping intervals in range [A[i].begin, S.end] is f[i]. Then f[0] is the answer we want.
    • Also suppose f[n] = 0;
    • State transition equation:
      • f[i] = max{f[i+1], 1 + f[Next[i]]}
    • It is quite obvious that the DP step take linear time.

The above solution is the one I come up with at the first glance of the problem. After that, I also think out a greedy approach which is simpler (but not faster in the sense of big O notation):

(With the same notation and assumptions as the DP approach above)

  1. Pre-process: Sort all intervals by their end points. Suppose we get an array B[n] of n intervals.

  2. Greedy:

    int ans = 0, cursor = S.begin;
    for(int i = 0; i < n; i++){
        if(B[i].begin >= cursor){
            ans++;
            cursor = B[i].end;
        }
    }
    

The above two solutions come out from my mind, but your problem is also referred as the activity selection problem, which can be found on Wikipedia http://en.wikipedia.org/wiki/Activity_selection_problem.

Also, Introduction to Algorithms discusses this problem in depth in 16.1.

like image 59
jeffrey Avatar answered Oct 10 '22 15:10

jeffrey