当前位置:
文档之家› 用遗传算法解决0-1背包问题
用遗传算法解决0-1背包问题
实现遗传算法的0-1背包问题 求解及其改进
姓名: 学号: 班级: 提交日期:2012年6月27日
实现遗传算法的0-1背包问题求解
摘要:研究了遗传算法解决0-1背包问题中的几个问题:
对于过程中不满足重量限制条件的个体的处理,通过代换 上代最优解保持种群的进化性 2) 对于交换率和变异率的理解和处理方法,采用逐个体和逐位 判断的处理方法 3) 对于早熟性问题,引入相似度衡量值并通过重新生成个体替 换最差个体方式保持种群多样性。 4) 一种最优解只向更好进化方法的尝试。 通过实际计算比较表明,本文改进遗传算法在背包问题求解中具有 很好的收敛性、稳定性和计算效率。通过实例计算,表明本文改进 遗传算法优于简单遗传算法和普通改进的遗传算法。 关键词:遗传算法;背包问题 ;优化 1)
1: 打开数据文件 2: 设置程序运行主界面 3: 调用初始化种群模块 3- 1: 按照一定的种群规模和染色体长度以基因为单位用随 机产生的0- 1对个体赋值 3- 2: 调用计算适应度函数 4: 以最大进化代数为循环终止条件开始进行循环 4- 1: 调用产生新一代个体的函数 4- 1- 1: 调用选择函数 4- 1- 2: 调用交叉函数 4- 1- 3: 调用变异函数 4- 1- 4: 调用计算适应度函数 5: 调用计算新一代种群统计数据函数 6: 调用输出新一代统计数据函数 7: 返回到第四步, 直至循环结束 二、 基本遗传算法解决0- 1背包问题存在的不足: 1.对于过程中不满足重量限制条件的个体的处理 在用基本遗传算法解决0- 1背包问题的时候,在初始化或者 交叉变异后可能会产生不满足重量约束条件的伪解,而对于这 些伪解,基本遗传算法没有给出一个很好的处理方法,而只是 又随机生成了一个满足约束条件的解作为新的个体从而替换掉 原来的个体。根据遗传算法的根本思想“优胜劣汰,适者生 存”的原则,可以将不满足条件的个体用已有的最优个体来进 行替换,这样,既使得种群中所有的个体均满足重量的约束条 件,又保留了较优解,符合遗传算法的思想。 具体做法为: 在程序中加入一个变量保存每代的最优解,当前代在进行 选择、复制、交叉、变异后如果有不满足约束条件的个体,则 在种群更新时采用这个最优值作为替代。 具体做法为:在每代遗传后通过函数 FindBestandWorstIndividual()找到当前最优值并保存
2. 对于算法早熟性的分析及解决方法 遗传算法中种群中的个体由初始化时的具有多样性,可能 会由于在进化过程中一些超常个体限制其它个体的进化——这 个个体的适应度大大优于种群内的其它值,由于适者生存原则 这个个体被不断复制从而充满了整个种群,使得种群的多样应 大大降低,进化停滞,从而出现算法收敛于局部最优解的现 象,称为早熟现象。 早熟现象的可能解法: 1) 通过提高变异率来增加种群的多样性,以期更优解的出 现,这也是最简单基本遗传算法中不添加相关操作的情 况下唯一的一种方法,然而这种方法有明显的弊端:在 提高变异率获得多样性种群的同时,个体变异的机会增 加,使得较优解发生变异,从而遗传算法丧失了其优于 其它算法的优越性,所以这种方法不是很好地解决方 法。 2) 引入多样性衡量和处理 基本思路:在出现进化停滞现象时要引入新的个体来增强种 群的多样性。 做法:1,判断是否达到早熟现象 对于种群中S个个体,判断等位基因的相等程度,即 引入一个参数值same,如果same达到一定的 理论值大 小就可以认为达到了早熟现象。 2,早熟现象的处理,即引入新的个体。 处理过程中应该不违反适者生存的原则,所以应该保 留较好的个体,所以首先选中适应度最小的 个体执行 删除操作,然后随机生成一个新的符合重量限制且打破早熟 现象的新个体。 具体实现见函数:void checkalike(void)
需要进行0-1互换变异2-3如果q 说明 不需要变
分析这两种处理方法可知:方法一没有很好地体现随机机会均 等的思想,因为在步骤1中确定的需要操作的数目n后,总体上 是保证了交叉或者变异的数目,但不是对于每一个个体而言 的,因而会出现有的个体被选择交叉或者变异多次而有的没有 机会交叉或者变异的情况,而如果采用方法二,就体现了机会 的均等性,即要求对每一个单元操作目标进行概率的验证,以 确定是否变异或者交叉。在程序中具体的实现方法体现在交叉 和变异函数中:
//相似度校验 for( i=0;i<S;i++) for(j=0;j<N;j++) bool temp=X[i].chromsome[j]; for(int k=1;k<S;k++) if(temp!=X[k].chromsome[j]) break; if(j==N)same++; if(same>N*0.5)//大于50%作为判定为早熟
);
Step 4 判断:若终止条件满足,则取S中适应度最大的染色体 作为所求结果,算法结束。 Step 5 选择-复制:按选择概率P(xi)所决定的选中机会,每次从 S中随机选定1个染色体并将其复制,共做N次,然后将复制所 得的N个染色体组成群体S1; Step 6 交叉:按交叉率Pc所决定的参加交叉的染色体数c,从S1 中随机确定c个染色体,配对进行交叉操作,并用产生的新染 色体代替原染色体,得群体S2; Step 7 变异:按变异率Pm所决定的变异次数m,从S2中随机确 定m个染色体,分别进行变异操作,并用产生的新染色体代替
1. 基本实现原理: 一、问题描述 0-1背包问题属于组合优化问题的一个例子,求解0-1背包问 题的过程可以被视作在很多可行解当中求解一个最优解。01背 包问题的一般描述如下: 给定n个物品和一个背包,物品i的重量为Wi,其价值为Vi,背 包的容量为C。选择合适的物品装入背包,使得背包中装入的 物品的总价值最大。注意的一点是,背包内的物品的重量之和 不能大于背包的容量C。在选择装入背包的物品时,对每种物 品i只有两种选择:装入背包或者不装入背包,即只能将物品i 装入背包一次。称此类问题为0/1背包问题。 其数学模型为:
原染色体,得群体S3; Step 8 更新:将群体S3作为新一代种群,即用S3代替S,t=t+1, 转步3; 遗传算法是一种仿生算法, 即模拟生命演化的算法,它从一 个代表问题初始解的初始种群出发, 不断重复执行选择, 杂交和 变异的过程, 使种群进化越来越接近某一目标既最优解,如果 视种群为超空间的一组点, 选择、杂交和变异的过程即是在超 空间中进行点集之间的某种变换, 通过信息交换使种群不断变 化, 遗传算法通过模拟达尔文“优胜劣汰, 适者生存”的原理激 励好的结构, 同时寻找更好的结构, 作为一种随机的优化与搜索 方法, 遗传算法有着其鲜明的特点。 —遗传算法一般是直接在解空间搜索, 而不像图搜索那样 一般是在问题空间搜索, 最后才找到解(如果搜索成功的话)。 —遗传算法的搜索随机地始于搜索空间的一个点集, 而不 像图搜索那样固定地始于搜索空间的初始节点或终止节点, 所 以遗传算法是一种随机搜索算法。 —遗传算法总是在寻找优解(最优解或次优解), 而不像图搜 索那样并非总是要求优解, 而一般是设法尽快找到解(当然包括 优解), 所以遗传算法又是一种优化搜索算法。 —遗传算法的搜索过程是从空间的一个点集(种群)到另一 个点集(种群)的搜索,而不像图搜索那样一般是从空间的一个点 到另一个点地搜索。 因而它实际是一种并行搜索, 适合大规模 并行计算, 而且这种种群到种群的搜索有能力跳出局部最优 解。 —遗传算法的适应性强, 除需知适应度函数外, 几乎不需要 其他的先验知识。 —遗传算法长于全局搜索, 它不受搜索空间的限制性假设 的约束,不要求连续性, 能以很大的概率从离散的、多极值的、 含有噪声的高维问题中找到全局最优解。 3.程序步骤: 一、 使用基本遗传算法解决0- 1背包问题:
其二,采用对每个操作单元分别进行特定概率下处理的方法, 步骤如下:
对于交叉操作: 1,在种群中进行S次循环,其中S代表种群中个体的数量 2,对于每一个个体X[i](X为种群数组)做如下操作 2-1生成随机数p [0,1],判断p与 的大小关系 2-2如果p 说明X[i]需要交换 2-2-1 随机在种群中找到异于X[i]的另一个体进行交换 2-3如果p 说明X[i]不需要交换 对于变异操作: 1,在种群中进行S次循环,其中S代表种群中个体的数量 2,对每一个个体X[i]做N次循环,其中N为染色体位数 2-1对染色体的每一位 3-1生成随机数q [0,1],判断q与 的大小关系 3-2如果q 说明
0-1背包问题传统的解决方法有动态规划法、分支界限法、回 溯法等等。传统的方法不能有效地解决0-1背包问题。遗传算 法(Genetic Algorithms)则是一种适合于在大量的可行解中搜 索最优(或次优)解的有效算法。 二、遗传算法特点介绍: 遗传算法(Genetic Algorithm, GA)是1962年Holland教授首次提 出了GA算法的思想是近年来随着信息数据量激增,发展起来 的一种崭新的全局优化算法,它借用了生物遗传学的观点,通 过自然选择、遗传、变异等作用机制,实现各个个体的适应性 的提高。 基本遗传算法求解步骤: Step 1 参数设置:在论域空间U上定义一个适应度函数f(x),给 定种群规模N,交叉率Pc和变异率Pm,代数T; Step 2 初始种群:随机产生U中的N个染色体s1, s2, …, sN,组成 初始种群S={s1, s2, …, sN},置代数计数器t=1; Step 3 计算适应度:S中每个染色体的适应度f(
对于交叉操作: 1,根据交叉率确定应该交叉的个体数目n 2,在种群中进行n次循环 2-1随机选中种群中的一个个体a 2-2随机选中种群中异于a的一个个体b 2-3随机确定交叉位数 2-4进行交叉 对于变异操作: 1,根据变异率确定应该变异的染色体数目n 2,在种群中进行n次循环 2-1随机选中种群中的一个个体的染色体a 2-2随机选中染色体a的某位基因 2-3对 进行0-1互换变异
void CrossoverOperator(void)//交叉操作 for(i=0; i<S; i++) do{p=rand()%S;//两个[0,S]的随机数 q=rand()%S; }while(p==q); int w=1+rand()%N;//[1,N]交换的位数 double p=(rand()%1001)/1000.0; if(p<=Pc) for(j=0;j<w;j++)交换w位数据 void MutationOperator(void)//变异操作 for (i=0; i<S; i++) for (j=0; j<N; j++) q=(rand()%1001)/1000.0;//产生q [0,1] if (q<Pm) //对每一位都要考虑 if(X[i].chromsome[j]==1)X[i].chromsome[j]=0; else X[i].chromsome[j]=1;