使用遗传算法求解函数最大值Word文档下载推荐.docx

上传人:b****3 文档编号:18277376 上传时间:2022-12-15 格式:DOCX 页数:16 大小:77.90KB
下载 相关 举报
使用遗传算法求解函数最大值Word文档下载推荐.docx_第1页
第1页 / 共16页
使用遗传算法求解函数最大值Word文档下载推荐.docx_第2页
第2页 / 共16页
使用遗传算法求解函数最大值Word文档下载推荐.docx_第3页
第3页 / 共16页
使用遗传算法求解函数最大值Word文档下载推荐.docx_第4页
第4页 / 共16页
使用遗传算法求解函数最大值Word文档下载推荐.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

使用遗传算法求解函数最大值Word文档下载推荐.docx

《使用遗传算法求解函数最大值Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《使用遗传算法求解函数最大值Word文档下载推荐.docx(16页珍藏版)》请在冰豆网上搜索。

使用遗传算法求解函数最大值Word文档下载推荐.docx

ivM;

i++)double士Lim二0;

■for(irrti=0;

N;

i++)doubleprob[nixn];

fop(inti=0;

i€M;

i++)H随机选攝住细5^种群

intseLectld[msnJ;

■for(inti=1;

i”)pryjb[i]2prob[i-l];

for(irrti=0;

i++)

H便用笙盘赌算法询环t

doublerandNum=randomOlO;

intj;

^ar(j=9;

j<

N-1^j屮{

if(randNum<

prob[j])

{selectld[i]三j;

break^

if(j=・m-1)selectTd[l]=j;

}

//把种詩更新为新选擇的个建集含

for(int£

=9;

i++)for(int1=9ji<

i-H-J

>

Group[l]=「oup[i];

group[i]=temGroup[selectl<

l[i]]j

但实验时发现结果不好,经过仔细研究之后发现,这里在x、y取某些值的时候,目标

函数计算出来的适应值可能会出现负值,这时如果按照把每个个体的适应值除以适应值的总

总和也可能出现负值,如果归一对实验结果造成影响。

对于这保证得到的适应值为正数,然

和的进行归一化的话会出现问题,因为个体可能出现负值,

化的时候除以了一个负值,选择时就会选择一些不良的个体,个问题,我把适应度函数定为目标函数的函数值加一个正数,

后再进行一般的归一化和选择的操作。

实验结果表明,之前的实验结果很不稳定,修正后的结果比较稳定,趋于最大值。

//适应度函数■为童免负值.把目标函勒Lt■正散Fdoublefitne55(const匚nroiriosotrc&

c)

doublex,y;

decode(c,y);

returnf(x,y)+5;

交叉操作

首先是根据交叉概率probCross选择要交叉的个体进行交叉。

H限据交叉槪車进行交叉

■for(inti.=%pre=-1;

i-l-+)

if(randomSlf)<

probCross)

if(pre==-1)pre=i;

else{crossover(group[prc]group[i]);

pre=-1;

}

这里根据交叉参数crossnum进行多点交叉,首先随机生成交叉点位置,允许交叉点重合,两个重合的交叉点效果互相抵消,相当于没有交叉点,然后根据交叉点进行交叉操作,得到新的个体。

"

交叉擾ft.使用券点交叉

^voidcrossovertChrcmoio『亡gcljChromoscmeAc2)

//生威交叉点位置.井排宮

intcrosspointfinxn];

for^inti-Q;

crassnuffi;

i++)crosspoint[i]■rand()%len:

scrt(亡rosspflint^er-05i|M£

nt+trassnjffl):

boolflag=9;

for^inti■0jj-i<

leriji-n-J

IffIflag)

if(i--cro55point[j])

□H如果若干个交叉点重合.則效果叠町

.//偶数个交叉点效果於于没有交叉点

while^j<

crcssnumi==cro55point[j])(

j++;

flag=Iflag;

三变异操作

首先是根据变异概率probMutation选择要变异的个体。

n根据变异概率遊行变异

for(inti=1<

1++)

iftrandom01()<

probMutation)mutate(group[i]);

Evoidnutatuffc)

I

n随机选择THS齐翻转

inti=rand()驚len^

Fc.g[i]-!

c.g[i]-

经过一定的进化之后得到最终种群,从中选择最优的个体即可得到最终的结果。

I//获取WftStt朋

-intgetOptimal(ch-ctics[tnxn]jdoublu&

k.double>

tdoublu&

^1)

H计亘适应值.遍帀得刹最优值井逬齐解冯

doublefitn€55Val[mKTi]j

for(inti=0;

i++)fitnessVal[i]=fitne5S(group[i])jintid=曲;

fortinti-1;

1<

Nji+f)

if(fltne£

sval[i]>

fitnes£

Val[Ld])

id=i;

decode^_roup[id],x,

■jal=f(xty);

returniti:

运行结果

借助matlab软件,我们可以知道该函数在该定义域下的图像为

6B数Xxx*sinp*y)-ty*cos(p^)的團像

以下设置不同的参数值进行对比试验:

表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等参数,由于参数太多,这里没有一一进行控制变量的比较。

大致估算可知,

交叉概率及交叉点的个数影响交叉操作产生新个体的质量,过多的交叉及变化过大的交叉可

能会产生不好的结果,而过多的变异也应该会造成算法的不稳定。

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

(3lflC:

Window?

\syiterr,32\cnn

岡数在点"

上盹酣1龙£

1柑刃砒阳7》取得最大值洱-曲44阳阴(Pv-ess:

anytocontInue....

其余若干个为:

59C:

\Windovw5Vy5terri32\ciTtd.exe

|團数在点"

書四19盟1.-豊-:

32910阿“取得最才-直:

2-89202745?

ftnyk耳yto(?

ont久nuu■・・.

[ZBC:

Wi

超数在点"

・S8193970.i.32785034>

®

得最HPressanykeytocontinuE・・・.

大值

EBCAWindowAsysterm32\cmd.exe

函数在点"

翦942£

叮也:

L-J2g399GG〉取得最大值-仙酊2551

PressanykeytocontiniAe---—

算法改进

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

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

否则

更新最优值。

防止硯g化

doubletenval;

intbestld=getOptimalCgroupj』temval);

if(temval<

beetval)

如柔新种群的最优值变差・把较优的个体詡奂进新种群group[bestId]■best匚;

^lse

如果新种群的最优値变好”則更新最优值记录best€-group[bestld])bestval=temvalj

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

知改进非常有效。

[SBC:

\Wind□ws\sy$tem3Acmd.exe

国数在点①罔252541-32&

£

07即〉取得最大直2.*94471酊Pressanytocontinue....

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

固C:

\Wind£

w$\yy:

5tEm?

2\£

[mileM

画数在点"

.S82&

19531250Q00,1,32&

507568359375>

©

^^X值;

养胡£

47135朝E2841Pressan^keytocontinue・・・.

源代码

改进后的源代码如下:

#include

<

iostream>

iomanip>

algorithm>

cmath>

ctime>

 

usingnamespacestd;

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

constintmxn=10000;

//最大的种群规模

constintmxlen=1000;

//最大的染色体长度

//遗传算法关键参数

//种群的个体数

const

intN=200;

intlen=30;

//

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

int

crossnum

=4;

//

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

constdoubleprobCross=0.85;

//交叉概率

constdoubleprobMutation=0.15;

//变异概率

//个体的染色体类

classChromosome

{]

public:

boolg[mxlen];

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

Chromosome()

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

for(inti=(

);

i<

len;

g[i]=rand()%2;

Chromosome(const

Chromosome&

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

for(inti=0

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

voidoperator=(

constChromosome&

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

};

double

bestval;

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

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&

decode(c,x,y);

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

doubleinlinerandom01()

{

returnrand()%10000/10000.0;

}//选择操作

voidselect(Chromosomegroup[mxn])

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

doublefitnessVal[mxn];

for(inti=0;

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

doublesum=0;

sum+=fitnessVal[i];

doubleprob[mxn];

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

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

intselectId[mxn];

for(inti=1;

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

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

randNum=random01();

intj;

for

(j=

0;

N-1;

j++)

if

(randNum<

selectId[i]=j;

break

if(j==N-1)

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

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

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

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

voidcrossoverChromosome&

c1,Chromosome&

c2)

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

intcrosspoint[mxn];

crossnum;

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

sort(crosspoint,crosspoint+crossnum);

//进行交叉

boolflag=0;

for(int

i=0,j=

len;

i++)

(!

flag)

swap(cl.g[i],

c2.g[i]);

(i==crosspoint[j])

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

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

while(j<

crossnum&

&

i==crosspoint[j])

//变异操作

voidmutate(Chromosome&

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

inti=rand()%len;

c.g[i]=!

c.g[i];

//获取种群最优个体

intgetOptimal(Chromosomegroup[mxn],double&

y,double&

val){」

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

intid=0;

(fitnessVal[i]>

fitnessVal[id])

decode(

group[id],x,y);

val=f(

x,y);

return

id;

//遗传算法总代码

voidGA(double&

val)

初始化种群

(inti=0

;

group[i]=

Chromosome();

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

//控制进化代数

for(intg=0;

g<

maxGeneration;

//选择操作

select(group);

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

for(inti=0,pre=-1;

if(random01()<

if(pre==-1)

pre=i;

else

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

pre=-1;

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

probMutation)

mutate(group[i]);

//防止种群退化

doubletemval;

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

bestval)

//如果新种群的最优值变好,则更新最优值记录bestC=group[bestld];

bestval=temval;

//获取最优值

getOptimal(group,x,y,val);

}intmain()

srand(time(0));

doublex,y,maxval;

GA(x,y,maxval);

y<

"

cout<

函数在点("

fixed<

setprecision(15)<

x<

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

当前位置:首页 > 医药卫生 > 预防医学

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

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