【文档说明】计算机算法基础(第5章)课件.ppt,共(95)页,430.254 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-76548.html
以下为本文档部分文字说明:
计算机算法基础(第5章)贪心算法(又称贪婪算法)是指在问题求解时,总是做出在当前看来是最好的选择。也就是说,不是整体最优上,仅是在某种意义上的局部最优解贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题能产生整体最优解或者是整体最
优解的近似解5.1一般方法1.问题的一般特征问题有n个输入,问题的解是由这n个输入的某个子集组成,这个子集必须满足某些事先给定的条件。约束条件:子集必须满足的条件;可行解:满足约束条件的子集;可行
解可能不唯一;目标函数:用来衡量可行解优劣的标准,一般以函数的形式给出;最优解:能够使目标函数取极值(极大或极小)的可行解。分类:根据描述问题约束条件和目标函数的数学模型的特性和问题的求解方法的不同,可分为:线性规划、整数规划、非线性规划、动态规划等。——最优化问题求解贪心方法:一种改进的分级
的处理方法,可对满足上述特征的某些问题方便地求解。例[找零钱]一个人用100元买了价值3元的可乐(找钱97元)。售货员希望用数目最少的硬币找给他。假设提供数目不限的面值为50元、10元、5元及1元的钱币。售货员分步骤组成要找的零钱数选择硬币时所采用的贪心算法如下:每一次选择应使零钱数尽
量增大。为确保解法的可行性(即:所给的零钱等于要找的零钱数),所选择的硬币不应使零钱总数超过最终所需的数目假设需要找给小孩97分,首先入选的是1张50元的纸币,第2入选的不能是50元,否则将不可行(零钱总数超过97),应选择4张10元的,然后是1张5元,最后加入2个1元的硬币贪心算法,在找零
钱时,应使找出的纸币数目最少(至少是接近最少的数目)2.贪心方法的一般策略问题的一般特征:问题的解是由n个输入的、满足某些事先给定的条件的子集组成。1)一般方法根据题意,选取一种度量标准。然后按照这种度量标准对n个输入排序,并按序一次输入一个量。如果这个输入和当前已构成在这种量度意义下的部分最
优解加在一起不能产生一个可行解,则不把此输入加到这部分解中。否则,将当前输入合并到部分解中从而得到包含当前输入的新的部分解。2)贪心方法这种能够得到某种量度意义下的最优解的分级处理方法称为贪心方法注:贪心解最优解直接将目标函数作
为量度标准也不一定能够得到问题的最优解3)使用贪心策略求解的关键选取能够得到问题最优解的量度标准。?=3.贪心方法的抽象化控制描述procedureGREEDY(A,n)//A(1:n)包含n个输入//solution←Φ
//将解向量solution初始化为空//fori←1tondox←SELECT(A)//按照度量标准,从A中选择一个输入,其值赋予x并将之从A中删除//ifFEASIBLE(solution,x)then//判定x是否可以包含在解向量中,
即是否能共同构成可行解//solution←UNION(solution,x)//将x和当前的解向量合并成新的解向量,并修改目标函数//endifrepeatreturn(solution)endGREEDY5.2背包问题1.问题的描述已知n种
物品具有重量(w1,w2,…,wn)和效益值(p1,p2,…,pn),及一个可容纳M重量的背包;设当物品i全部或一部分xi放入背包将得到pixi的效益,这里,0≤xi≤1,pi>0。问题:采用怎样的装包方法才能使装入背包的物品的总效益最大?分析:①装入背包的总重量不能超过M②如果所有物品的
总重量不超过M,即≤M,则把所有的物品都装入背包中将获得最大可能的效益值③如果物品的总重量超过M,则将有物品不能(全部)装入背包中。由于0≤xi≤1,所以可以把物品的一部分装入背包,所以最终背包中可刚好
装入重量为M的若干物品(整个或一部分)目标:使装入背包的物品的总效益达到最大niiixw1问题的形式描述目标函数:约束条件:可行解:满足上述约束条件的任一集合(x1,x2,…,xn)都是问题的一个可行解——可行解可
能为多个。(x1,x2,…,xn)称为问题的一个解向量最优解:能够使目标函数取最大值的可行解是问题的最优解——最优解也可能为多个。niiixp1niwpxMxwiiiniii1,0,0,101例5.1
背包问题的实例设,n=3,M=20,(p1,p2,p3)=(25,24,15),(w1,w2,w3)=(18,15,10)。可能的可行解如下:(x1,x2,x3)①(1/2,1/3,1/4)16.524.25//没有放满背包//②(1,2/15,0)202
8.2③(0,2/3,1)2031④(0,1,1/2)2031.5①(1/2,1/3,6/10)2029.5①(1/2,2/3,1/10)2030iixpiixw2.贪心策略求解度量标准的选择:三种不同的选择1)以目标函数作为度量标准
即,每装入一件物品,就使背包背包获得最大可能的效益增量。该度量标准下的处理规则:●按效益值的非增次序将物品一件件地放入到背包;●如果正在考虑的物品放不进去,则只取其一部分装满背包:如果该物品的一部分不满足获得最大效益增量的度量标准,则
在剩下的物品种选择可以获得最大效益增量的其它物品,将它或其一部分装入背包。如:若ΔM=2,背包外还剩两件物品i,j,且有(pi=4,wi=4)和(pj=3,wj=2),则下一步应选择j而非i放入背包:pi/2=2<pj=3实例分析(例5.1)(p1,p2,p
3)=(25,24,15),(w1,w2,w3)=(18,15,10)∵p1>p2>p3∴首先将物品1放入背包,此时x1=1,背包获得p1=25的效益增量,同时背包容量减少w1=18个单位,剩余空间ΔM=2。其次考虑物品2和3。就ΔM=2而言有,只能
选择物品2或3的一部分装入背包。物品2:若x2=2/15,则p2x2=16/5=3.1物品3:若x3=2/10,则p3x3=3为使背包的效益有最大的增量,应选择物品2的2/15装包,即x2=2/15最后,背包装满,ΔM=0,故物品3将不能装入背包,x3=
0。背包最终可以获得效益值=x1p1+x2p2+x3p3=28.2(次优解,非问题的最优解)2)以容量作为度量标准以目标函数作为度量标准所存在的问题:尽管背包的效益值每次得到了最大的增加,但背包容量也过快地被消耗掉了,从而不能装入“更多”的物品。改进:让背包容量尽可能慢地消耗,从而
可以尽量装入“更多”的物品。即,新的标准是:以容量作为度量标准该度量标准下的处理规则:●按物品重量的非降次序将物品装入到背包;●如果正在考虑的物品放不进去,则只取其一部分装满背包;实例分析(例5.1)(p1,
p2,p3)=(25,24,15),(w1,w2,w3)=(18,15,10)∵w3<w2<w1∴首先将物品3放入背包,此时x3=1,背包容量减少w3=10个单位,还剩余空间ΔM=10。同时,背包获得p3=15的效益增量。其次考虑物品1和2。就ΔM=10而言有,也只能选择物品1或2的一
部分装入背包。为使背包的按照“统一”的规则,下一步将放入物品2的10/15装包,即x2=10/15=2/3最后,背包装满ΔM=0,故物品1将不能装入背包,x1=0。背包最终可以获得效益值=x1p1+x2p2+x3p3=
31(次优解,非问题的最优解)存在的问题:效益值没有得到“最大”的增加3)最优的度量标准影响背包效益值得因素:背包的容量M放入背包中的物品的重量及其可能带来的效益值可能的策略是:在背包效益值的增长速率和背包容量消耗速率之间取得平衡,即每次装入的物品应使它所占用的每
一单位容量能获得当前最大的单位效益。在这种策略下的量度是:已装入的物品的累计效益值与所用容量之比。新的量度标准是:每次装入要使累计效益值与所用容量的比值有最多的增加(首次装入)和最小的减小(其后的装入)。按照物品的单
位效益值:pi/wi比值(密度)的非增次序考虑。实例分析(例5.1)(p1,p2,p3)=(25,24,15),(w1,w2,w3)=(18,15,10)∵p1/w1<p3/w3<p2/w2∴首先将物品2放入背包,此时x2=1,背包容量减少w2=15个单位
,还剩余空间ΔM=5。同时,背包获得p2=24的效益增量。其次考虑物品1和3。此时,应选择物品3,且就ΔM=5而言有,也只能放入物品3的一部分到背包中。即x3=5/10=1/2最后,背包装满ΔM=0,故物品1将不能装入背包,x1=0。背包
最终可以获得效益值=x1p1+x2p2+x3p3=31.5(最优解)3.背包问题的贪心求解算法算法5.2背包问题的贪心算法procedureGREEDY-KNAPSACK(P,W,M,X,n)//p(1:n)和w(1:n)分别含有按P(i)/W(i)≥P(i+1)/W(i+
1)排序的n件物品的效益值和重量。M是背包的容量大小,而x(1:n)是解向量//realP(1:n),W(1:n),X(1:n),M,cu;integerI,nX←0//将解向量初始化为空//cu←M//cu是背包的剩余容量//fori
←1tondoifW(i)>cuthenexitendifX(i)←1cu←cu-W(i)repeatifi≤nthenX(i)←cu/W(i)endifendGREEDY-KNAPSACK4.最优解的证明即证明:由第三种策略所得到的贪心解是问题的最优解。最优解的含义:
在满足约束条件的情况下,可使目标函数取极(大或小)值的可行解。贪心解是可行解,故只需证明:贪心解可使目标函数取得极值。证明的基本思想:将此贪心解与(假设中的)任一最优解相比较。●如果这两个解相同,则显然贪心解就是最优解。否则,●这两个解
不同,就去找开始不同的第一个分量位置i,然后设法用贪心解的这个xi去替换最优解的那个xi,并证明最优解在分量代换前后总的效益值没有任何变化。可反复进行代换,直到新产生的最优解与贪心解完全一样。这一代换过程中,最优解
的效益值没有任何损失,从而证明贪心解的效益值与代换前后最优解的效益值相同。即,贪心解如同最优解一样可取得目标函数的最大/最小值。从而得证:该贪心解也即问题的最优解。定理5.1如果p1/w1≥p2/w2≥…≥pn/
wn,则算法GREEDY-KNAPSACK对于给定的背包问题实例生成一个最优解。证明:设X=(x1,x2,…,xn)是GRDDDY-KNAPSACK所生成的贪心解①如果所有的xi都等于1,则显然X就是问题的最优解。否则,②设j是使
xi≠1的最小下标。由算法可知,xi=11≤i<j,0≤xj<1xi=0j<i≤n若X不是问题的最优解,则必定存在一个可行解Y=(y1,y2,…,yn),使得:且应有:iiiixpypMywii设k
是使得yk≠xk的最小下标,则有yk<xk:a)若k<j,则xk=1。因为yk≠xk,从而有yk<xkb)若k=j,由于,且对1≤i<j,有yi=xi=1,而对j<i≤n,有xi=0;故此时若yk>xk,则将有,与Y是可行解相矛盾。而yk≠xk,所以yk<xkc)若k>j,
则,不能成立在Y中作以下调整:将yk增加到xk,因为yk≤xk,为保持解的可行性,必须从(yk+1,…,yn)中减去同样多的量。设调整后的解为Z=(z1,z2,…,zn),其中zi=xi,1≤i≤k,且有:则对于Z有:MxwiiMywiiMywii
nikkkkiiiyzwzyw)()(niiiinikiikkkkkiiniiiwpwzywpwyzypzp11/)(/)(nikkinikiikkkiiwpwzywyzyp1
/])()[(niiiyp1由以上分析得,若,则Y将不是最优解;若,则或者Z=X,则X就是最优解;或者Z≠X,则重复以上替代过程,或者证明Y不是最优解,或者把Y转换成X,从而证明X是最优解
iiiiypzpiiiiypzp5.3带有限期的作业排序1.问题描述假定在一台机器上处理n个作业,每个作业均可在单位时间内完成;同时每个作业i都有一个截至期限di>0,当且仅当作业i在其截至期限以前被完成时,则
获得pi>0的效益。问题:求这n个作业的一个子集J,其中的所有作业都可在其截至期限内完成。——J是问题的一个可行解。可行解J中的所有作业的效益之和是,具有最大效益值的可行解是该问题的最优解。如果所有的作业都能在其期限之内完成则
显然可以获得当前最大效益值;否则,将有作业无法完成——决策应该执行哪些作业,以获得最大可能的效益值。目标函数:约束条件:所有的作业都应在其期限之前完成JiipJiip例5.2n=4,(p1,p2,p3,p4)=(
100,10,15,20)和(d1,d2,d3,d4)=(2,1,2,1)。可行解如下表所示:问题的最优解是⑦。所允许的处理次序是:作业4、作业1可行解处理顺序效益值①(1)1100②(2)210③(3)315④(4)420⑤(1,2)2,1110⑥(1,3)1,3或3
,1115⑦(1,4)4,1120⑧(2,3)2,325⑨(3,4)4,3351.带有限期的作业排序算法1)度量标准的选择以目标函数作为量度。量度标准:下一个要计入的作业将是使得在满足所产生的J是一个可行解的限制
条件下让得到最大增加的作业。处理规则:按pi的非增次序来考虑这些作业。JiipJiip例:例5.2求解(p1,p2,p3,p4)=(100,10,15,20)(d1,d2,d3,d4)=(2,1,2
,1)①首先令J=Φ,②作业1具有当前的最大效益值,且{1}是可行解,所以作业1计入J;③在剩下的作业中,作业4具有最大效益值,且{1,4}也是可行解,故作业4计入J,即J={1,4};④考虑{1,3,4}和{1,2,4}均不能构成新的可行解,作业3和2将被舍弃。故最后的J={1
,4},最终效益值=120(问题的最优解)0Jiip2)作业排序算法的概略描述算法5.3procedureGREEDY-JOB(D,J,n)//作业按p1≥p2≥…≥pn的次序输入,它们的期限值D(i)≥1,1≤i≤n,n≥1。J是在它们的截止期限完成的作业的集合//J←{1}for
i←2tondoifJ∪{i}的所有作业能在它们的截止期限前完成thenJ←J∪{i}endifrepeatendGREEDY-JOB2.最优解证明定理5.2算法5.3对于作业排序问题总是得到问题的一个最优解证明:设J是由算法所得的贪心解作业集合,I是一个最优解的作业集合。①若I=J,则J就是
最优解;否则②,即至少存在两个作业a和b,使得a∈J且,b∈I且。并设a是这样的一个具有最高效益值的作业,且由算法的处理规则可得:对于在I中而不在J中的作业所有b,有:pa≥pbIaJbIJJI且9/3/202227•设SJ和SI分别是J和I的可行的调度表。因
为J和I都是可行解,故这样的调度表一定存在;设i是既属于J又属于I的一个作业,并i设在调度表SJ中的调度时刻是[t,t+1],而在SI中的调度时刻是[t’,t’+1]。在SJ和SI中作如下调整:●若t<t’,则将SJ中在[t’,t’+1]时
刻调度的那个作业(如果有的话)与i相交换。如果J中在[t’,t’+1]时刻没有作业调度,则直接将i移到[t’,t’+1]调度。——新的调度表也是可行的。反之,●若t’<t,则在SI中作类似的调换,即将SI中在[t,t+1]时刻调度的那个作业(如果有的话)与i相交换。如果I中在[t
,t+1]时刻没有作业调度,则直接将i移到[t,t+1]调度。——同样,新的调度表也是可行的。对J和I中共有的所有作业作上述的调整。设调整后得到的调度表为S’J和S’I,则在S’J和S’I中J和I中共有的所有作业将在相同的时间被
调度。设a在S’J中的调度时刻是[ta,ta+1],b是S’I中该时刻调度的作业。根据以上的讨论有:pa≥pb在S’I中,去掉作业b,而去调度作业a,得到的是作业集合I’=I-{b}∪{a}的一个可行的调度表,且I’的效益值不小于I的效益值。而I’中比I
少了一个与J不同的作业重复上述的转换,可使I在不减效益值的情况下转换成J。从而J至少有和I一样的效益值。所以J也是最优解(证毕)3.如何判断J的可行性方法一:检验J中作业所有可能的排列,对于任一种次序排列的作业排列,判断这些作业是否能够在其期限前完成——若J中有k个作业,则将要检查k!个序列方法二
:检查J中作业的一个特定序列就可判断J的可行性:对于所给出的一个排列σ=i1i2„ik,由于作业ij完成的最早时间是j,因此只要判断出σ排列中的每个作业dij≥j,就可得知σ是一个允许的调度序列,从而J是一个可行解。反之,如果σ排列
中有一个dij<j,则σ将是一个行不通的调度序列,因为至少作业ij不能在其期限之前完成。这一检查过程可以只通过检验J中作业的一种特殊的排列:按照作业期限的非降次序排列的作业序列即可完成。定理5.3设J是k个作业的集合,σ=i1i2…ik是J中作业的一种排列,它使得di1≤
di2≤…≤dik。J是一个可行解,当且仅当J中的作业可以按照σ的次序而又不违反任何一个期限的情况来处理。证明:①如果J中的作业可以按照σ的次序而又不违反任何一个期限的情况来处理,则J是一个可行解②若J是一个可行解,则必存在序列σ’=r1r2…rk,使
得drj≥j,1≤j≤k。★若σ=σ’,则σ即是可行解。否则,★σ≠σ’,令a是使得ra≠ia的最小下标,并设rb=ia。则有:b>a且dra≥drb(为什么?)在σ’中调换ra与rb,所得的新序列σ’’=s
1s2…sk的处理次序不违反任何一个期限。重复上述过程,则可将σ’转换成σ且不违反任何一个期限。故σ是一个可行的调度序列故定理得证。σ=i1i2…ia……ic…ikσ’=r1r2…ra…rb…rk★a<b★dra≥drb5.带有限期的作业排序算法的实现对当前正在考虑
的作业j,按限期大小采用一种“插入排序”的方式,尝试将其“插入”到一个按限期从小到大顺序构造的作业调度序列中,以此判断是否能够合并到当前部分解J中。如果可以,则插入到序列中,形成新的可行解序列。否则,舍弃该作业。具体如下:假设n个作业已经按照效益值从大到小的次序,即p1≥p
2≥…≥pn的顺序排列好,每个作业可以在单位时间内完成,并具有相应的时间期限;且至少有一个单位时间可以执行作业首先,将作业1存入部分解J中,此时J是可行的;然后,依次考虑作业2到n。假设已经处理了i-1个作业,其中有k个作业计入
了部分解J中:J(1),J(2),…,J(k),且有D(J(1))≤D(J(2))≤…≤D(J(k))对当前正在考虑的作业i,将D(i)依次和D(J(k)),D(J(k-1)),„,D(J(1))相比较,直到找到位置q:使得★D(i)<D(J(l)),q<l≤k,且★D(J(q))
≤D(i)此时,若D(J(l))>l,q<l≤k,即说明q位置之后的所有作业均可推迟一个单位时间执行,而又不违反各自的执行期限。最后,将q位置之后的所有作业后移一位,将作业i插入到位置q+1处,从而得到一个包含k+1个
作业的新的可行解。若找不到这样的q,作业i将被舍弃。对i之后的其它作业重复上述过程直到n个作业处理完毕。最后J中所包含的作业集合是此时算法的贪心解,也是问题的最优解。算法5.4带有限期和效益的单位时间的作业排序贪心算法procedureJS(D,J,n,k)/
/D(1),…,D(n)是期限值。n≥1。作业已按p1≥p2≥…≥pn的顺序排序。J(i)是最优解中的第i个作业,1≤i≤k。终止时,D(J(i))≤D(J(i+1)),1≤i<k//integerD(0:n),J(0:n),i,k,n,rD(0)←J(0)←0/
/初始化//k←1;J(1)←1//计入作业1//fori←2tondo//按p的非增次序考虑作业。找i的位置并检查插入的可行性//r←kwhileD(J(r))>D(i)andD(J(r))≠rdor←r-1repeatIfD(J(r))≤D
(i)andD(i)>rthen//把i插入到J中//fori←ktor+1by-1doJ(i+1)←J(i)//将插入点的作业后移一位//repeatJ(r+1)←i;k←k+1endifrepeatendJS计算时间分析fori←2tondo将循环n-1
次------------------①r←kwhileD(J(r))>D(i)andD(J(r))≠rdo至多循环k次,k是当前计入J中的作业数---②r←r-1repeatIfD(J(r))≤D(i)andD(i)>rthenfori←kto
r+1by-1do循环k-r次,r是插入点的位置-----③J(i+1)←J(i)repeatJ(r+1)←I;k←k+1endifrepeat设s是最终计入J中的作业数,则算法JS所需要的总时间是O(sn)。s≤n,故最坏情况:TJS=О(n2),
特例情况:pi=di=n-i+1,1≤i≤n最好情况:TJS=О(n),特例情况:di=i,1≤i≤n6.一种“更快”的作业排序问题不相交集合的UNION和FIND算法,可以将JS算法的计算时间降低到数量级接近О(n)例5.3设n=5,(p1,…,p5)=(20,15,10,5,1),
(d1,…,d5)=(2,2,1,3,3)。J已分配时间片正被考虑作业动作0无1分配[1,2]{1}[1,2]2分配[0,1]{1,2}[0,1],[1,2]3不适合,舍弃{1,2}[0,1],[1,2]4分配[2,3]{1,2,4}[0,1],
[1,2],[2,3]5舍弃最优解是J={1,2,4}9/3/2022••5.4最优归并模式1.问题的描述1)两个文件的归并问题两个已知文件的一次归并所需的计算时间=O(两个文件的元素总数)例:n个记录的文件+(n+m)个记录的文件m个记录的文件О(n+m)2)
多个文件的归并已知n个文件,将之归并成一个单一的文件例:假定文件X1,X2,X3,X4,采用两两归并的方式,可能的归并模式有:①X1+X2=Y1+X3=Y2+X4=Y3②X1+X2=Y1+→Y3X3+X4=Y2二路归并模式:每次仅作两个文件的归并;当有多个文件时,采用两两归
并的模式,最终得到一个完整的记录文件。二元归并树:二路归并模式的归并过程可以用一个二元树的形式描述,称之为二元归并树。如归并树的构造外结点:n个原始文件内结点:一次归并后得到的文件在两路归并模式下,每个内结点刚好有两个儿子,代表把它的两个儿子表示的文件归并成其本身所代表的文件6050302
010X1Z1XX3X2不同的归并顺序带来的计算时间是不同的。例5.5已知X1,X2,X3是分别为30、20、10个记录长度的已分类文件。将这3个文件归并成长度为60的文件。可能的归并过程和相应的记录移动次数如下:问题:采用怎样的归并顺序才能使归并过程中元素的移动次数最小(或执行的速度
最快)XX3X2X1移动50次移动60次XX1X2X3移动30次移动60次总移动次数:110次总移动次数:90次2.贪心求解1)度量标准的选择★任意两个文件的归并所需的元素移动次数与这两个文件的长度之和成正比;★度量标准:每次选择需要移动次
数最少的两个集合进行归并;★处理规则:每次选择长度最小的两个文件进行归并。95355203060301510F4F3Z1Z2Z4Z3F1F5F2(F1,F2,F3,F4,F5)=(20,30,10,5,30)
2)目标函数目标:元素移动的次数最少实例:为得到归并树根结点表示的归并文件,外部结点中每个文件记录需要移动的次数=该外部结点到根的距离,即根到该外部结点路径的长度。如,F4:则F4中所有记录在整个归并过程中移动的总量=|F4|*3带权外部路径长度:记di是由根到代表文件Fi的外部结
点的距离,qi是Fi的长度,则这棵树的代表的归并过程的元素移动总量是:最优的二路归并模式:与一棵具有最小外部带权路径长度的二元树相对应。F4Z1Z2Z4niiidq1算法5.6生成二元归并树的算法procedureTREE
(L,n)//L是n个单结点的二元树表//fori←1ton-1docallGETNODE(T)//构造一颗新树T//LCHILD(T)←LEAST(L)//从表L中选当前根WEIGHT最小的树,并从中删除//RCHILD(T)←LEAST(L)WEIGHT
(T)←WEIGHT(LCHILD(T))+WEIGHT(RCHILD(T))callINSERT(L,T)//将归并的树T加入到表L中//repeatreturn(LEAST(L))//此时,L中的树即为归并的结果//endTREE例5.6已知六个初始文件,长
度分别为:2,3,5,7,9,13。采用算法TREE,各阶段的工作状态如图所示:L迭代2357913023579131523579132510235791335101623579134510162323579135510162339时间分析1)循环体:n-1次2)L以有序序列表示LEA
ST(L):О(1)INSERT(L,T):О(n)总时间:О(n2)3)L以min-堆表示LEAST(L):О(logn)INSERT(L,T):О(logn)总时间:О(nlogn)3.最优解的证明定理5.4若L最初包含n≥1个单结点的树,这些树有WEIGH
T值为(q1,q2,…,qn),则算法TREE对于具有这些长度的n个文件生成一棵最优的二元归并树。证明:归纳法证明①当n=1时,返回一棵没有内部结点的树。定理得证。②假定算法对所有的(q1,q2,…,qn),1≤m<n,生成一棵最优二元归并树。③对于n,假定q1≤q2
≤…≤qn,则q1和q2将是在for循环的第一次迭代中首先选出的具有最小WEIGHT值的两棵树(的WEIGHT值);如图所示,T是由这样的两棵树构成的子树:q1q2q1+q2T■设T’是一棵对于(q1,q2,…,qn)的最优二元归并树。■设P
是T’中距离根最远的一个内部结点。若P的两棵子树不是q1和q2,则用q1和q2代换P当前的子树而不会增加T’的带权外部路径长度。故,T应是最优归并树中的子树。则在T’中用一个权值为q1+q2的外部结点代换T,得到的是一棵关于(q1+q2,…,qn)最优归并树T”。而由归纳假设,在用权值为q1+
q2的外部结点代换了T之后,过程TREE将针对(q1+q2,…,qn)得到一棵最优归并树。将T带入该树,根据以上讨论,将得到关于(q1,q2,…,qn)的最优归并树。故,TREE生成一棵关于(q1,q2,…,qn)的
最优归并树。5.k路归并模式每次同时归并k个文件。k元归并树:可能需要增加“虚”结点,以补充不足的外部结点。★如果一棵树的所有内部结点的度都为k,则外部结点数n满足nmod(k-1)=1★对于满足nmod(k-1)=1的整数n,存在一棵具
有n个外部结点的k元树T,且T中所有结点的度为k。至多需要增加k-2个外部结点。k路最优归并模式得贪心规则:每一步选取k棵具有最小长度的子树归并。5.5最小生成树1.问题的描述生成树:设G=(V,E)是一个
无向连通图。如果G的生成子图T=(V,E')是一棵树,则称T是G的一棵生成树(spanningtree).最小生成树:2.贪心策略度量标准:选择能使迄今为止所计入的边的成本和有最小增加的那条边。●Prim算法●Kruskal算法125643最小
生成树——PRIM算法1256431621331418196105166518最小生成树——PRIM算法111256431621331418196105166518最小生成树——PRIM算法1112564321331419105166518最小
生成树——PRIM算法111256435166518最小生成树——PRIM算法113.Prim算法策略:使得迄今所选择的边的集合A构成一棵树;对将要计入到A中的下一条边(u,v),应是E中一条当前不在A中且使得A∪{(u,v)
}也是一棵树的最小成本边。1462531030204525554050153512162162316234边(1,2)(2,6)(3,6)(6,4)成本102515201462531020251535边(3,5
)成本35V(TP)={1,2,3,4,5,6}E(TP)={(1,2),(2,6),(3,5),(4,6),(3,6)}算法5.7Prim最小生成树算法procedurePRIM(E,COST,n,T,mincost)//E是G的边
集。COST(n,n)是n结点图G的成本邻接矩阵,矩阵元素COST(i,j)是一个正实数,如果不存在边(i,j),则为+∞。计算一棵最小生成树并把它作为一个集合存放到数组T(1:n-1,2)中(T(i,1),T(i,2))是最小成本生成树的一条
边。最小成本生成树的总成本最后赋给mincost//realCOST(n,n),mincostintegerNEAR(n),n,i,k,l,T(1:n-1,2)(k,l)←具有最小成本的边mincost←COST(k,l)(T(l,1),T(l,2))←(k,l
)fori←1tondo//将NEAR置初值//ifCOST(i,l)<COST(i,k)thenNEAR(i)←lelseNEAR(i)←kendifrepeatNEAR(k)←NEAR(l)←0fori←2ton-1do//找T的其余n-
2条边//设j是NEAR(j)≠0且COST(j,NEAR(j))最小的下标(T(i,1),T(i,2))←(j,NEAR(j))mincost←mincost+COST(j,NEAR(j))NEAR(j)←0for
k←1tondo//修改NEAR//ifNEAR(k)≠0andCOST(k,NEAR(k))>COST(k,j)thenNEAR(k)←jendifrepeatrepeatifmincost>∞thenprint(‘nospanni
ngtree’)endifendPRIM计算复杂性:第3行花费Θ(e)(e=|E|)时间,第4行花费Θ(1)时间;第6-9行的循环花费Θ(n)时间;第12行和第16-20行的循环要求Θ(n)时间,因此第11-21行循环要花费
Θ(n)时间。所以PRIM算法具有的时间复杂度)(2n另一种PRIM算法最小生成树中包含了与每个结点v相关的一条最小成本边证明略方法:从一棵包含任何一个随意指定的结点而没有边的树开始这一算法,然后再逐条增加边。125643最小生成树——Kruskal算法1
256431621331418196105166518最小生成树——Kruskal算法111256432133141910166518最小生成树——Kruskal算法111256435166518最小生成树——Kruskal算法114.Kruskal算法
(连通)图的边按成本的非降次序排列,下一条计入生成树T中的边是还没有计入的边中具有最小成本、且和T中现有的边不会构成环路的边。1462531030204525554050153512162162316234边(1,2)(3,6)(4,6)(2,6)成本101520
2516234563453454551462531020251535边(1,4)(3,5)成本30舍弃35V(TK)={1,2,3,4,5,6}E(TK)={(1,2),(2,6),(3,5),(4,6),(3,6)}算法5.9Kruska
l算法procedureKRUSKAL(E,COST,N,T,mincost)//G有n个结点,E是G的边集。COST(u,v)是边(u,v)的成本。T是最小成本生成树的边集,mincost是它的成本//realmincost,COST(1
:n,1:n);integerPARENT(1:n),T(1:n-1,2),n以边成本为元素构造一个min堆PARENT←1//每个结点都在不同的集合中//i←mincost←0whilei<n-1and堆非空do从堆中删去最小成本边(u,v)并重新构造堆j←FIND(u);k←FIND(v
)if(j≠k)theni←i+1T(i,1)←u;T(i,2)←vmincost←mincost+COST(u,v)callUNION(j,k)endifrepeatifi≠n-1thenprint(‘nospanningtr
ee’)endifreturnendKRUSKAL注:●边集以min-堆的形式保存,一条当前最小成本边可以在О(loge)的时间内找到;●当且仅当图G是不连通的,i≠n-1;此时算法具有最坏的执行时间;●
算法的计算时间是О(eloge)5.6单源点最短路径1.问题描述最短路径问题:●每对结点之间的路径问题●特定线路下的最短路径问题●单源最短路径问题等单源最短路径问题已知一个n结点有向图G=(V,E
)和边的权函数c(e),求由G中某指定结点v0到其它各结点的最短路径。假定边的权值为正。125643单源点最短路径1256431621171418551051616518单源点最短路径11125643211
71455101616518单源点最短路径1112564317101618单源点最短路径11例5.10如图所示。设v0是起始点,求v0到其它各结点的最短路径。路径长度(1)v0v210(2)v0v2v32
5(3)v0v2v3v145(4)v0v445注:路径按照长度的非降次序给出v0v1v4v5v3v24545101520101533520302.贪心策略求解1)度量标准量度的选择:迄今已生成的所有路径长度之和——为使之达到
最小,其中任意一条路径都应具有最小长度:假定已经构造了i条最短路径,则下一条要构造的路径应是下一条最短的路径。处理规则:按照路径长度的非降次序依次生成从结点v0到其它各结点的最短路径。例:v0→v2v0→v2→v3v0→v2→v3→v1v0→v42)贪
心算法♠设S是已经对其生成了最短路径的结点集合(包括v0)。♠对于当前不在S中的结点w,记DIST(w)是从v0开始,只经过S中的结点而在w结束的那条最短路径的长度。则有,SW①如果下一条最短路径是到结点u,则这条路
径是从结点v0出发在u处终止,且只经过那些在S中的结点,即由v0至u的这条最短路径上的所有中间结点都是S中的结点:设w是这条路径上的任意中间结点,则从v0到u的路径也包含了一条从v0到w的路径,且其长度小于从v0到u的路径长度。v0,s1,s2,„,w,„,sm-1,u均在S中根据
生成规则:最短路径是按照路径长度的非降次序生成的,因此从v0到w的最短路径应该已经生成。从而w也应该在S中。故,不存在不在S中的中间结点。②所生成的下一条路径的终点u必定是所有不在S内的结点中且具有最小距离DIST(u)的结点。③如果选出了这样结点u并生成了从v0到u的最短路
径之后,结点u将成为S中的一个成员。此时,那些从v0出发,只经过S中的结点并且在S外的结点w处结束的最短路径可能会减少——DIST(w)的值变小:如果这样的路径的长度发生了改变,则这些路径必定是一条从v0开始,经过u然后到w的更短的路所致
。★根据DIST(w)的定义,它所表示的v0至w的最短路径上的所有中间结点都在S中;★只考虑<u,w>∈E和的情况★u是从v0至w的最短路径上所经过的结点。则有:DIST(w)=DIST(u)+c(u,w)Ewu,SWuv0算法5.10生成最短路径的贪心算法pr
ocedureSHORTEST-PATHS(v,COST,DIST,n)//G是一个n结点有向图,它由其成本邻接矩阵COST(n,n)表示DIST(j)被置以结点v到结点j的最短路径长度,这里1≤j≤n。DIST(v)被置成零//booleanS(1:n);realCOST(1:n,1:n
),DIST(1:n)integeru,v,n,num,I,wfori←1tondo//将集合S初始化为空//S(i)←0;DIST(i)←COST(v,i)repeatS(v)←1;DIST(v)←0//结点v计入
S//fornum←2ton-1do//确定由结点v出发的n-1条路//选取结点u,它使得DIST(u)=S(u)←1//结点u计入S//for所有S(w)=0的结点wdo//修改DIST(w)//DIST(w)=min(DIST(w),DIST(u)+COST(u,w))repea
trepeatendSHORTEST-PATHS)}({min0)(wDISTwS3)计算时间⑴算法3.10的计算时间是:О(n2)⑴fori←1tondoS(i)←0;DIST(i)←COST(v,i)r
epeat⑵fornum←2ton-1do选取结点u,它使得DIST(u)=S(u)←1for所有S(w)=0的结点wdoDIST(w)=min(DIST(w),DIST(u)+COST(u,w))repeatrepeat⑵最短路径算法的时间复杂度由于任何一条边都
有可能是最短路径中的边,所以求任何最短路径的算法都必须至少检查图中的每条边一次,所以这样的算法的最小时间是О(e)。邻接矩阵表示的图:О(n2))}({min0)(wDISTwS)(n)2(-n)(n)(n例5.11求下图中从v1出发到其余各结点的最短
路径v1v2v4v3v5v6v7205025705070105055403025图的成本邻接矩阵:0205030+∞+∞+∞+∞025+∞+∞70+∞+∞+∞0402550+∞+∞+∞+∞055+∞+∞+∞+∞+∞+∞01070+∞+∞+∞+∞+∞050+∞+∞+∞+∞+∞+∞0算法的执行轨迹描
述迭代选取的结点SDIST(1)(2)(3)(4)(5)(6)(7)置初值12345-2435611,21,2,41,2,4,31,2,4,3,51,2,4,3,5,60205030+∞+∞+∞0204530+∞90+∞02045308590+∞02045307090+∞0
204530709014002045307090130算法的执行在有n-1个结点加入到S中后终止3.最短路径生成树对于无向连通图G,由结点v到其余各结点的最短路径的边构成G的一棵生成树,称为最短路径生成树。注:不同起点v的生成树可能不同。213567485552
54035151050204530213567485254015102030213567485552515104530原始图由结点1出发的最短路径生成树最小成本生成树练习——最短路径、邻接矩阵1501234504
530103075350201535658550065354520355002095501535300805520403550vvvvvv思考题1.在Dijkstra算法中,事
先约定了所有边的权值为正数。如果边的权可以为负数,那么Dijkstra算法是否仍然成立?2.假定对于一个图G,已经生成了一棵由节点v出发的最短路径生成树p。如果图G中所有边的权值由ai变成ai2,ai>0,这时,p是否依
然是图G的最短路径生成树?3.计算F1(1),F1(2),F1(3),F1(4)的轨迹,将其计算时间与过程F(n)比较。procedureF1(n)//返回第n个斐波那契数//integernifn<
2thenreturn(1)elsereturn(F2(2,n,1,1))endifendF1procedureF2(i,n,x,y)ifi≤nthencallF2(i+1,n,y,x+y)endifreturn(y)endF24.在数据集n=5,A(1:5)=10,20,
12,18,16上模拟过程MAX1procedureMAX1(i)//查找数组A中最大值元素,并返回该元素的最大下标。//globalintegern,A(1:n),j,kintegeriifi<nthenj←MAX1(i+1)//递归调用//i
fA(i)>A(j)thenk←ielsek←jendifelsek←nendifreturn(k)//递归调用的返回//endMAX15.写一个递归程序。BINOM(n,m)=BINOM(n-1,m)+BIN
OM(n-1,m-1)BINOM(n,0)=BINOM(n,n)=0习题二2.递归表达式T(n)=g(n),n足够小=2T(n/2)+f(n),否则求①g(n)=O(1)和f(n)=O(n)②g(n)=O(1)和f(n)=O(1)15.模拟执行QUICKSORT算法(1,1,1,1,1)(5
,5,8,3,4,3,2)procedurePARTITION(m,p)integerm,p,i;globalA(m:p-1)v←A(m);i←m//A(m)是划分元素//looploopi←i+1untilA(i)≥vrepeatloopp←p-1untilA(
p)≤vrepeatifi<pthencallswap(A(i),A(p))elseexitendifrepeatA(m)←A(p);A(p)←vendPARTITIONprocedureQUICKSORT(p,q)
integerp,q;globaln,A(1:n)ifp<qthenj←q+1callPARTITION(p,j)callQUICKSORT(p,j-1)callQUICKSORT(j+1,q)endifendQUICKSORT超难题五个海盗抢到了100颗宝石,每一颗都一样大小和
价值连城。他们决定这么分:抽签决定自己的号码(1、2、3、4、5)首先,由1号提出分配方案,然后大家表决,当且仅当超过半数的人同意时,按照他的方案进行分配,否则将被扔进大海喂鲨鱼如果1号死后,再由2号提出分配方案,然后剩下的4人进行表决,当且仅当超过半数的人同意时,按
照他的方案进行分配,否则将被扔入大海喂鲨鱼依此类推条件:每个海盗都是很聪明的人,都能很理智地做出判断,从而做出选择。问题:第一个海盗提出怎样的分配方案才能使自己的收益最大化?设5个人分别是①②③④⑤假设前面的都扔海里了,由④来分,无论他怎么分(包括全给⑤),都面临被否决扔海里的危
险。所以,当③来分时,④⑤一个不给,全由③独吞,④为了避免被扔海里的危险,也要同意,③的方案成立。那么,在②分时,③是肯定要反对的,要赢得④⑤的同意,必须多给一个,否则有可能否决(对④⑤来说,反正③来分时还是0,你不多给一个就否决),所以②的分配方案一定是:②98
③0④1⑤1回到①来的分配,由于②肯定反对,为了赢得③④⑤的同意,必须在②分配方案的基础上给他们加一个,由于只需再争取两票,③④⑤中可以排除争取一个,从收益来说,排除④⑤中的一个即可,那么①的分配方案为:①98③1④(或⑤)1其它都不给!