Greedy Algorithm - Activity-Selection-Problem & Optimal Merge Pattern
Greedy Algorithm - Activity-Selection-Problem & Optimal Merge Pattern
The Activity Selection Problem is an optimization problem which deals with the selection of
non-conflicting activities that needs to be executed by a single person or machine in a given
time frame.
Each activity is marked by a start and finish time. Greedy technique is used for finding the
solution since this is an optimization problem.
Let's consider that you have n activities with their start and finish times, the objective is to
find solution set having maximum number of non-conflicting activities that can be
executed in a single time frame, assuming that only one person or machine is available for
execution.
It might not be possible to complete all the activities, since their timings can collapse.
Two activities, say i and j, are said to be non-conflicting if si >= fj or sj >= fi where si
and sj denote the starting time of activities i and j respectively, and fi and fj refer to the
finishing time of the activities i and j respectively.
Greedy approach can be used to find the solution since we want to maximize the count of
activities that can be executed. This approach will greedily choose an activity with earliest
finish time at every step, thus yielding an optimal solution.
sol[] array refering to the solution set containing the maximum number of non-
conflicting activities.
Following are the steps we will be following to solve the activity selection problem,
Step 1: Sort the given activities in ascending order according to their finishing time.
Step 2: Select the first activity from sorted array act[] and add it to sol[] array.
Step 4: If the start time of the currently selected activity is greater than or equal to the finish
time of previously selected activity, then add it to the sol[] array.
In the table below, we have 6 activities with corresponding start and end time, the objective is
to compute an execution schedule having maximum number of non-conflicting activities:
5 9 a1
1 2 a2
3 4 a3
0 6 a4
5 7 a5
8 9 a6
Step 1: Sort the given activities in ascending order according to their finishing time.
1 2 a2
3 4 a3
0 6 a4
5 7 a5
5 9 a1
8 9 a6
Step 2: Select the first activity from sorted array act[] and add it to the sol[] array, thus sol
= {a2}.
Step 3: Repeat the steps 4 and 5 for the remaining activities in act[].
Step 4: If the start time of the currently selected activity is greater than or equal to the finish
time of the previously selected activity, then add it to sol[].
A. Select activity a3. Since the start time of a3 is greater than the finish time of a2 (i.e. s(a3)
> f(a2)), we add a3 to the solution set. Thus sol = {a2, a3}.
B. Select a4. Since s(a4) < f(a3), it is not added to the solution set.
C. Select a5. Since s(a5) > f(a3), a5 gets added to solution set. Thus sol = {a2, a3, a5}
D. Select a1. Since s(a1) < f(a5), a1 is not added to the solution set.
E. Select a6. a6 is added to the solution set since s(a6) > f(a5). Thus sol = {a2, a3, a5, a6}.
Hence, the execution schedule of maximum number of non-conflicting activities will be:
PROGRAM:
#include <bits/stdc++.h>
int main()
{
Activity arr[N];
for(int i=0; i<=N-1; i++)
{
cout<<"Enter the start and end time of "<<i+1<<" activity
\n";
cin>>arr[i].start>>arr[i].finish;
}
print_Max_Activities(arr, N);
return 0;
}
The program is executed using same inputs as that of the example explained above. This will
help in verifying the resultant solution set with actual output.
Time Complexity Analysis
Following are the scenarios for computing the time complexity of Activity Selection
Algorithm:
Case 1: When a given set of activities are already sorted according to their finishing time,
then there is no sorting mechanism involved, in such a case the complexity of the algorithm
will be O(n)
Case 2: When a given set of activities is unsorted, then we will have to use the sort()
method defined in bits/stdc++ header file for sorting the activities list. The time complexity
of this method will be O(nlogn), which also defines complexity of the algorithm.
Scheduling multiple competing events in a room, such that each event has its own start and
end time.
Scheduling manufacturing of multiple products on the same machine, such that each
product has its own production timelines.
Activity Selection is one of the most well-known generic problems used in Operations
Research for dealing with real-life business problems.
Optimal Merge Pattern
Merge a set of sorted files of different length into a single sorted file. We need to find an
optimal solution, where the resultant file will be generated in minimum time.
If the number of sorted files are given, there are many ways to merge them into a single
sorted file. This merge can be performed pair wise. Hence, this type of merging is called as 2-
way merge patterns.
As, different pairings require different amounts of time, in this strategy we want to determine
an optimal way of merging many files together. At each step, two shortest sequences are
merged.
To merge a p-record file and a q-record file requires possibly p + q record moves, the
obvious choice being, merge the two smallest files together at each step.
Two-way merge patterns can be represented by binary merge trees. Let us consider a set of n
sorted files {f1, f2, f3, …, fn}. Initially, each element of this is considered as a single node
binary tree. To find this optimal solution, the following algorithm is used.
At the end of this algorithm, the weight of the root node represents the optimal cost.
Example 1
Let us consider the given files, f1, f2, f3, f4 and f5 with 20, 30, 10, 5 and 30 number of
elements respectively.
50 + 60 + 65 + 95 = 270
Sorting the numbers according to their size in an ascending order, we get the following
sequence −
15 + 35 + 65 + 95 = 210
In this context, we are now going to solve the problem using this algorithm.
Initial Set
Step-1
Step-2
Step-3
Step-4
Example 2
#include<bits/stdc++.h>
priority_queue<int, vector<int>,
greater<int>> pq;
{
// Add sizes to priorityQueue
pq.push(files[i]);
int count = 0;
while(pq.size() > 1)
pq.pop();
pq.pop();
count += temp;
pq.push(temp);
return count;
int main()
{
// No of files
int n = 6;
int files[] = { 2, 3, 4, 5, 6, 7 };
// Total no of computations
return 0;
Output:
Minimum Computations = 68