Greedy Algorithms
Greedy Algorithms
A greedy algorithm constructs a solution to the problem by always making a choice that looks the best
at the moment. A greedy algorithm never takes back its choices, but directly constructs the final solution.
For this reason, greedy algorithms are usually very efficient.
The difficulty in designing greedy algorithms is to find a greedy strategy that always produces an optimal
solution to the problem. The locally optimal choices in a greedy algorithm should also be globally
optimal. It is often difficult to argue that a greedy algorithm works.
★ Coin Problem:
The coin problem exemplifies a situation where a greedy algorithm may or may not produce an
optimal solution. The problem involves finding the minimum number of coins needed to form a given
sum of money n, using a set of coins {c1, c2, ..., ck} where each coin can be used any number of
times.
Example:
If the coins available are the euro denominations {1, 2, 5, 10, 20, 50, 100, 200} and the target
sum is n = 520, the greedy algorithm works as follows:
The solution is {200, 200, 100, 20} using four coins, which is optimal.
Limitations:
The greedy algorithm does not always yield the best solution for arbitrary coin sets. For example, with
the coin set {1, 3, 4} and target n = 6, the algorithm:
This results in {4, 1, 1} (three coins), but the optimal solution is {3, 3} (two coins). Thus, the
greedy algorithm fails for this coin set.
General Case:
For some coin sets, it is impossible to construct a greedy algorithm that always works. Counter
examples, like the one above, show the algorithm’s limitations. In these cases, dynamic programming
techniques can be used to find the optimal solution.
Scheduling problems often lend themselves to greedy algorithms. A classic example involves
maximizing the number of events that can be scheduled without overlapping, given their start and end
times.
Problem Description:
Each event is defined by a start and end time. The goal is to select the maximum number of non-
overlapping events.
Example:
Given events:
• A: (1, 3)
• B: (2, 5)
• C: (3, 9)
• D: (6, 8)
1. Shortest Duration: Select events with the shortest duration first. This approach can fail; for example,
choosing shorter events may prevent scheduling longer, non-overlapping ones.
2. Earliest Start Time: Select events that start the earliest. This approach can also fail; scheduling an
early-start event may block more events that could have been included.
3. Earliest End Time (Optimal): Select events that end the earliest. This strategy ensures the maximum
remaining time for subsequent events and always produces an optimal solution.
The correctness of the earliest-end-time algorithm can be proven by showing that any deviation from this
strategy leads to a suboptimal solution.
This problem involves scheduling tasks with durations and deadlines to maximize a score. For each
task, completing it earlier yields a higher score.
Problem Description:
Given n tasks, each with a duration and a deadline, the score for completing a task is d - x, where d is the
deadline and x is the completion time. The objective is to maximize the total score.
Example:
Tasks:
• A: (duration=4, deadline=2)
• B: (duration=3, deadline=5)
• C: (duration=2, deadline=7)
• D: (duration=4, deadline=5)
Greedy Strategy:
Sort tasks by increasing duration and execute them in that order. This strategy works because swapping
longer tasks with shorter ones improves the total score. The reasoning is simple: shorter tasks finished
earlier reduce penalties for subsequent tasks.
★ Minimizing Sums
This problem involves finding a value x that minimizes a specific sum for a given set of numbers. The
problem varies based on the form of the sum.
Minimize the sum ∑|ai − x|. The optimal x is the median of the numbers. The median minimizes the total
deviation because shifting x left or right increases the sum. For even numbers, any value between the two
medians is optimal.
Minimize the sum ∑(ai − x)^2. The optimal x is the average of the numbers. The squared differences
create a parabola-shaped function, with the minimum at the mean.
Example:
Numbers: [1, 2, 9, 2, 6]
Compression involves reducing the size of data by encoding it efficiently. A binary code assigns a
sequence of bits (codeword) to each character, with shorter codewords for more frequent characters.
Huffman Coding:
Huffman coding is a greedy algorithm that generates an optimal prefix-free binary code. The algorithm
constructs a binary tree based on character frequencies:
Example:
• A: 0
• B: 110
• C: 10
• D: 111
The compressed string is shorter than using a constant-length code, demonstrating Huffman coding’s
efficiency.
Greedy algorithms are a fundamental concept in computer science, often used to solve optimization
problems by making the locally optimal choice at each step with the hope of finding a global optimum. To
enhance your understanding, here are some recommended YouTube resources:
I. Jump Game
V. Candy
★ Conclusion
In summary, greedy algorithms are powerful tools for solving specific types of problems efficiently.
However, their applicability depends on the problem structure, and proving correctness often requires
careful reasoning. Examples like the coin problem, scheduling, task deadlines, sum minimization, and
Huffman coding highlight their strengths and limitations.