贪婪算法Word文档下载推荐.docx
《贪婪算法Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《贪婪算法Word文档下载推荐.docx(27页珍藏版)》请在冰豆网上搜索。
具有最大满意度值的饮料有时并没有足够的量来满足此婴儿解渴的需要。
设ai是第i种饮料的总量(以盎司为单位),而此婴儿需要t盎司的饮料来解渴,那么,需要饮用n种不同的饮料各多少量才能满足婴儿解渴的需求呢?
设各种饮料的满意度已知。
令xi为婴儿将要饮用的第i种饮料的量,则需要解决的问题是:
找到一组实数xi(1≤i≤n),使n?
i=1sixi最大,并满足:
n?
i=1xi=t及0≤xi≤ai。
需要指出的是:
如果n?
i=1ai<
t,则不可能找到问题的求解方案,因为即使喝光所有的饮料也不能使婴儿解渴。
对上述问题精确的数学描述明确地指出了程序必须完成的工作,根据这些数学公式,可以对输入/输出作如下形式的描述:
输入:
n,t,si,ai(其中1≤i≤n,n为整数,t、si、ai为正实数)。
输出:
实数xi(1≤i≤n),使n?
i=1sixi最大且n?
i=1xi=t(0≤xi≤ai)。
t,则输出适当的错误信息。
在这个问题中,限制条件是n?
i=1xi=t且0≤xi≤ai,1≤i≤n。
而优化函数是n?
i=1sixi。
任何满足限制条件的一组实数xi都是可行解,而使n?
i=1sixi最大的可行解是最优解。
例1-2[装载问题]有一艘大船准备用来装载货物。
所有待装货物都装在货箱中且所有货箱的大小都一样,但货箱的重量都各不相同。
设第i个货箱的重量为wi(1≤i≤n),而货船的最大载重量为c,我们的目的是在货船上装入最多的货物。
这个问题可以作为最优化问题进行描述:
设存在一组变量xi,其可能取值为0或1。
如xi为0,则货箱i将不被装上船;
如xi为1,则货箱i将被装上船。
我们的目的是找到一组xi,使它满足限制条件n?
i=1wixi≤c且xi?
{0,1},1≤i≤n。
相应的优化函数是n?
i=1xi。
满足限制条件的每一组xi都是一个可行解,能使n?
i=1xi取得最大值的方案是最优解。
例1-3[最小代价通讯网络]城市及城市之间所有可能的通信连接可被视作一个无向图,图的每条边都被赋予一个权值,权值表示建成由这条边所表示的通信连接所要付出的代价。
包含图中所有顶点(城市)的连通子图都是一个可行解。
设所有的权值都非负,则所有可能的可行解都可表示成无向图的一组生成树,而最优解是其中具有最小代价的生成树。
在这个问题中,需要选择一个无向图中的边集合的子集,这个子集必须满足如下限制条件:
所有的边构成一个生成树。
而优化函数是子集中所有边的权值之和。
1.2算法思想
在贪婪算法(greedymethod)中采用逐步构造最优解的方法。
在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。
决策一旦作出,就不可再更改。
作出贪婪决策的依据称为贪婪准则(greedycriterion)。
例1-4[找零钱]一个小孩买了价值少于1美元的糖,并将1美元的钱交给售货员。
售货员希望用数目最少的硬币找给小孩。
假设提供了数目不限的面值为25美分、10美分、5美分、及1美分的硬币。
售货员分步骤组成要找的零钱数,每次加入一个硬币。
选择硬币时所采用的贪婪准则如下:
每一次选择应使零钱数尽量增大。
为保证解法的可行性(即:
所给的零钱等于要找的零钱数),所选择的硬币不应使零钱总数超过最终所需的数目。
假设需要找给小孩67美分,首先入选的是两枚25美分的硬币,第三枚入选的不能是25美分的硬币,否则硬币的选择将不可行(零钱总数超过67美分),第三枚应选择10美分的硬币,然后是5美分的,最后加入两个1美分的硬币。
贪婪算法有种直觉的倾向,在找零钱时,直觉告诉我们应使找出的硬币数目最少(至少是接近最少的数目)。
可以证明采用上述贪婪算法找零钱时所用的硬币数目的确最少(见练习1)。
例1-5[机器调度]现有n件任务和无限多台的机器,任务可以在机器上得到处理。
每件任务的开始时间为si,完成时间为fi,si<
fi。
[si,fi]为处理任务i的时间范围。
两个任务i,j重指两个任务的时间范围区间有重叠,而并非是指i,j的起点或终点重合。
例如:
区间[1,4]与区间[2,4]重叠,而与区间[4,7]不重叠。
一个可行的任务分配是指在分配中没有两件重叠的任务分配给同一台机器。
因此,在可行的分配中每台机器在任何时刻最多只处理一个任务。
最优分配是指使用的机器最少的可行分配方案。
假设有n=7件任务,标号为a到g。
它们的开始与完成时间如图13-1a所示。
若将任务a分给机器M1,任务b分给机器M2,...,任务g分给机器M7,这种分配是可行的分配,共使用了七台机器。
但它不是最优分配,因为有其他分配方案可使利用的机器数目更少,例如:
可以将任务a、b、d分配给同一台机器,则机器的数目降为五台。
一种获得最优分配的贪婪方法是逐步分配任务。
每步分配一件任务,且按任务开始时间的非递减次序进行分配。
若已经至少有一件任务分配给某台机器,则称这台机器是旧的;
若机器非旧,则它是新的。
在选择机器时,采用以下贪婪准则:
根据欲分配任务的开始时间,若此时有旧的机器可用,则将任务分给旧的机器。
否则,将任务分配给一台新的机器。
根据例子中的数据,贪婪算法共分为n=7步,任务分配的顺序为a、f、b、c、g、e、d。
第一步没有旧机器,因此将a分配给一台新机器(比如M1)。
这台机器在0到2时刻处于忙状态。
在第二步,考虑任务f。
由于当f启动时旧机器仍处于忙状态,因此将f分配给一台新机器(设为M2)。
第三步考虑任务b,由于旧机器M1在Sb=3时刻已处于闲状态,因此将b分配给M1执行,M1下一次可用时刻变成fb=7,M2的可用时刻变成ff=5。
第四步,考虑任务c。
由于没有旧机器在Sc=4时刻可用,因此将c分配给一台新机器(M3),这台机器下一次可用时间为fc=7。
第五步考虑任务g,将其分配给机器M2,第六步将任务e分配给机器M1,最后在第七步,任务2分配给机器M3。
(注意:
任务d也可分配给机器M2)。
上述贪婪算法能导致最优机器分配的证明留作练习(练习7)。
可按如下方式实现一个复杂性为O(nlogn)的贪婪算法:
首先采用一个复杂性为O(nlogn)的排序算法(如堆排序)按Si的递增次序排列各个任务,然后使用一个关于旧机器可用时间的最小堆。
例1-6[最短路径]给出一个有向网络,路径的长度定义为路径所经过的各边的耗费之和。
要求找一条从初始顶点s到达目的顶点d的最短路径。
贪婪算法分步构造这条路径,每一步在路径中加入一个顶点。
假设当前路径已到达顶点q,
且顶点q并不是目的顶点d。
加入下一个顶点所采用的贪婪准则为:
选择离q最近且目前不在路径中的顶点。
这种贪婪算法并不一定能获得最短路径。
例如,假设在图13-2中希望构造从顶点1到顶点5的最短路径,利用上述贪婪算法,从顶点1开始并寻找目前不在路径中的离顶点1最近的顶点。
到达顶点3,长度仅为2个单位,从顶点3可以到达的最近顶点为4,从顶点4到达顶点2,最后到达目的顶点5。
所建立的路径为1,3,4,2,5,其长度为10。
这条路径并不是有向图中从1到5的最短路径。
事实上,有几条更短的路径存在,例如路径1,4,5的长度为6。
根据上面三个例子,回想一下前几章所考察的一些应用,其中有几种算法也是贪婪算法。
例如,霍夫曼树算法,利用n-1步来建立最小加权外部路径的二叉树,每一步都将两棵二叉树合并为一棵,算法中所使用的贪婪准则为:
从可用的二叉树中选出权重最小的两棵。
LPT调度规则也是一种贪婪算法,它用n步来调度n个作业。
首先将作业按时间长短排序,然后在每一步中为一个任务分配一台机器。
选择机器所利用的贪婪准则为:
使目前的调度时间最短。
将新作业调度到最先完成的机器上(即最先空闲的机器)。
注意到在机器调度问题中,贪婪算法并不能保证最优,然而,那是一种直觉的倾向且一般情况下结果总是非常接近最优值。
它利用的规则就是在实际环境中希望人工机器调度所采用的规则。
算法并不保证得到最优结果,但通常所得结果与最优解相差无几,这种算法也称为启发式方法(heuristics)。
因此LPT方法是一种启发式机器调度方法。
定理9-2陈述了LPT调度的完成时间与最佳调度的完成时间之间的关系,因此LPT启发式方法具有限定性
能(boundedperformance)。
具有限定性能的启发式方法称为近似算法(approximationalgorithm)。
本章的其余部分将介绍几种贪婪算法的应用。
在有些应用中,贪婪算法所产生的结果总是最优的解决方案。
但对其他一些应用,生成的算法只是一种启发式方法,可能是也可能不是近似算法。
1.3.1货箱装船
这个问题来自例1-2。
船可以分步装载,每步装一个货箱,且需要考虑装载哪一个货箱。
根据这种思想可利用如下贪婪准则:
从剩下的货箱中,选择重量最小的货箱。
这种选择次序可以保证所选的货箱总重量最小,从而可以装载更多的货箱。
根据这种贪婪策略,首先选择最轻的货箱,然后选次轻的货箱,如此下去直到所有货箱均装上船或船上不能再容纳其他任何一个货箱。
例1-7假设n=8,[w1,...w8]=[100,200,50,90,150,50,20,80],c=400。
利用贪婪算法时,所考察货箱的顺序为7,3,6,8,4,1,5,2。
货箱7,3,6,8,4,1的总重量为390个单位且已被装载,剩下的装载能力为10个单位,小于剩下的任何一个货箱。
在这种贪婪解决算法中得到[x1,...,x8]=[1,0,1,1,0,1,1,1]且?
xi=6。
定理1-1利用贪婪算法能产生最佳装载。