Greedy Algorithms
此内容尚不支持你的语言。
The Greedy Paradigm
Section titled “The Greedy Paradigm”A greedy algorithm makes the locally optimal choice at each step, hoping this leads to a globally Optimal solution. Unlike dynamic programming, greedy algorithms do not consider all possible Subproblems, they commit to a choice and never reconsider.
When to Consider Greedy
Section titled “When to Consider Greedy”| Signal | Try Greedy First? |
|---|---|
| Problem has a matroid structure | Yes |
| Activity/resource scheduling with ordering | Yes |
| Huffman-like optimal prefix coding | Yes |
| Fractional version of a knapsack problem | Yes |
| MST or shortest path on non-negative weights | Yes |
| 0/1 knapsack, partition, edit distance | No (use DP) |
| TSP | No (NP-hard) |
| Problem requires “try all possibilities” to verify correctness | Probably No |
The Exchange Argument
Section titled “The Exchange Argument”The exchange argument is the primary proof technique for greedy correctness. The idea: assume an Optimal solution differs from the greedy solution, then show we can exchange some element of the Optimal solution with the greedy choice without making the solution worse.
Structure of an Exchange Argument
Section titled “Structure of an Exchange Argument”- Let be the greedy solution and be an optimal solution
- Find the first point where and differ
- Show that replacing the optimal”s choice with the greedy’s choice produces a solution that is at least as good as
- Conclude that there exists an optimal solution that agrees with the greedy at this step
- By induction, the greedy solution is optimal
Example: Activity Selection
Section titled “Example: Activity Selection”Given activities with start times and finish times Select the maximum number of non-overlapping activities.
Greedy: always pick the activity with the earliest finish time.
def activity_selection(activities): """ Maximum number of non-overlapping activities. Greedy: sort by finish time, pick earliest finishing. Time: O(n log n) for sorting Space: O(1) (excluding input) """ sorted_activities = sorted(activities, key=lambda x: x[1]) count = 0 last_finish = float('-inf')
for start, finish in sorted_activities: if start >= last_finish: count += 1 last_finish = finish
return countExchange argument proof:
Let be the greedy solution and be an optimal Solution, both sorted by finish time. has the earliest finish time of all activities. Since also finishes before We have . Replacing with in gives a valid solution (since finishes no later than It does not overlap With ). The new solution has the same size as and starts with . By induction, .