贪心算法的正确性证明

贪心算法的正确性证明

摘要

贪心算法最难的部分就是正确性的证明,常用的方法有归纳法(对算法步数归纳、对问题归纳)和交换论证法(从最优解出发,不变坏地替换,得到贪心策略的解)。下面以三个例子说明这些正确性证法。

  1. 活动选择问题——对算法步数归纳
  2. 最优装载问题——对问题规模归纳
  3. 最小延迟调度——交换论证

我的个人博客上的原文链接

活动选择问题

问题

S = { 1 , 2 , … , n } S = \{ 1,2,…,n\} S={1,2,,n}为n项活动的集合, s i 和 f i s_i和f_i sifi分别为活动i的开始和结束时间,活动i与j相容当且仅当 s i ≥ f j 或 s j > = f i s_i \geq f_j或s_j>=f_i sifjsj>=fi,求最大的活动集

贪心策略

按截止时间排序

伪代码:

贪心算法的正确性证明_第1张图片

正确性证明:对算法步数归纳

定理:算法Select执行到第k步,选择k项活动 i 1 = 1 , i 2 , … , i k i_1=1,i_2,…,i_k i1=1,i2,,ik,那么存在最优解A包含$ i_1=1 ,i_2,…,i_k $

只要此定理成立,算法至多到第n步得到最优解

归纳基础:设 S = { 1 , 2 , … . n } S = \{1,2,….n\} S={1,2,.n} 是活动集,活动按截止时间递增顺序排序,k=1,证明存在最优解包含活动1

任取最优解A,A中的活动按照截止时间递增的顺序排列,如果A的第一个活动为j,j不为1,令
A ′ = ( A − { j } ) ∪ { 1 } A' = (A-\{j\}) ∪\{1\} A=(A{j}){1}
由于 f 1 < = f j , A ′ f_1 <= f_j ,A' f1<=fjA 也是最优解,而且含有1

归纳步骤:

假设命题对k为真,证明对k+1也为真

算法执行到第k步,选择了活动 i 1 = 1 , i 2 , … , i k i_1=1,i_2,…,i_k i1=1,i2,ik 根据归纳假设存在最优解A包含 i 1 = 1 , i 2 , … , i k i_1=1,i_2,…,i_k i1=1,i2,,ik ,设最优解A包含$i_1=1,i_2,…,i_k $ ,A中剩下的活动选自集合$S’= { i | i ∈ S , s_i \geq f_k } $ ,且 A = { i 1 , i 2 , … , i k } ∪ B A = \{i_1,i_2,…,i_ k\} \cup B A={i1,i2,ik}B ,B一定是 S ′ S' S 的最优解

根据归纳基础,存在$S’ $ 的最优解B含有 S ′ S' S 中的第一个活动,设为 i k + 1 i_{k+1} ik+1 ,且$|B’| = |B| $,于是

1552637520943

最优装载

问题

n个集装箱1,2…,n装上轮船,集装箱i的重量为 w i w_i wi ,轮船载重量限制为 c c c ,无体积限制。如何使装上船的集装箱最多。(假设每个集装箱重量小于c)

贪心策略

将集装箱按照从轻到重排序,轻者先装

正确性证明:对规模归纳

  • 设箱子标号按照从轻到重记为1,2,…,n
  • n = 1 贪心选择显然得到最优解
  • 假设对规模n-1的输入得到最优解,证明对规模n的输入也得到最优解

贪心算法的正确性证明_第2张图片

最小延迟调度

问题

任务集合S,$\forall i∈S $ , d i 为 截 止 时 间 , t i 为 加 工 时 间 , 均 为 正 整 数 d_i为截止时间,t_i为加工时间,均为正整数 di,ti

一个调度f:S→N,f(i)为任务i的开始时间。求最大延迟达到最小的调度,即求f 使得

贪心算法的正确性证明_第3张图片

贪心策略

按照截止时间 d i d_i di从小到大选择任务,安排时不留空闲时间

伪代码:

正确性证明:交换论证

上述算法的解的性质:没有空闲时间,没有逆序(不存在 f ( i ) < f ( j ) , d i > d j f(i)<f(j) , d_i > d_j f(i)<f(j),di>dj)

命题1:所有没有逆序、没有空闲时间的调度具有相同的最大延迟

命题1证明 f 1 和 f 2 f_1和f_2 f1f2都没有逆序,具有相同截止时间的任务必须被连续安排。在这些连续安排的任务中最大延迟是最后一个任务,被延迟的时间只与已安排任务加工时间之和有关,与任务标号无关。

证明思想:从一个没有空闲时间的最优解出发,在不改变最优性的条件下,转变为没有逆序的解。

  1. 如果一个最优调度存在逆序,那么存在i < n使得(i,i+1构成一个逆序)
  2. 存在逆序(i,j),j = i + 1,那么交换i和j得到的解的逆序数减一,后面证明这个新的调度仍然最优
  3. 至多经过n(n-1)/2次交换得到一个没有逆序的最优调度

交换相邻逆序任务(i,j)不影响最优性

  1. 交换i,j显然对其他任务的延迟时间没有影响
  2. 交换后不增加j的延迟
  3. 任务i在 f 2 f_2 f2的延迟 L 2 i L_{2i} L2i 小于任务j在$f_1 $ 的延迟 L 1 j L_{1j} L1j 因此小于$ f_1 $的最大延迟

贪心算法的正确性证明_第4张图片

你可能感兴趣的:(算法)