- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第11章_近似算法
* Design and Analysis of Algorithm * 11.3.1 装箱问题 First Fit Decreasing(首次适宜降序FFD)算法 首先把物体按体积大小递减的顺序排序 然后用FF算法装入物体 Best Fit Decreasing(最适宜降序BFD)算法 首先把物体按体积大小递减的顺序排序 然后用BF算法装入物体 11.3.2 子集和问题 令S={s1, s2,…, sn}是一个正整数的集合,子集和问题要求在这个正整数集合中,找出其和不超过正整数C的最大和数的子集。 考虑蛮力法求解子集和问题,为了求得集合{s1, s2,…, sn}的所有子集和,先将所有子集和的集合初始化为L0={0},然后求得子集和中包含s1的情况,即L0中的每一个元素加上s1,用L0+s1表示对集合L0中的每个元素加上s1后得到的新集合,则所有子集和的集合为L1=L0+(L0+s1)={0, s1};再求得子集和中包含s2的情况,即L1中的每一个元素加上s2,所有子集和的集合为L2=L1+(L1+s2)={0, s1, s2, s1+s2};依此类推,一般情况下,为求得子集和中包含si(1≤i≤n)的情况,即Li-1中的每一个元素加上si,所有子集和的集合为Li=Li-1+(Li-1+si)。因为子集和问题要求不超过正整数C,所以,每次合并后都要在Li中删除所有大于C的元素。例如,若S={104, 102, 201, 101},C=308,利用上述算法求解子集和问题的过程如图11.7所示 L0={0} L1=L0+(L0+104)={0}+{104}={0, 104} L2=L1+(L1+102)={0, 104}+{102, 206}={0, 102, 104, 206} L3=L2+(L2+201)={0, 102, 104, 206}+{201, 303, 305, 407} ={0, 102, 104, 201, 206, 303, 305} L4=L3+(L2+101)={0, 102, 104, 201, 206, 303, 305}+{101, 203, 205, 302, 307, 404, 406} ={0, 101, 102, 104, 201, 203, 205, 206, 302, 303, 305, 307} 图11.7 蛮力法求解子集和问题示例 集合Li以数组L[i]的形式存储,n个元素的正整数集合S用数组s[n]存储且下标从1开始,两个集合的合并操作与4.3.1中介绍的归并排序的合并算法类似,蛮力法求解子集和问题的算法如下: 算法11.5——子集和问题 int SubsetSum1(int n, int s[ ], int C) { L[0]={0}; for (i=1; i=n; i++) //依次计算子集和中包含元素s[i] { L[i]=Merge(L[i-1], L[i-1]+s[i]); 删去L[i]中超过C的元素; } return max(L[n]); } 算法SubsetSum1中的数组L[i]是一个包含了不超过C的所有可能的(s1, s2,…, si)的子集和,在最坏情况下(即L[i]中的元素各不相同),L[i]中的元素个数为2i,所以,算法SubsetSum1的时间复杂性为O(2n) 基于算法SubsetSum1的近似算法的基本思想是,在迭代过程中,对数组L[i]进行适当的修整,使得在子集和不超过一定误差的前提下,尽可能减少数组L[i]中的元素个数,从而获得算法时间性能的提高。具体方法是:用一个修整参数δ(0<δ<1),从数组L[i]中删去尽可能多的元素,得到一个数组L1[i],使得每一个从L[i]中删去的元素y,在数组L1[i]中都有一个修整后的元素z满足(1-δ)×y≤z≤y,可以将z看作是被删去元素y在修整后的数组L1[i]中的代表。 例如,若δ=0.1,且L={10, 11, 12, 15, 20, 21, 22, 23, 24, 29},则用δ对L进行修整后得到L1={10, 12, 15, 20, 23, 29}。其中被删去的元素11由10来代表,21和22由20来代表,24由23来代表。 给定一个修整参数δ,对有序数组L的修整算法如下: 算法11.6——有序数组的修整 int [ ] Trim(int m, int L[ ], int L1[ ], double δ) { //数组L的长度为m,下标从1开始, //对数组L修整后存储在数组L1中 L1
文档评论(0)