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.
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.
(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.
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.
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.
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.
Pre-process:
A[n]
of n intervals.
O(n * log(n))
timeNext[n]
of n
integers.
i,
we may assign n
to Next[i]
.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.DP:
[A[i].begin, S.end]
is f[i]
. Then f[0]
is the answer we want.f[n] = 0
;f[i] = max{f[i+1], 1 + f[Next[i]]}
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)
Pre-process: Sort all intervals by their end points. Suppose we get an array B[n]
of n intervals.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With