Greedy Algorithm
Greedy Algorithm
⮚ A Greedy Algorithm is a problem-solving strategy where you make the best choice at
each step without overthinking the future. It's like going for the immediate advantage
without worrying if it's the absolute best in the end.
⮚ For example, think of a game where you need to collect coins to reach a target
amount. The greedy approach would be grabbing the biggest coin available at each
moment until you hit the goal. It might not always give you the absolute best result,
but it's a quick and simple way to get close.
Basic:
⮚ A greedy algorithm always makes the choice that looks best at the moment.
⮚ We hope that a locally optimal choice will lead to a globally optimal solution.
⮚ For some problems, it works.
⮚ Greedy algorithms tend to be easier to code
A Simple Example
Pick k numbers out of n numbers such that the sum of these k numbers is the largest.
Algorithm
FOR i = 1 to k
Pick out the largest number and
Delete this number from the input. ENDFOR
1. for i=1 to k do
2. pick out the largest number
3. delete this number from the input
4. end for
Optimization Problems
An optimization problem is the problem of finding the best solution from all
feasible solutions
● Fractional knapsack: we maximize our profit
● Activity selection: we maximize the number of activities
● Shortest path problem: we minimize the path length.
● Minimum spanning tree: we minimize the spanning tree weight
Pseudo-code (version 1)
return profit
pseudocode (version 2):
Function FractionalKnapsack(W, v[n], w[n])
5. sort items by vi/wi descending // vi, wi = value and weight of the ith item
6. cap_left = W, profit = 0 // cap_left = capacity left
7. i = 1
8. while cap_left > 0 and i <= n do
9. if cap_left ≥ wi then
10. profit = profit + vi
11. cap_left = cap_left - wi
12. else:
13. profit = profit + vi * cap_left/wi
14. cap_left = 0
15. i = i+1
16. end if
17. end while
return totalProfit;
}
int main() {
int n;
cout << "Enter the number of items: ";
cin >> n;
vector<Item> items(n);
cout << "Enter weight and profit for each item:\n";
for (int i = 0; i < n; ++i) {
cout << "Item " << i + 1 << " --> Weight: ";
cin >> items[i].weight;
cout << "Item " << i + 1 << " --> Profit: ";
cin >> items[i].profit;
}
int capacity;
cout << "Enter the capacity of the knapsack: ";
cin >> capacity;
return 0;
}
PROBLEM 02. Activity Selection Problem
Suppose we have a set S = {a_1, a_2, …, a_n} of n proposed activities that wish to
use a resource, such as a lecture hall, which can serve only one activity at a time.
Each activity a_i has a start time s_i and a finish time f_i, where 0 ≤ s_i < f_i < ∞. If
selected, activity a_i takes place during the half-open time interval [s_i, f_i).
Activities a_i and a_j are compatible if the intervals [s_i, f_i) and [s_j, f_j) do not
overlap. That is, a_i and a_j are compatible if s_i ≥ f_j or s_j ≤ f_i. In the
activity-selection problem, we wish to select a maximum-size subset of mutually
compatible activities.
int main(){
int s[] = { 1, 3, 0, 5, 8, 5 };
int f[] = { 2, 4, 6, 7, 9, 9 };
int n = sizeof(s) / sizeof(s[0]);
// Function call
printMaxActivities(s, f, n);
return 0;
}
PROBLEM 03. Greedy Coin Change
Given a value of V Rs and an infinite supply of each of the denominations {1, 2, 5,
10, 20, 50, 100, 500, 1000} valued coins/notes, The task is to find the minimum
number of coins and/or notes needed to make the change?
Examples:
Input: V = 70
Output: 2
Explanation: We need a 50 Rs note and a 20 Rs note.
Input: V = 121
Output: 3
Explanation: We need a 100 Rs note, a 20 Rs note, and a 1 Rs coin.
Procedure minCoinChange(Note):
coins[] = {1000, 500, 100, 50, 20, 10, 5, 2, 1}
num_of_coin = length(coins)
change_coin = []
int main(){
int n = 93;
cout << "Following is minimal"
<< " number of change for " << n << ": ";
findMin(n);
return 0;
}
Practice problems: https://leetcode.com/tag/greedy/