算法设计与分析 第五章 贪心算法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第五章 贪心算法

§1.贪心算法基本思想

找零钱 假如售货员需要找给小孩67美分的零钱。现在,售货员手中只有25美分、10美分、5美分和1美分的硬币。在小孩的催促下,售货员想尽快将钱找给小孩。她的做法是:先找不大于67美分的最大硬币25美分硬币,再找不大于67-25=42美分的最大硬币25美分硬币,再找不大于42-25=17美分的最大硬币10美分硬币,再找不大于17-10=7美分的最大硬币5美分硬币,最后售货员再找出两个1美分的硬币。至此,售货员共找给小孩6枚硬币。售货员的原则是拿尽可能少的硬币个数找给小孩。从另一个角度看,如果售货员将捡出的硬币逐一放在手中,最后一起交给小孩,那么售货员想使自己手中的钱数增加的尽量快些,所以每一次都尽可能地捡面额大的硬币。

装载问题 有一艘大船用来装载货物。假设有n 个货箱,它们的体积相同,重量分别是n w w w ,,21 ,货船的最大载重量是c 。目标是在船上装最多货箱该怎样装?如果用1=i x 表示装第i 个货箱,而0=i x 表示不装第i 个货箱,则上述问题是解优化问题:求n x x x ,,,21 ,

∑=n

i i x 1max (5.1.1)

c x i n

i i ≤∑=1

w (5.1.2)

贪心方法,顾名思义,是在决策中总是作出在当前看来是最好的选择。例如找零钱问题中,售货员每捡一个硬币都想着使自己手中的钱尽快达到需要找钱的总数。在装载问题中,每装一个货箱都想着在不超重的前提下让船装更多的箱子。但是贪心方法并未考虑整体最优解,它所作出的选择只是在某种意义上的局部最优选择。当然,在采用贪心算法时未必不希望结果是整体最优的。事实上,有相当一部分问题,采用贪心算法能够达到整体最优,如前面的找零钱问题以及后面将要讲到的单点源最短路径问题、最小生成树问题、工件排序问题等。为了更好理解贪心算法,我们将装载问题稍加推广,考虑可分割的背包问题。

背包问题 已知容量为M 的背包和n 件物品。第i 件物品的重量为i w ,价值是i p 。因而将物品i 的一部分i x 放进背包即获得i i x p 的价值。问题是:怎样装包使所获得的价值最大。即是如下的优化问题:

∑≤≤n

i i i x p 1max (5.1.3)

n

i w p x M

x w i i i n

i i i ≤≤>>≤≤≤∑≤≤1,0,0,101 (5.1.4)

采用贪心方法,有几种原则可循:a ).每次捡最轻的物品装;b ).每次捡价值最大的装;c ).每次装包时既考虑物品的重量又考虑物品的价值,也就是说每次捡单位价值i i w p 最大的装。按原则a 来装只考虑到多装些物品,但由于单位价值未必高,总价值不能达到最大;按原则b 来装,每次选择的价值最大,但同时也可能占用了较大的空间,装的物品少,未必能够达到总价值最大。比较合理的原

则是c )。事实上,按照原则c )来装,确实能够达到总价值最大。

程序5-1-1 背包问题贪心算法

GreedyKnapsack(p, w, M, x, n) //价值数组p[1:n]、重量数组w[1:n],

//它们元素的排列顺序满足p[i]/w[i]≥p[i+1]/w[i+1]; M 是背包容量, // x 是解向量

real p[1:n], w[1:n], x[1:n], M, rc; integer i, n;

x=0; // 将解向量初始化为零 rc=M; // 是背包剩余容量初始化为M for i from 1 to n do

if w[i] > rc then exit endif x[i]=1; rc=rc-w[i]; endfor if i ≤n then

x[i]=rc/w[i]; endif

end GreedyKnapsack

例子 n=3, M=20, p=(25, 24, 15), w=(18,15,10)(说明该算法的执行情况) 定理5.1.1 如果][/][]2[/]2[]1[/]1[n w n p w p w p ≥≥≥ ,则GreedyKnapsack 对于给定的背包问题实例生成一个最优解。

证明 设),,,(21n x x x x =是GreedyKnapsack 所生成的解,但不是最优解。因而必有某个i x 不为1。不妨设j x 是第一个这样的分量。于是,当j i <≤1时,1=i x ;

当j i =,10<≤i x ;当n i j ≤<时,0=i x 。不妨假定M x w i i =∑。因为x 不是最优解,必存在解向量),,,(21n y y y y =,使得∑∑>i i i i x p y p 。设k 是使得k k x y ≠的最小下标,则y k < x k . 这是因为:当j k <时,1=k x ,上述不等式自然成立;当j k ≥时,因为 ,11y x =,0,0,111===+--n k k k x x y x 所以由 ,k k y x <可推出

M x w y w n

i i i n i i i =>∑∑==1

1

,y 不是解向量,矛盾。

由k k x y <,可以假定M y w n

i i i =∑=1

,进而有

)(1

k k k n

k i i i y x w y w -≥∑+=。

现在取新的向量),,,(21n z z z z =满足

k k k k x z y x y z ===--,,,1111 ,n n k k y z y z ≤≤≤≤++0,,011 而且

)()(1k k k n

i k i i i y z w z y w -=-∑≤≤+

由上段的不等式,这样的向量z 是存在的,而且是背包问题的可行解,因为

M

y w y w y w z w z w y w z w n

i i i n

i k i

i k i i i n

i k i

i k k k i i i n

i i i ≤=

+=++=∑∑∑∑∑∑≤≤≤≤-≤≤≤≤+-≤≤≤≤11

111

11

至此,我们找到一个新的解向量z 。以下证明它的总价值不小于y 的总价值:

∑∑∑∑∑∑≤≤≤≤+≤≤≤<≤≤≤≤=

⎪⎭

⎫ ⎝⎛

---+≥---+=n

i i

i k

k n

i k i i i k k k n

i i i i

i n

i k i i i k k k k k n

i i i n

i i i y p w p w z y w y z y p w p w z y w p w y z y p z p 11111/)()(/)(/)(

中间的不等式是由于当k i >时有][/][][/][i w i p k w k p ≥而得。但是z 与x 的不同分量的个数比y 与x 的不同分量的个数至少减少一个。以z 代替y 进行上面的讨论,我们又可以找到新的解向量'z ,如此等等,由于分量的个数n n 有限,必到某一步停止,最后找到解向量*y ,它和x 有相同的分量,又与y 有不同的总价值(大

相关文档
最新文档