问题01背包问题课程设计说明书.docx
《问题01背包问题课程设计说明书.docx》由会员分享,可在线阅读,更多相关《问题01背包问题课程设计说明书.docx(16页珍藏版)》请在冰豆网上搜索。
![问题01背包问题课程设计说明书.docx](https://file1.bdocx.com/fileroot1/2022-10/28/0f17d59e-0dc7-457d-8097-de075215d101/0f17d59e-0dc7-457d-8097-de075215d1011.gif)
问题01背包问题课程设计说明书
【关键字】问题
摘要
0-1背包问题在实际中有广泛的应用,本课程设计采用遗传算法中Prim算法解决0-1背包问题,遗传算法主要特点是直接对结构对象进行操作,不存在求导和函数连续性的限定;具有内在的隐并行性和更好的全局寻优能力;采用概率化的寻优方法,能自动获取和指导优化的搜索空间,自适应地调整搜索方向,不需要确定的规则。
遗传算法不是对所有问题都能得到整体最优解,但对范围相当广的许多问题它能产生整体最优解。
通过分析用遗传算法解决0-1背包问题能得到问题的最优解。
根据算法的设计结果,采用C语言实现算法,通过测试分析,程序运行结果正确,运行效率较高。
关键词:
0-1背包问题,遗传算法,Prim算法
1问题描述
(1)0-1背包问题:
给定n中物品和一个背包。
物品i的重量是Wi,其价值为Vi,背包的容量为C。
问:
应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?
在选择装入的背包的物品时,对每种物品i只有两种选择,即装入背包或不装入背包。
不能将物品i装入背包多次,也不能只装入部分物品i。
因此,该问题成为0-1背包问题。
(2)遗传算法:
遗传算法(GeneticAlgorithm)是模拟达尔文生物退化论的自然选择和遗传学机理的生物退化过程的计算模型,是一种通过模拟自然退化过程搜索最优解的方法,它最初由美国Michigan大学J.Holland教授于1975年首先提出来的,并出版了颇有影响的专著《AdaptationinNaturalandArtificialSystems》,GA这个名称才逐渐为人所知,J.Holland教授所提出的GA通常为简单遗传算法(SGA)。
遗传算法(GeneticAlgorithm)是一类借鉴生物界的退化规律(适者生存,优胜劣汰遗传机制)演化而来的随机化搜索方法。
其主要特点是直接对结构对象进行操作,不存在求导和函数连续性的限定;具有内在的隐并行性和更好的全局寻优能力;采用概率化的寻优方法,能自动获取和指导优化的搜索空间,自适应地调整搜索方向,不需要确定的规则。
遗传算法的这些性质,已被人们广泛地应用于组合优化、机器学习、信号处理、自适应控制和人工生命等领域。
它是现代有关智能计算中的关键技术。
遗传算法是从代表问题可能潜在的解集的一个种群(population)开始的,而一个种群则由经过基因(gene)编码的一定数目的个体(individual)组成。
每个个体实际上是染色体(chromosome)带有特征的实体。
染色体作为遗传物质的主要载体,即多个基因的集合,其内部表现(即基因型)是某种基因组合,它决定了个体的形状的外部表现,如黑头发的特征是由染色体中控制这一特征的某种基因组合决定的。
因此,在一开始需要实现从表现型到基因型的映射即编码工作。
由于仿照基因编码的工作很复杂,我们往往进行简化,如二进制编码,初代种群产生之后,按照适者生存和优胜劣汰的原理,逐代(generation)演化产生出越来越好的近似解,在每一代,根据问题域中个体的适应度(fitness)大小选择(selection)个体,并借助于自然遗传学的遗传算子(geneticoperators)进行组合交叉(crossover)和变异(mutation),产生出代表新的解集的种群。
这个过程将导致种群像自然退化一样的后生代种群比前代更加适应于环境,末代种群中的最优个体经过解码(decoding),可以作为问题近似最优解。
2问题分析
对于背包问题遗传算法的基本运算过程如下:
a)初始化:
设置退化代数计数器t=0,设置最大退化代数T,随机生成M个个体作为初始群体P(0)。
b)个体评价:
计算群体P(t)中各个个体的适应度。
c)选择运算:
将选择算子作用于群体。
选择的目的是把优化的个体直接遗传到下一代或通过配对交叉产生新的个体再遗传到下一代。
选择操作是建立在群体中个体的适应度评估基础上的。
d)交叉运算;将交叉算子作用于群体。
所谓交叉是指把两个父代个体的部分结构加以替换重组而生成新个体的操作。
遗传算法中起核心作用的就是交叉算子。
e)变异运算:
将变异算子作用于群体。
即是对群体中的个体串的某些基因座上的基因值作变动。
群体P(t)经过选择、交叉、变异运算之后得到下一代群体P(t1)。
f)终止条件判断:
若tT,则以退化过程中所得到的具有最大适应度个体作为最优解输出,终止计算。
3算法设计
据设计要求,该算法的基本运行流程为:
第1步:
随机产生一组初始个体构成的初始群体;
第2步:
计算群体中每一个个体的适配值(fitnessvalue);
第3步:
应用复制、交叉、变异算子产生下一代群体;
第4步:
把在任何一代中出现的最好的个体串指定为遗传算法的执行结果。
4算法实现
//遗传算法求解0-1背包问题
#include
#include
#include
#include
#include
usingnamespacestd;
//定义问题的最大规模
#definemax100
//为题规模,即共有多少个包
intpackageNum;
//每个包的重量
intpackageWeight[max];
//每个包的价值
intpackageValue[max];
//约束,背包的最大容量
intlimitWeight;
//群体的规模
intcolonySize;
/*colonyState[i][k]表示一个染色体*/
/*colonyState[1...conlonySize][0|1]表示一个群体*/
intcolonyState[max][2][max];
/*currAge表示当前代的编号*/
/*(currAge+1)%2表示下一代的编号*/
intcurrAge=0;
/*个体评价*/
typedefstructtagIndivdualMsg
{intindex;
intvalue;
}IndivdualMsg;
IndivdualMsgindivdualMsg[max];
/*函数声明*/
voidprintColonyState(intnextAge);
/*初始化群体,初始种群产生,并计算每个适应度值和其对应的约束条件值(即为在染色体中选取的物品的重量)
比较初始种群中各个个体的适应度。
选择最大者所对应的个体作为第一代最优个体,并记录该个体以及它的适应度和约束条件值。
*/
voidcolonyInit()
{inti,j;
intw;
for(i=0;i{//保证找到一个符合约束的染色体
w=limitWeight+1;
while(w>limitWeight)
{w=0;
for(j=0;j{
colonyState[i][currAge][j]=rand()%2;
w+=packageWeight[j]*colonyState[i][currAge][j];}
}
}
}
/*对个体进行评价*/
intcmp(constvoid*a,constvoid*b)
{
IndivdualMsg*x=(IndivdualMsg*)a;
IndivdualMsg*y=(IndivdualMsg*)b;
returny->value-x->value;
}
voidindivdualEstimate()
{inti,j;
for(i=0;i{
indivdualMsg[i].index=i;
indivdualMsg[i].value=0;
for(j=0;jindivdualMsg[i].value+=packageValue[j]*colonyState[i][currAge][j];}
qsort(indivdualMsg,colonySize,sizeof(IndivdualMsg),cmp);
}
/*终止循环的条件,给定一个最大进化步数*/
boolstopFlag()
{//进行n代进行后停止
staticintn=50;
if(n--<=0)
returnfalse;
else
returntrue;
}
/*赌轮选择*/
intgambleChoose()
{
intwheel[max]={0};
inti=colonySize-1;
intchoose;
wheel[i]=indivdualMsg[i].value;
for(i--;i>=0;i--)
wheel[i]=(indivdualMsg[i].value+wheel[i+1])+colonySize*(colonySize-i);
intseed=abs(wheel[0]-(rand()%(2*wheel[0]+1)));
choose=colonySize-1;
while(seed>wheel[choose])
choose--;
returnchoose;
}
/*交叉,进行交叉运算,随即选择一对个体产生一对有效交叉位置进行交叉运算,并计算新产生的个体的适应度值和约束条
件值。
如果新产生的个体重量大于背包容量,则对新产生的个体进行修正,放弃在一个个体中的一个物品,增加另一个个体的
一个物品使其重量小于背包重量。
*/
voidacross(intmale,intfemale,intindex)
{
intnextAge=(currAge+1)%2;
inti,j,t;
intacrossBit=rand()%(packageNum-1)+1;
for(j=0;j{
colonyState[index][nextAge][j]=colonyState[indivdualMsg[male].index][currAge][j];
colonyState[index+1][nextAge][j]=colonyState[indivdualMsg[female].index][currAge][j];
}
for(i=0;i{
t=colonyState[index][nextAge][i];
colonyState[index][nextAge][i]=colonyState[index+1][nextAge][i];
colonyState[index+1][nextAge][j]=t;
}
}
/*变异:
进行变异操作,如果一个个体的一个基因为1,则变为0;如果是0则变为1,重新计算该个体的适应度值和约束条件值*/
voidaberrance(intindex)
{intseed,nextAge;
nextAge=(currAge+1)%2;
//只有1/3的概率发生异变
seed=rand()%(packageNum*3);
if(seedcolonyState[in