贪心算法
引言
在真实工程系统中,我们经常面临这样的问题:
数据规模巨大、系统状态动态变化、决策必须在毫秒级完成。
在这种条件下,很多“理论最优算法”并不可行。
贪心算法,正是工程系统在现实约束下做出的理性选择。
基础概念
贪心算法是一类在求解问题过程中,在每一步都选择当前看起来最优的方案,并期望通过一系列局部最优选择最终得到全局最优解的算法策略。
其核心特征可以概括为一句话:不回头、不试错,只做当前最优选择。
贪心算法不是一种具体算法,而是一种算法设计思想。
基本思想
贪心算法遵循以下基本原则:
局部最优选择
每一步都做出当前状态下的最优决策
不可回溯
一旦选择,不再撤销或修改
期望累积为全局最优
局部最优决策的累积能够导向全局最优解
与动态规划不同,贪心算法不会保存所有中间状态,也不比较不同路径的结果。
贪心选择性质在工程上的含义是:当前这一步的最优选择,不会破坏未来系统状态的可行性。
必要条件
一个问题适合使用贪心算法,通常必须满足以下两个性质:
贪心选择性质(Greedy Choice Property)
每一步的局部最优选择,必然存在于某个全局最优解中。
换言之,当前最优的选择不会阻碍最终得到最优解。
最优子结构(Optimal Substructure)
一个问题的最优解,可以由其子问题的最优解构成。
这是贪心算法与动态规划的共同前提。
误区警告
0/1 背包 ≠ 分数背包
问题背景
背包问题的基本描述:
- 给定若干物品
- 每个物品有重量和价值
- 背包容量有限
目标:最大化总价值
看似合理的贪心策略
按单位价值(价值/重量)从高到低选择物品。这个策略在“分数背包”中是完全正确的。
为什么在 0/1 背包中失败?
关键区别在于:
分数背包:物品可以拆分
0/1 背包:物品只能“选”或“不选”
反例说明
假设:
| 物品 |
重量 |
价值 |
单位价值 |
| A |
10 |
60 |
6 |
| B |
20 |
100 |
5 |
| C |
30 |
120 |
4 |
背包容量:50
贪心选择:
选 A(10)
选 B(20)
剩余容量 20,无法放 C
→ 总价值 = 160
最优解:
选 B + C
→ 总价值 = 220
失败原因分析
单位价值的局部最优选择,会阻断后续更优组合的可能性,不满足贪心选择性质。
正确做法
使用动态规划
状态:容量 × 物品数量
时间复杂度:O(nW)
工程启示
一旦选择具有“不可拆分性”,贪心算法往往不再适用。
最短路径(有负权)≠ Dijkstra
问题背景
最短路径问题广泛存在于:
- 网络路由
- 图计算
- 调度系统
看似合理的贪心策略
每次选择当前距离源点最近的节点,并将其路径固定。
这是 Dijkstra 算法 的核心思想。
为什么在有负权图中失败?
Dijkstra 的前提是:
一旦某个节点被选中,其当前最短路径不会再被更新。

最低0.47元/天 解锁文章
2135

被折叠的 条评论
为什么被折叠?



