实验五遗传算法求解函数最值问题实验Word格式.docx

上传人:b****5 文档编号:20769915 上传时间:2023-01-25 格式:DOCX 页数:13 大小:198.98KB
下载 相关 举报
实验五遗传算法求解函数最值问题实验Word格式.docx_第1页
第1页 / 共13页
实验五遗传算法求解函数最值问题实验Word格式.docx_第2页
第2页 / 共13页
实验五遗传算法求解函数最值问题实验Word格式.docx_第3页
第3页 / 共13页
实验五遗传算法求解函数最值问题实验Word格式.docx_第4页
第4页 / 共13页
实验五遗传算法求解函数最值问题实验Word格式.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

实验五遗传算法求解函数最值问题实验Word格式.docx

《实验五遗传算法求解函数最值问题实验Word格式.docx》由会员分享,可在线阅读,更多相关《实验五遗传算法求解函数最值问题实验Word格式.docx(13页珍藏版)》请在冰豆网上搜索。

实验五遗传算法求解函数最值问题实验Word格式.docx

表1不同参数的对比实验

N

len

crossnum

maxGeneration

probCross

probMutate

实验一

实验二

1

10

4

1000

0.85

0.15

2.61433204

2.74697117

2

50

5000

2.87176512

2.88383150

3

200

20

2.89202745

2.89307359

30

10000

2.89440656

2.88852551

5

0.8

0.2

2.88806821

2.89165073

6

300

40

100000

2.89363739

2.89445359

以上我们主要对种群规模N,个体染色体长度len,迭代次数maxGeneration进行比较。

可以看出,随着种群规模的增大,染色体长度的增长,迭代次数的增加,算法得到的结果越来越精确。

当参数规模达到一定程度时,再增加参数的值会明显地增加程序运行时间,但却不一定能明显改善解的质量,反而可能因为一些随机因数而产生质量更差的解,如第6组实验一所示。

同时也大概比较了一下多点交叉的交叉点个数crossnum,交叉概率probCross,变异概率probMutate等参数,由于参数太多,这里没有一一进行控制变量的比较。

大致估算可知,交叉概率及交叉点的个数影响交叉操作产生新个体的质量,过多的交叉及变化过大的交叉可能会产生不好的结果,而过多的变异也应该会造成算法的不稳定。

下面给出以上几个实验结果的实验截图,其中到现在为止结果最好的一个为:

其余若干个为:

5.实验代码

改进后的源代码如下:

#include<

iostream>

iomanip>

algorithm>

cmath>

ctime>

usingnamespacestd;

//程序欲分配内存的数组大小

constintmxn=10000;

//最大的种群规模

constintmxlen=1000;

//最大的染色体长度

//遗传算法关键参数

constintN=200;

//种群的个体数

constintlen=30;

//每个个体的染色体的长度,x和y各占一半

constintcrossnum=4;

//交叉操作时多点交叉的交叉点个数

constintmaxGeneration=2000;

//最大进化代数

constdoubleprobCross=0.85;

//交叉概率

constdoubleprobMutation=0.15;

//变异概率

//个体的染色体类

classChromosome

{

public:

boolg[mxlen];

//二进制编码的编码数组

Chromosome()//默认构造函数,构造随机染色体

{

for(inti=0;

i<

len;

i++)g[i]=rand()%2;

}

Chromosome(constChromosome&

c)//拷贝构造函数,进行深复制

i++)g[i]=c.g[i];

voidoperator=(constChromosome&

c)//重载=号,进行深复制

};

doublebestval;

//记录当前所得的最优值

ChromosomebestC;

//记录当前最优值对应的个体染色体

Chromosomegroup[mxn],temGroup[mxn];

//个体的种群,辅助数组

//目标函数

doublef(doublex,doubley)

returnx*sin(6*y)+y*cos(8*x);

}

//解码函数,从染色体得到x和y的值

voiddecode(constChromosome&

c,double&

x,double&

y)

doublenum=pow(2.0,len/2.0);

inttem=0;

for(inti=len-1,q=1;

i>

=len/2;

i--)

tem+=c.g[i]*q,q=q*2;

y=1+(2-1)/num*tem;

tem=0;

for(inti=len/2-1,q=1;

=0;

x=1+(2-1)/num*tem;

//适应度函数,为避免负值,把目标函数加一个正数

doublefitness(constChromosome&

c)

doublex,y;

decode(c,x,y);

returnf(x,y)+5;

//辅助函数,生成0-1之间的随机小数

doubleinlinerandom01()

returnrand()%10000/10000.0;

//选择操作

voidselect(Chromosomegroup[mxn])

//计算每个个体的选择概率

doublefitnessVal[mxn];

for(inti=0;

N;

i++)fitnessVal[i]=fitness(group[i]);

doublesum=0;

i++)sum+=fitnessVal[i];

doubleprob[mxn];

i++)prob[i]=fitnessVal[i]/sum;

//随机选择N个个体组成新种群

intselectId[mxn];

for(inti=1;

i++)prob[i]+=prob[i-1];

i++)

//使用轮盘赌算法选择个体

doublerandNum=random01();

intj;

for(j=0;

j<

N-1;

j++)

{

if(randNum<

prob[j])

{

selectId[i]=j;

break;

}

}

if(j==N-1)

selectId[i]=j;

//把种群更新为新选择的个体集合

i++)temGroup[i]=group[i];

i++)group[i]=temGroup[selectId[i]];

//交叉操作,使用多点交叉

voidcrossover(Chromosome&

c1,Chromosome&

c2)

//生成交叉点位置,并排序

intcrosspoint[mxn];

for(inti=0;

crossnum;

i++)crosspoint[i]=rand()%len;

sort(crosspoint,crosspoint+crossnum);

//进行交叉

boolflag=0;

for(inti=0,j=0;

if(!

flag)

swap(c1.g[i],c2.g[i]);

if(i==crosspoint[j])

//如果若干个交叉点重合,则效果叠加

//偶数个交叉点效果相当于没有交叉点

while(j<

crossnum&

&

i==crosspoint[j])

j++;

flag=!

flag;

//变异操作

voidmutate(Chromosome&

//随机选择一位进行翻转

inti=rand()%len;

c.g[i]=!

c.g[i];

//获取种群最优个体

intgetOptimal(Chromosomegroup[mxn],double&

x,double&

y,double&

val)

//计算适应值,遍历得到最优值并进行解码

intid=0;

i++)

if(fitnessVal[i]>

fitnessVal[id])

id=i;

decode(group[id],x,y);

val=f(x,y);

returnid;

//遗传算法总代码

voidGA(double&

//初始化种群

group[i]=Chromosome();

//

bestC=group[getOptimal(group,x,y,bestval)];

//控制进化代数

for(intg=0;

g<

maxGeneration;

g++)

//选择操作

select(group);

//根据交叉概率进行交叉

for(inti=0,pre=-1;

if(random01()<

probCross)

if(pre==-1)

pre=i;

else

{

crossover(group[pre],group[i]);

pre=-1;

}

//根据变异概率进行变异

probMutation)

mutate(group[i]);

//防止种群退化

doubletemval;

intbestId=getOptimal(group,x,y,temval);

if(temval<

bestval)

//如果新种群的最优值变差,把较优的个体替换进新种群

group[bestId]=bestC;

else

//如果新种群的最优值变好,则更新最优值记录

bestC=group[bestId];

bestval=temval;

//获取最优值

getOptimal(group,x,y,val);

intmain()

srand(time(0));

doublex,y,maxval;

GA(x,y,maxval);

cout<

<

"

函数在点("

<

fixed<

setprecision(15)<

x<

"

y<

)取得最大值:

"

maxval<

endl;

system("

pause"

);

三、实验体会

以上实验得到的最好结果仍然是差强人意,这里对算法做一个小的优化,即添加防止种群退化的操作。

记录当前位置所得到的最优值及对应的个体,每次更新种群之后,计算新种群的最优值,如果最优值变差了,则把之前较优的个体替换进新种群,防止种群退化;

否则更新最优值。

改进之后的效果如下所示,显然比之前更优,且实验结果显示对于前面对比实验中的参数值,这里只需要较小的参数(如迭代次数只需2000次)值即可稳定收敛到此最大值,可知改进非常有效。

增加输出精度之后为,于是得到最优的结果为2.894471354862841

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

当前位置:首页 > 成人教育 > 成考

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

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