智能控制作业遗传算法求解背包问题.docx

上传人:b****5 文档编号:8128822 上传时间:2023-01-29 格式:DOCX 页数:17 大小:60.89KB
下载 相关 举报
智能控制作业遗传算法求解背包问题.docx_第1页
第1页 / 共17页
智能控制作业遗传算法求解背包问题.docx_第2页
第2页 / 共17页
智能控制作业遗传算法求解背包问题.docx_第3页
第3页 / 共17页
智能控制作业遗传算法求解背包问题.docx_第4页
第4页 / 共17页
智能控制作业遗传算法求解背包问题.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

智能控制作业遗传算法求解背包问题.docx

《智能控制作业遗传算法求解背包问题.docx》由会员分享,可在线阅读,更多相关《智能控制作业遗传算法求解背包问题.docx(17页珍藏版)》请在冰豆网上搜索。

智能控制作业遗传算法求解背包问题.docx

智能控制作业遗传算法求解背包问题

智能控制

遗传算法求解背包问题

——16组

遗传算法求解背包问题

摘要:

遗传算法是在分析遗传个体进化机制基础上提出的一种新型优化算法。

本论文根据0-1背包问题的特点,提出用于求该问题的遗传算法及相关的解决方案,阐明算法的具体实现过程。

通过对其他文献中仿真实例的计算和结果比较,表明应用该算法求解背包问题取得了良好的效果。

该算法同样可以应用于其他组合优化题。

关键词:

背包问题;遗传算法

一.概述

背包问题(knapsackproblem)是运筹学中一个典型的优化难题,有着广泛的实际应用背景,如管理中的资源分配、投资决策、预算控制等问题,并且经常作为其他问题的子问题被研究。

研究背包问题的求解算法在理论上和实践中都具有一定的意义。

从计算复杂性理论来看,背包问题是个NP完全问题,该问题的求解方法主要有启发式算法,如贪心算法、遗传算法、粒子群算法。

以遗传算法为代表的生物进化算法建立在达尔文自然选择学说的基础上,是对生物进化过程的模拟,是人们对从自然演化过程中抽象出的概念、原则和机制的类比应用,被广泛用于解决复杂的计算问题。

其主要特点是直接对结构对象进行操作,不存在求导和函数连续性的限定;具有内在的隐并行性和更好的全局寻优能力;采用概率化的寻优方法,能自动获取和指导优化的搜索空间,自适应地调整搜索方向,不需要确定的规则。

遗传算法的这些性质,已被人们广泛地应用于组合优化、机器学习、信号处理、自适应控制和人工生命等领域。

它是现代有关智能计算中的关键技术。

本文在分析遗传算法的基础上,提出了将贪婪修复方法与遗传算法相结合,构成混和遗传算法,并应用于求解经典背包问题。

它是可以解决复杂问题的新方法。

本论文系统的介绍背包问题的遗传算法解决方案。

二.背包问题的数学模型

背包问题的定义:

我们有n种物品,物品j的重量为wj,价格为pj。

我们假定所有物品的重量和价格都是非负的。

背包所能承受的最大重量为W。

如果限定每种物品只能选择0个或1个,则问题称为0-1背包问题。

可以用公式表示为:

方法1:

每个背包只能使用一次或有限次(可转化为一次):

A.求最多可放入的重量。

有一个箱子容量为v(正整数,o≤v≤20000),同时有n个物品(o≤n≤30),每个物品有一个体积(正整数)。

要求从n个物品中,任取若千个装入箱内,使箱子的剩余空间为最小。

l.搜索方法

proceduresearch(k,v:

integer);{搜索第k个物品,剩余空间为v}

vari,j:

integer;

begin

ifv

=v;

ifv-(s[n]-s[k-1])>=bestthenexit;{s[n]为前n个物品的重量和}

ifk<=nthenbegin

ifv>w[k]thensearch(k+1,v-w[k]);

search(k+1,v);

end;

end;

2.DP:

F[I,j]为前i个物品中选择若干个放入使其体积正好为j的标志,为布尔型。

实现:

将最优化问题转化为判定性问题

f[I,j]=f[i-1,j-w[i]](w[I]<=j<=v)边界:

f[0,0]:

=true.

ForI:

=1tondo

Forj:

=w[I]tovdoF[I,j]:

=f[I-1,j-w[I]];

优化:

当前状态只与前一阶段状态有关,可降至一维。

F[0]:

=true;

ForI:

=1tondobegin

F1:

=f;

Forj:

=w[I]tovdo

Iff[j-w[I]]thenf1[j]:

=true;

F:

=f1;

End;

B.求可以放入的最大价值。

F[I,j]为容量为I时取前j个背包所能获得的最大价值。

F[i,j]=max{f[i–w[j],j-1]+p[j],f[i,j-1]}

C.求恰好装满的情况数。

DP:

Procedureupdate;

varj,k:

integer;

begin

c:

=a;

forj:

=0tondo

ifa[j]>0then

ifj+now<=ntheninc(c[j+now],a[j]);

a:

=c;

end;

方法2:

可重复背包

A求最多可放入的重量。

F[I,j]为前i个物品中选择若干个放入使其体积正好为j的标志,为布尔型。

状态转移方程为

f[I,j]=f[I-1,j–w[I]*k](k=1..jdivw[I])

B.求可以放入的最大价值。

进行一次竞赛,总时间T固定,有若干种可选择的题目,每种题目可选入的数量不限,每种题目有一个ti(解答此题所需的时间)和一个si(解答此题所得的分数),现要选择若干题目,使解这些题的总时间在T以内的前提下,所得的总分最大,求最大的得分。

*易想到:

f[i,j]=max{f[i-k*w[j],j-1]+k*p[j]}(0<=k<=idivw[j])

其中f[i,j]表示容量为i时取前j种背包所能达到的最大值。

*实现:

Begin

FillChar(f,SizeOf(f),0);

Fori:

=1ToMDo

Forj:

=1ToNDo

Ifi-problem[j].time>=0Then

Begin

t:

=problem[j].point+f[i-problem[j].time];

Ift>f[i]Thenf[i]:

=t;

End;

Writeln(f[M]);

End.

C.求恰好装满的情况数。

求自然数n本质不同的质数和的表达式的数目。

思路一:

生成每个质数的系数的排列,在一一测试,这是通法。

proceduretry(dep:

integer);

vari,j:

integer;

begin

cal;{此过程计算当前系数的计算结果,now为结果}

ifnow>nthenexit;{剪枝}

ifdep=l+1thenbegin{生成所有系数}

cal;

ifnow=ntheninc(tot);

exit;

end;

fori:

=0tondivpr[dep]dobegin

xs[dep]:

=i;

try(dep+1);

xs[dep]:

=0;

end;

end;

思路二:

递归搜索效率较高

proceduretry(dep,rest:

integer);

vari,j,x:

integer;

begin

if(rest<=0)or(dep=l+1)thenbegin

ifrest=0theninc(tot);

exit;

end;

fori:

=0torestdivpr[dep]do

try(dep+1,rest-pr[dep]*i);

end;

{main:

try(1,n);}

思路三:

可使用动态规划求解

设V个物品,背包容量为n,求放法总数。

转移方程:

Procedureupdate;

varj,k:

integer;

begin

c:

=a;

forj:

=0tondo

ifa[j]>0then

fork:

=1tondivnowdo

ifj+now*k<=ntheninc(c[j+now*k],a[j]);

a:

=c;

end;

{main}

begin

read(now);{读入第一个物品的重量}

i:

=0;{a[i]为背包容量为i时的放法总数}

whilei<=ndobegin

a[i]:

=1;inc(i,now);end;{定义第一个物品重的整数倍的重量a值为1,作为初值}

fori:

=2tovdo

begin

read(now);

update;{动态更新}

end;

writeln(a[n]);

三.算法综述

遗传算法是从代表问题可能潜在的解集的一个种群开始的,而一个种群则由经过基因编码的一定数目的个体组成。

每个个体实际上是染色体带有特征的实体。

染色体作为遗传物质的主要载体,即多个基因的集合,其内部表现(即基因型)是某种基因组合,它决定了个体的形状的外部表现,如黑头发的特征是由染色体中控制这一特征的某种基因组合决定的。

因此,在一开始需要实现从表现型到基因型的映射即编码工作。

由于仿照基因编码的工作很复杂,我们往往进行简化,如二进制编码,初代种群产生之后,按照适者生存和优胜劣汰的原理,逐代演化产生出越来越好的近似解,在每一代,根据问题域中个体的适应度大小选择个体,并借助于自然遗传学的遗传算子进行组合交叉和变异,产生出代表新的解集的种群。

这个过程将导致种群像自然进化一样的后生代种群比前代更加适应于环境,末代种群中的最优个体经过解码,可以作为问题近似最优解。

贪婪算法是从眼前最大的利益出发,寻找最优解的方法,虽然很多情况下不能找到最优解,但是找到较好的解的可能性还是比较大的。

这似乎一种符合人的直觉的算法,时间复杂度比较低。

四.遗传算法求解背包问题

1.贪婪算法求解背包问题

贪婪算法属于一步式启发算法,即每采用一个贪婪准则便做出一个不可撤回的决策。

用贪婪算法求解背包问题的特点是每一步迭代选一物品入包,直到无法再装。

该算法没有在两个可行解之间比较选择,算法结束时得到一个可行解。

常用的贪婪准则是价值密度(价值重量比C/W)贪婪算法,这种选择准则为:

从剩余物品中选择可装入包的C/W值最大的物品,这也是通常所使用的贪婪策略,因为它是一个直觉上的近似的解。

2.基于贪婪算法的混合遗传算法求解背包问题

将贪婪算法与遗传算法相结合构成的混合遗传算法,通过遗传算法的择优,不断重复执行选择、杂交和变异以及贪婪算法的修正这样一个过程,所求解将不断进化越来越接近最优解。

(1)基因编码

基因编码将n个Xi的值顺序排列,就可构成背包问题的遗传编码。

即我们使用的是等长度的二进制编码方法,编码串中1表示将对应的物品放入背包中,0表示不将其放入。

例如“11100111000000000000……00000011”就代表一个解,它表示将第1,2,3,6,7,8,…n-1,n号物品放入背包中,其他的物品则不放入。

(2)编码修复

上述基因编码的方案虽然比较直观,但对于任意一个编码串,或者由交叉,变异所产生的任意一个个体,由于它们不一定满足约束条件,就不一定表示可行解,也就是说这种编码方案会产生很多无效染色体。

对于这些不满足约束条件的基因编码串,我们可以利用贪婪算法的思想进行修复。

修复的基本思想为:

在Xj=1的所有物品中,将价值重量比(C/W)最小的物品取出,直到满足背包的容量约束为止。

由此可产生一些新的基因编码串,并且这些新编码串总是相对来说质量比较好的,特别是它们肯定满足问题的约束条件。

(3)适应度函数

由于对每个个体使用贪婪算法修正已保证了不会产生无效染色体,所以在进行个体适应度评价时无须引入罚函数项,而是直接用目标函数值作为适应度函数

值,即:

(4)选择:

采用轮盘赌的方式进行选择。

在本算法中,将各基因的适应值事先作处理:

fi(i)=fit(i)-min(fit)+1;

以防止适廊度函数值出现小于零的情况,并且可以在一定程度上防止适应值差别过大时丢失低适应值基因的有用信息。

(5)交叉:

采用单点交叉方式,随机选取一点作为基因的交叉点,交叉概率pc=0.5。

(6)变异:

采用一个较小的值如pm=0.01。

算法步骤:

3.不使用贪婪算法的遗传算法求解背包问题。

为了通过对比显示出使用贪婪算法的遗传算法的优势,使用纯粹的遗传算法解决背包问题。

适应度函数与使用贪婪算法不同,需要加入惩罚项。

fit=v*value'-cf*v*value'./(v*c').*((v*c'-m1)>0).*(v*c'-m1);

cf表示惩罚力度

其他过程与加入贪婪算法的基本一致。

五.背包问题的遗传算法应用程序(matlab)

1.将贪婪算法、遗传算法结合解决背包问题:

源代码:

%遗传算法解决背包问题GA.m

clc;

clear;closeall;

%初始化物品价值value和质量c

c=[989295707270838065255055404850322260303240383532252830225030453060502065202530105650302015108531];

value=[3003182981921801802652421601381551301251221201181151101051011001009896959088828077757372706966656360582025151020107522];

g=value./c;%价值重量比,用于贪婪算法

m1=1000;%总重量约束值

v=2*rand(50,50)-1;

v=hardlim(v);%v为50*50随机产生的矩阵值为0或1

%贪婪算法修复解

%v=greedy(v,c,g,m1);

[N,L]=size(v);ger=500;pc=0.5;pm=0.01;

disp(sprintf('代数:

%d',ger));

disp(sprintf('种群大小:

%d',N));

disp(sprintf('交叉概率:

%.3f',pc));

disp(sprintf('变异概率:

%.3f',pm));

%初始化与参数设定

sol1=1;it=1;updatef=-10;%soll为当前算出的总价值,it为代数

fit=v*value';

t0=clock;%记录初始时间

figure

(1);

holdon;

whileit<=ger

%选择(轮盘赌方法)

fori=1:

N

fi(i)=fit(i)-min(fit)+1;

end

fori=1:

N

sp(i)=fi(i)/sum(fi);

endfori=2:

N

sp(i)=sp(i-1)+sp(i);

end

fori=1:

N

p=rand

(1);sindex=1;

whilep>sp(sindex)

sindex=sindex+1;%寻找要选择个体的位置

end

newv(i,:

)=v(sindex,:

);

end

fori=1:

N

v(i,:

)=newv(i,:

);%用选择出的个体构成的种群替代旧的种群

end

%交叉

fori=1:

N

cindex(i)=i;

end

fori=1:

N%产生要配对的父代的序号;经过N次顺序调换,将原有顺序打乱,使相邻两个个体作为交叉的父代

point=unidrnd(N-i+1);

temp=cindex(i);

cindex(i)=cindex(i+point-1);

cindex(i+point-1)=temp;

end

fori=1:

2:

N

p=rand

(1);

if(p

point=unidrnd(L-1)+1;%1

forj=point:

(L-1)%交叉

ch=v(cindex(i),j);

v(cindex(i),j)=v(cindex(i+1),j);%cindex中相邻的两个为两个父代的序号

v(cindex(i+1),j)=ch;

end

end

end

%变异

M=rand(N,L)<=pm;%产生(N,L)维的01矩阵,为1的位置进行变异

v=v-2.*(v.*M)+M;

%计算适应度与进化

v=greedy(v,c,g,m1);

fit=v*value';

[sol1,indb1]=max(fit);%indb1为适应度最大的染色体

ifupdatef>=sol1

sol1=updatef;

v(indb1,:

)=updatec;

end

updatef=sol1;

updatec=v(indb1,:

);

[sol2,indb2]=min(fit);%indb2为适应度最小的染色体

v(indb2,:

)=v(indb1,:

);

fit=v*value';

media=mean(fit);

it=it+1;

plot(it,sol1,'r');

end;

T=etime(clock,t0);

fx=sol1;P=v;

disp(sprintf('程序运行时间%2.4f',T));

disp(sprintf('最优解:

[%.2f]',fx));

%******************************************

修正函数:

functionv=greedy(v,c,g,m1)

[mn]=size(v);

fori=1:

m

label=g;

label=label.*v(i,:

);

ifsum(v(i,:

).*c)>m1

%修复

whilesum(v(i,:

).*c)>m1

min=10000;

forj=1:

n

iflabel(j)~=0&&label(j)

min=label(j);

modify=j;

end

end

v(i,modify)=0;

label(modify)=0;

end

end

end

weight=v*c';

2.纯粹的遗传算法解决背包问题:

源代码:

%遗传算法解决背包问题GA.m

clc;

clear;closeall;

%初始化物品价值value和质量c

c=[989295707270838065255055404850322260303240383532252830225030453060502065202530105650302015108531];

value=[3003182981921801802652421601381551301251221201181151101051011001009896959088828077757372706966656360582025151020107522];

g=value./c;%价值重量比,用于贪婪算法

m1=1000;%总重量约束值

cf=2;%惩罚系数

v=2*rand(50,50)-1;

v=hardlim(v);%v为50*50随机产生的矩阵值为0或1

%贪婪算法修复解

%v=greedy(v,c,g,m1);

[N,L]=size(v);ger=1000;pc=0.5;pm=0.01;

disp(sprintf('代数:

%d',ger));

disp(sprintf('种群大小:

%d',N));

disp(sprintf('交叉概率:

%.3f',pc));

disp(sprintf('变异概率:

%.3f',pm));

%初始化与参数设定

sol1=1;it=1;updatef=-10;%soll为当前算出的总价值,it为代数

fit=v*value'-cf*v*value'./(v*c').*((v*c'-m1)>0).*(v*c'-m1);

t0=clock;%记录初始时间

figure

(1);

holdon;

whileit<=ger

%选择(轮盘赌方法)

fori=1:

N

fi(i)=fit(i)-min(fit)+1;

end

fori=1:

N

sp(i)=fi(i)/sum(fi);

end

fori=2:

N

sp(i)=sp(i-1)+sp(i);

end

fori=1:

N

p=rand

(1);sindex=1;

whilep>sp(sindex)

sindex=sindex+1;%寻找要选择个体的位置

end

newv(i,:

)=v(sindex,:

);

end

fori=1:

N

v(i,:

)=newv(i,:

);%用选择出的个体构成的种群替代旧的种群

end

%交叉

fori=1:

N

cindex(i)=i;

end

fori=1:

N%产生要配对的父代的序号;经过N次顺序调换,将原有顺序打乱,使相邻两个个体作为交叉的父代

point=unidrnd(N-i+1);

temp=cindex(i);

cindex(i)=cindex(i+point-1);

cindex(i+point-1)=temp;

end

fori=1:

2:

N

p=rand

(1);

if(p

point=unidrnd(L-1)+1;%1

forj=point:

(L-1)%交叉

ch=v(cindex(i),j);

v(cindex(i),j)=v(cindex(i+1),j);%cindex中相邻的两个为两个父代的序号

v(cindex(i+1),j)=ch;

end

end

end

%变异

M=rand(N,L)<=pm;%产生(N,L)维的01矩阵,为1的位置进行变异

v=v-2.*(v.*M)+M;

%计算适应度与进化

%v=greedy(v,c,g,m1);

fit=v*value'-cf*v*value'./(v*c').*((v*c'-m1)>0).*(v*c'-m1);

[sol1,indb1]=max(fit);%indb1为适应度最大的染色体

ifupdatef>=sol1

sol1=updatef;

v(indb1,:

)=updatec;

end

updatef=sol1;

updatec=v(indb1,:

);

[sol2,indb2]=min(fit);%indb2为适应度最小的染色体

v(indb2,:

)=v(indb1,:

);

fit=v*value'-cf*v*value'./(v*c').*((v*c'-m1)>0).*(v*c'-m1);

media=mean(fit);

it=it+1;

fit2=v*value'-v*value'.*((v*c'-m1)>0);

[so

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工作范文 > 行政公文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1