当前位置:文档之家› 遗传算法解决01背包问题

遗传算法解决01背包问题

遗传算法解决01背包问题2015 ~2016 学年第二学期学生姓名专业学号2016年 6 月目录一:问题描述 (3)二:遗传算法原理及特点 (3)三:背包问题的遗传算法求解 (3)1.文字描述 (3)2.遗传算法中的抽象概念在背包问题的具体化 (3)3.算法求解的基本步骤 (4)四:算法实现 (4)1.数据结构 (4)2.部分代码 (5)五:结论 (8)六:参考文献 (8)一、问题描述0-1背包问题属于组合优化问题的一个例子,求解0-1背包问题的过程可以被视作在很多可行解当中求解一个最优解。

01背包问题的一般描述如下:给定n个物品和一个背包,物品i的重量为Wi,其价值为Vi,背包的容量为C。

问应如何选择合适的物品装入背包,使得背包中装入的物品的总价值最大。

注意的一点是,背包内的物品的重量之和不能大于背包的容量C。

在选择装入背包的物品时,对每种物品i只有两种选择:即装入背包或者不装入背包,不能讲物品i装入背包多次,也不能只装入部分的物品,称此类问题为0/1背包问题。

二、遗传算法原理及特点遗传算法(Genetic Algorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。

遗传算法有着鲜明的优点:(1)遗传算法的操作对象是一组可行解,而非单个可行解;搜索轨道有多条,而非单条,因而具有良好的并行性.(2)遗传算法只需利用目标的取值信息,而无需递度等高价值信息,因而适用于任何规模,高度非线形的不连续多峰函数的优化以及无解析表达式的目标函数的优化,具有很强的通用性.(3)遗传算法择优机制是一种“软”选择,加上良好的并行性,使它具有良好的全局优化性和稳健性.(4)遗传算法操作的可行解集是经过编码化的(通常采用二进制编码),目标函数解释为编码化个体(可行解)的适应值,因而具有良好的可操作性与简单性.三、背包问题的遗传算法求解1、文字描述0-1背包问题传统的解决方法有动态规划法、分支界限法、回溯法等等。

传统的方法不能有效地解决0-1背包问题。

在物品不是很多的时候用这些算法来处理背包问题效率上还是可以接受的,一旦物品过多(如50件物品)这些算法的效率就大打折扣了,因此采用一些智能的启发式搜索算法来处理就显得很有必要,遗传算法(Genetic Algorithms)则是一种适合于在大量的可行解中搜索最优(或次优)解的有效算法。

2、遗传算法中的抽象概念在背包问题的具体化(1)基因:0或1,代表相应的商品选还是不选。

(2)染色体:本实验中固定有50个商品,所以染色体就是50个基因序列,也就是40个0、1串,代表了一种往包里装商品的组合。

一个染色体例:0111101101011011110101110101010101011110。

(3)群体:一定数量的基因个体组成了群体(population),群体中个体的数量叫做群体大小。

本实验的背包问题中,种群大小为100,代表100个往包里装商品的组合。

(4)适应度:各个个体对环境的适应程度叫做适应度。

本实验的背包问题中,每染色体个体的适应度为选入包中的商品的价值和。

3、算法求解的基本步骤(1)种群的初始化:确定种群大小M、交叉概率pc、变异概率pm、染色体长度N及最大进化代数T.随机初始化染色体,给出物品体积、物品价值和背包容量C.以8个待分配的物件为例:随机产生n个长度为8的二进制串,即种群中个体的染色体编码的每一位按等概率在0与1中选择.n指的是种群规模,即种群中的个体数目。

(2)产生遗传编码:采用二进制n维矢量解X作为解空间参数的遗传编码,串的长度等于n,xi=1表示该物件装入背包,xi=0表示该物件没有被装入背包确定染色编码方式,它根据不同的问题模型使用不同编码方式,有二进制编码也有整数编码和浮点数编码,对于01背包问题,采用二进制编码。

因为物品只有选中与不选中两种状态,例如7个物品,用七个01组成的编码来表示,这是染色体长度就是7,x={0,1,0,1,0,0,1)表示第2、4、7这三个物品被选入背包中。

而其他的没有被选中。

也就是说,现在这个背包里只有2、4、7这三个物件。

这个遗传编码也需要随机地产生,随机地产生数字0或l,就构成一个染色体串,也就是一个遗传编码。

每产生一个染色体,就对它进行一次检验,如果不满足约束条件,则拒绝接受。

重新产生一个新的染色体;如果产生的染色体满足条件,则接受它作为种群的一名成员,经过有限次抽样后,得到M个可行的染色体。

(3)适应度函数的构造:根据题意可构造出适应度函数如下:其中Xi=1或0(i=1,2,…,n).(4)选择操作:根据选择概率选择染色体,将上述的个体作为第1代,这里采用以正比于适应度的赌轮随机选择方式。

评价函数,01背包问题的评价函数很简单,就是选中的物品的价值之和,如:11100的评价值就是前三个选中物品的价值之和,当然还有前三个物品体积不能超过背包容量这个约束条件,一旦超出容量那么它的评价值就是0了。

交叉操作:采用一点交叉方式,交叉概率为pc,具体操作是在个体串中随机设定一个交叉点.6)变异操作:染色体变异采用位点变异的方式.对种群依次进行选择、交叉、变异后就检验得到的新个体,当某代得到的结果满足要求或当前代数等于结束代数时算法结束得到结果,否则重复选择、交叉、变异操作,直到得到满意的结果为止.四、算法实现1、数据结构(1)重要参数:#define zhongqun_size 100//种群的规模#define pc 0.8 //杂交概率#define pm 0.08 //变异概率#define chrom_length 50//染色体长度#define max_daishu 1000//最大进化代数(2)染色个体:struct population{unsigned int chrom[chrom_length];//染色体double weight;//背包重量double fitness;//适应度unsigned int parent1,parent2,cross;//双亲、交叉点};(3)种群://新生代种群、父代种群struct population oldpop[zhongqun_size],newpop[zhongqun_size];2、部分代码#define zhongqun_size 100//种群的规模#define pc 0.8//杂交概率#define pm 0.08//变异概率#define chrom_length 50//染色体长度#define max_daishu 1000//最大进化代数struct population{unsigned int chrom[chrom_length];//染色体double weight;//背包重量double fitness;//适应度unsigned int parent1,parent2,cross;//双亲、交叉点};//新生代种群、父代种群struct population oldpop[zhongqun_size],newpop[zhongqun_size]; //背包问题中物体重量、收益、背包容量int weight[chrom_length],profit[chrom_length],bagweight;//种群的总适应度、最小、最大、平均适应度double sumfitness,minfitness,maxfitness,avgfitness;//计算适应度时使用的惩罚函数系数double alpha;//一个种群中最大和最小适应度的个体int minpop,maxpop;void read_infor(){FILE*fp;int j;//获取背包问题信息文件if((fp=fopen("data.txt","r"))==NULL){//读取文件失败//AfxMessageBox("The file is not found",MB_OK,NULL);return;}//读入物体收益信息for(j=0;j<chrom_length;j++){fscanf(fp,"%d",&profit[j]);}//读入物体重量信息for(j=0;j<chrom_length;j++){fscanf(fp,"%d",&weight[j]);}//读入背包容量fscanf(fp,"%d",&bagweight);fclose(fp);}//根据计算的个体重量,判断此个体是否该留在群体中double cal_weight(unsigned int*chr){int j;double pop_weight;//背包重量pop_weight=0;for(j=0;j<chrom_length;j++){pop_weight=pop_weight+(*chr)*weight[j];chr++;}return pop_weight;}double cal_fit(unsigned int*chr){int j;double pop_profit;//适应度pop_profit=0;//pop_weight=0;for(j=0;j<chrom_length;j++){pop_profit=pop_profit+(*chr)*profit[j];//pop_weight=pop_weight+(*chr)*weight[j];chr++;}return pop_profit;}void generation(){unsigned int i,j,mate1,mate2;double tmpWeight;int ispop;//记录是否是符合条件的个体i=0;while(i<zhongqun_size){ispop=false;while(!ispop){//选择mate1=selection(i);mate2=selection(i+1);//交叉crossover(oldpop[mate1].chrom,oldpop[mate2].chrom,i);//变异for(j=0;j<chrom_length;j++){newpop[i].chrom[j]=mutation(newpop[i].chrom[j]);}//选择重量小于背包容量的个体,即满足条件tmpWeight=cal_weight(newpop[i].chrom);if(tmpWeight<=bagweight){newpop[i].fitness=cal_fit(newpop[i].chrom);newpop[i].weight=tmpWeight;newpop[i].parent1=mate1;newpop[i].parent2=mate2;ispop=true;}}//此个体可以加入到种群中i=i+1;}}void main(int argc,char*argv[]){int gen,oldmaxpop,k;double oldmax;read_infor();//读入背包信息gen=0;srand((unsigned)time(NULL));//置随机种子initpop();memcpy(&newpop,&oldpop,zhongqun_size*sizeof(struct population)); statistics(newpop);//统计新生种群的信息report(newpop,gen);while(gen<max_daishu){gen=gen+1;if(gen0==0){srand((unsigned)time(NULL));//置随机种子}oldmax=maxfitness;oldmaxpop=maxpop;generation();statistics(newpop);//统计新生代种群信息//如果新生代种群中个体的最大适应度小于老一代种群//个体的最大适应度,则保存老一代种群个体的最大适应度//否则报告新生代的最大适应度if(maxfitness<oldmax){for(k=0;k<chrom_length;k++)newpop[minpop].chrom[k]=oldpop[oldmaxpop].chrom[k];newpop[minpop].fitness=oldpop[oldmaxpop].fitness;newpop[minpop].parent1=oldpop[oldmaxpop].parent1;newpop[minpop].parent2=oldpop[oldmaxpop].parent2;newpop[minpop].cross=oldpop[oldmaxpop].cross;statistics(newpop);}else if(maxfitness>oldmax){report(newpop,gen);}//保存新生代种群的信息到老一代种群信息空间memcpy(&oldpop,&newpop,zhongqun_size*sizeof(struct population));}printf("It is over.");getch();}五、结论遗传算法在处理背包问题时借助了大自然的演化过程,采用的是种群和随机搜索机制,它是一种多线索而非单线索的全局优化方法,能克服传统优化方法的缺点,从而达到好的优化效果。

相关主题