The Greedy Method is a straightforward algorithmic paradigm often used for optimization problems. It builds a solution piece by piece, making the choice that looks best at the moment, with the hope that this local optimum will lead to a global optimum. This approach is particularly effective for problems exhibiting two key properties: optimal substructure and the greedy choice property.
The general method of greedy algorithms involves making a sequence of choices. At each stage, the algorithm considers a specific input and makes a decision whether to include it in the solution or not. This decision is based on some predefined selection procedure or greedy criterion, which aims to maximize or minimize a certain objective function.
A greedy algorithm proceeds in stages, making decisions that are:
For a greedy algorithm to guarantee an optimal solution, the problem must exhibit:
Not all optimization problems can be solved optimally using a greedy approach. It's crucial to verify these properties for a given problem.
The Fractional Knapsack Problem is a classic optimization problem where the goal is to fill a knapsack with items to maximize the total profit, given that the knapsack has a maximum weight capacity. Unlike the 0/1 Knapsack problem, items can be broken into fractions.
Problem Statement: Given objects, each with a profit and a weight , and a knapsack with a capacity . If a fraction of object is placed in the knapsack, a profit is earned, and a weight is consumed. The objective is to maximize the total profit: Subject to:
Greedy Strategy: The optimal greedy strategy for the Fractional Knapsack Problem is to prioritize items based on their profit-per-unit-weight ratio ().
Example: Let , capacity . Items: , , .
Calculate Ratios ():
Optimal Solution: Take Item 2 entirely, and half of Item 3. Total profit = .
#include <iostream>
#include <vector>
#include <algorithm> // For std::sort
// Structure to represent an item
struct Item {
int profit;
int weight;
double ratio; // profit/weight ratio
// Constructor
Item(int p, int w) : profit(p), weight(w) {
ratio = static_cast<double>(profit) / weight;
}
};
// Custom comparison function for sorting items by ratio in descending order
bool compareItems(const Item& a, const Item& b) {
return a.ratio > b.ratio;
The Job Sequencing with Deadlines problem aims to find a sequence of jobs, each with a profit and a deadline, to maximize the total profit. There is only one machine available, and each job takes one unit of time to complete.
Problem Statement: Given a set of jobs . Each job has an associated profit and an integer deadline . A job is completed by its deadline if it starts at time and finishes by time . Only one job can be processed at a time. The objective is to find a subset of jobs that can be completed by their deadlines and yields the maximum total profit.
Greedy Strategy: The greedy approach for Job Sequencing with Deadlines is as follows:
schedule[max_deadline], where max_deadline is the largest deadline among all jobs).Example: Let jobs. | Job | Deadline () | Profit () | | :-- | :--------------- | :------------- | | J1 | 2 | 20 | | J2 | 2 | 60 | | J3 | 1 | 40 | | J4 | 3 | 100 | | J5 | 4 | 80 |
Sort by Profit (descending):
Optimal Schedule: Total Profit: .
Visualizing the schedule:
Time Slot: 0-1 1-2 2-3 3-4
Job: J3 J2 J4 J5The Optimal Storage on Tapes problem deals with arranging programs on a single tape to minimize the mean retrieval time (MRT). When a program is to be retrieved, the tape is positioned at the front, and the tape head scans forward until the desired program is found.
Problem Statement: Given programs with lengths . These programs are to be stored on a computer tape. When a program is retrieved, the tape must scan through all programs stored before , including itself. The objective is to find an optimal permutation (order) of these programs on the tape that minimizes the .
If programs are stored in the order , where is the -th program in the sequence, the time required to retrieve is .
The Mean Retrieval Time (MRT) is calculated as:
Greedy Strategy: To minimize the MRT, the greedy strategy is straightforward:
Why this works: Placing shorter programs first minimizes the cumulative length that needs to be scanned for subsequent programs. This reduction in scan time for many programs at the beginning of the tape has a greater impact on the total retrieval time than placing longer programs early.
Example: Let programs with lengths: .
Sort by Length (ascending):
Optimal Storage Order:
The greedy choice (shortest program first) clearly yields a smaller MRT.
Tape Layout:
+-----+-----+--------+
| P3 | P1 | P2 |
| (3) | (5) | (10) |
+-----+-----+--------+
0 3 8 18 (Total length)
Retrieval Sequence:
1. P3: Scan 3 units
2. P1: Scan 3+5 = 8 units
3. P2: Scan 3+5+10 = 18 units
Sum of Retrieval Times = 3 + 8 + 18 = 29
Mean Retrieval Time = 29 / 3 approx 9.67While powerful, the greedy method isn't universally applicable. Its success hinges on the greedy choice property and optimal substructure. Problems like the 0/1 Knapsack Problem, where items cannot be fractioned, do not satisfy the greedy choice property; a locally optimal choice (e.g., taking an item with the highest profit/weight ratio) might prevent a better overall solution later. For such problems, dynamic programming or other methods are often required.
Other greedy applications not covered in detail here but often mentioned:
The principle that a locally optimal choice at each stage leads to a globally optimal solution for the overall problem.
The property where an optimal solution to a problem can be constructed from optimal solutions to its subproblems.
An optimization problem solved greedily by selecting items based on their profit-to-weight ratio to maximize total profit within a capacity, allowing item fractions.
A scheduling problem where jobs with profits and deadlines are prioritized to maximize total profit, typically by considering jobs with higher profits first and placing them in the latest possible valid time slot.
Arranging programs on a tape to minimize the mean retrieval time (MRT) by storing shorter programs first, as retrieval typically starts from the tape's beginning.
Test your understanding with 5 questions
Which characteristic is essential for a problem to be solvable using a greedy algorithm?
In the Fractional Knapsack Problem, what is the greedy criterion for selecting items?
Consider a Job Sequencing problem with deadlines. If two jobs have the same deadline but different profits, which job should be scheduled first according to the greedy approach?
When storing programs on a tape to minimize mean retrieval time, what is the optimal greedy strategy?
Which of the following problems is *not* typically solved using the greedy approach, but rather dynamic programming?
Sort by Ratio (descending):
Fill Knapsack:
Current Capacity = 20, Total Profit = 0.Current Capacity = 20 - 15 = 5.
Total Profit = 0 + 24 = 24.Initialize Schedule: Max deadline is 4. So, slots available: [slot 0, slot 1, slot 2, slot 3]
(representing time intervals respectively).
Schedule Jobs:
slot 0, slot 1, slot 2. Try slot 2. It's free.
Schedule J4 in slot 2. Total Profit = 100.
Schedule: [_, _, J4, _]slot 0, slot 1, slot 2, slot 3. Try slot 3. It's free.
Schedule J5 in slot 3. Total Profit = 100 + 80 = 180.
Schedule: [_, _, J4, J5]slot 0, slot 1. Try slot 1. It's free.
Schedule J2 in slot 1. Total Profit = 180 + 60 = 240.
Schedule: [_, J2, J4, J5]slot 0. Try slot 0. It's free.
Schedule J3 in slot 0. Total Profit = 240 + 40 = 280.
Schedule: [J3, J2, J4, J5]slot 0, slot 1. Both are taken. J1 is rejected.Calculate Retrieval Times and MRT for Optimal Order:
Consider a non-optimal order, e.g., :
6 Modules
6 Modules
Current Capacity = 5 - (10 \cdot 0.5) = 0Total Profit = 24 + (15 \cdot 0.5) = 24 + 7.5 = 31.5