“在Work–Depth 模型中,把计算固定为带 precedence 边的有向无环图:每个节点恰耗一个离散时间步,总节点数即 work $W$,最长依赖链的节点数即 span $D$。给定…”
形式陈述
贪心算法维护一个可行的部分解,并反复按固定局部规则选择下一项;一旦选择便不回溯。它是一种算法设计范式,不是一条“取当前最好就会全局最好”的定理。一个完整贪心算法必须同时说明候选集合、可行性条件、选择次序与停止规则。
正确性通常归结为安全选择:在当前部分解下,存在某个全局最优解也包含贪心选中的下一项。证明这一点后,再把剩余部分视为同类子问题,才能递归或归纳地推出最终最优。交换论证、领先不变量和图上的割性质是实现这条主线的不同结构工具;列出工具名称本身并不构成证明。
这里的量词是“每做完一步,仍存在一个与当前选择一致的最优解”。不必证明所有最优解都包含该选择,也不能每轮只证明该项出现在某个与既有选择冲突的最优解里。把已选部分一直保留在交换前提中,才能把局部论证串成整次算法的证明。
直觉
贪心算法的表面动作是“现在就决定”,背后的证明图像却是“总能把一个最优解调整到同意这个决定”。若调整不会降低目标值,也不会破坏可行性,那么早期选择就没有封死通往最优解的道路。真正困难的部分不是找一个听起来合理的评分,而是发现问题中允许这种调整的结构。
动态规划通常保留多个可能影响未来的状态;贪心法只保留一条选择路径。少掉的那些状态必须由证明补回来:要么说明它们都可交换成当前路径,要么说明当前路径在每个前缀都不落后。没有这一步,简洁只是少搜索,并不意味着答案正确。
例子与边界
无权区间调度要求选择最多个两两不重叠的区间。按结束时间从早到晚扫描,每次接受与已选区间兼容的第一个候选。设贪心首选区间为
采用半开区间
若要求安排全部区间、把资源数降到最少,目标便变成区间分配。完美图中的区间实例按开始时刻处理,用最小堆复用最早释放的资源;每次必须新增资源时,同时重叠的区间就给出匹配的下界。这与此处按结束时刻选择最大兼容子集是两种不同的贪心证明。
若区间带收益,目标改成总收益最大,原交换便不能保证目标不降:收益
局部规则稍换就可能失败。硬币面额为
若算法只写“选最小权候选”,却没有说明何时跳过会破坏可行性的候选,它还不是完整算法。若论证只展示若干输入成功,则只是测试;贪心正确性需要覆盖每一步和所有合法实例的结构证明。
推论与应用
设计贪心算法时,可以先用小实例攻击候选规则:让最早、最短、最便宜或收益最高的选择互相竞争,观察某个局部决定是否阻断更好的组合。规则经得住反例后,再寻找交换映射或前缀不变量;这个顺序常比先写伪代码更快暴露错误。
最小生成树的安全边由割性质证明,拟阵贪心则刻画一类对所有权重都能由贪心获得最优解的可行集系统。另一些问题只有可量化的近似保证,例如集合覆盖按单位新增覆盖成本选择集合。它们共享不可回溯的选择方式,却必须分别说明保证是精确最优还是近似比。
参考资料
- Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022,Part IV, Ch. 15, Greedy Algorithms。
- Jon Kleinberg and Éva Tardos, Algorithm Design, Pearson, 2005,Ch. 4, greedy algorithms and exchange arguments。