pi /wi 值最大的物品,这种策略也不能保证得到最优解。利用此策略试解 n= 3 ,w=[20,15,15], p=[40,25,25],
c=30 时的最优解。
我们不必因所考察的几个贪婪算法都不能保证得到最优解而沮丧, 0 / 1 背包问题是一个 N P-复杂问
题。对于这类问题,也许根本就不可能找到具有多项式时间的算法。虽然按 pi /wi 非递(增)减的次序装
入物品不能保证得到最优解,但它是一个直觉上近似的解。我们希望它是一个好的启发式算法,且大多数
时候能很好地接近最后算法。在 6 0 0 个随机产生的背包问题中,用这种启发式贪婪算法来解有 2 3 9 题为
最优解。有 5 8 3 个例子与最优解相差 1 0 %,所有 6 0 0 个答案与最优解之差全在 2 5 %以内。该算法能在
O (nl o gn)时间内获得如此好的性能。我们也许会问,是否存在一个 x (x<1 0 0 ),使得贪婪启发法的结果
与最优值相差在 x%以内。答案是否定的。为说明这一点,考虑例子 n =2, w = [ 1 ,y], p= [ 1 0 , 9y], 和 c=
y。贪婪算法结果为 x=[1,0], 这种方案的值为 1 0。对于 y≥ 1 0 / 9,最优解的值为 9 y。因此,贪婪算法的
值与最优解的差对最优解的比例为( ( 9y - 1 0)/9y* 1 0 0 ) %,对于大的 y,这个值趋近于 1 0 0 %。但是可
以建立贪婪启发式方法来提供解,使解的结果与最优解的值之差在最优值的 x% (x<100) 之内。首先将最
多 k 件物品放入背包,如果这 k 件物品重量大于 c,则放弃它。否则,剩余的容量用来考虑将剩余物品按
pi /wi 递减的顺序装入。通过考虑由启发法产生的解法中最多为 k 件物品的所有可能的子集来得到最优解。
例 13-9 考虑 n =4, w=[2,4,6,7], p=[6,10,12,13], c = 11。当 k= 0 时,背包按物品价值密度非递减顺序装
入,首先将物品 1 放入背包,然后是物品 2,背包剩下的容量为 5 个单元,剩下的物品没有一个合适的,
因此解为 x = [ 1 , 1 , 0 , 0 ]。此解获得的价值为 1 6。
现在考虑 k = 1 时的贪婪启发法。最初的子集为{ 1 } , { 2 } , { 3 } , { 4 }。子集{ 1 } , { 2 }产生与 k= 0
时相同的结果,考虑子集{ 3 },置 x3 为 1。此时还剩 5 个单位的容量,按价值密度非递增顺序来考虑如何
利用这 5 个单位的容量。首先考虑物品 1,它适合,因此取 x1 为 1,这时仅剩下 3 个单位容量了,且剩余
物品没有能够加入背包中的物品。通过子集{ 3 }开始求解得结果为 x = [ 1 , 0 , 1 , 0 ],获得的价值为 1 8。
若从子集{ 4 }开始,产生的解为 x = [ 1 , 0 , 0 , 1 ],获得的价值为 1 9。考虑子集大小为 0 和 1 时获得的最
优解为[ 1 , 0 , 0 , 1 ]。这个解是通过 k= 1 的贪婪启发式算法得到的。
若 k= 2,除了考虑 k< 2 的子集,还必需考虑子集{ 1 , 2 } , { 1 , 3 } , { 1 , 4 } , { 2 , 3 } , { 2 , 4 } 和{ 3 ,
4 }。首先从最后一个子集开始,它是不可行的,故将其抛弃,剩下的子集经求解分别得到如下结果:[ 1 ,
1 , 0 , 0 ] , [ 1 , 0 , 1 , 0 ] , [ 1 , 0 , 0 , 1 ] , [ 0 , 1 , 1 , 0 ] 和[ 0 , 1 , 0 , 1 ],这些结果中最后一个价值为 2 3,它的
值比 k= 0 和 k= 1 时获得的解要高,这个答案即为启发式方法产生的结果。 这种修改后的贪婪启发方法称
为 k 阶优化方法(k - o p t i m a l)。也就是,若从答案中取出 k 件物品,并放入另外 k 件,获得的结果
不会比原来的好,而且用这种方式获得的值在最优值的( 1 0 0 / (k + 1 ) ) %以内。当 k= 1 时,保证最终结
果在最佳值的 5 0 %以内;当 k= 2 时,则在 3 3 . 3 3 %以内等等,这种启发式方法的执行时间随 k 的增大
而增加,需要测试的子集数目为 O (nk ),每一个子集所需时间为 O (n),因此当 k >0 时总的时间开销为 O
(nk+1 )。实际观察到的性能要好得多。
1.3.3 拓扑排序
一个复杂的工程通常可以分解成一组小任务的集合,完成这些小任务意味着整个工程的完成。例如,
汽车装配工程可分解为以下任务:将底盘放上装配线,装轴,将座位装在底盘上,上漆,装刹车,装门等
等。任务之间具有先后关系,例如在装轴之前必须先将底板放上装配线。任务的先后顺序可用有向图表示
——称为顶点活动( Activity On Vertex, AOV)网络。有向图的顶点代表任务,有向边(i, j) 表示先后关系:
任务 j 开始前任务 i 必须完成。图 1 - 4 显示了六个任务的工程,边( 1 , 4)表示任务 1 在任务 4 开始前完
成,同样边( 4 , 6)表示任务 4 在任务 6 开始前完成,边(1 , 4)与(4 , 6)合起来可知任务 1 在任务 6 开
始前完成,即前后关系是传递的。由此可知,边(1 , 4)是多余的,因为边(1 , 3)和(3 , 4)已暗示了
这种关系。
在很多条件下,任务的执行是连续进行的,例如汽车装配问题或平时购买的标有“需要装配”的消费
评论0