怎么用遗传算法求一函数的极小值,编写matlab程序。

怎么用遗传算法求一函数的极小值,编写matlab程序。,第1张

需要很多的子函数

%子程序:新物种交叉 *** 作,函数名称存储为crossover.m

function scro=crossover(population,seln,pc)

BitLength=size(population,2)

pcc=IfCroIfMut(pc)%根据交叉概率决定是否进行交叉 *** 作,1则是,0则否

if pcc==1

chb=round(rand*(BitLength-2))+1%在[1,BitLength-1]范围内随机产生一个交叉位

scro(1,:)=[population(seln(1),1:chb) population(seln(2),chb+1:BitLength)]

scro(2,:)=[population(seln(2),1:chb) population(seln(1),chb+1:BitLength)]

else

scro(1,:)=population(seln(1),:)

scro(2,:)=population(seln(2),:)

end

%子程序:计算适应度函数,函数名称存储为fitnessfun.m

function [Fitvalue,cumsump]=fitnessfun(population)

global BitLength

global boundsbegin

global boundsend

popsize=size(population,1)%有popsize个个体

for i=1:popsize

x=transform2to10(population(i,:))%将二进制转换为十进制

%转化为[-2,2]区间的实数

xx=boundsbegin+x*(boundsend-boundsbegin)/(power(2,BitLength)-1)

Fitvalue(i)=targetfun(xx)%计算函数值,即适应度

end

%给适应度函数加上一个大小合理的数以便保证种群适应度值为正数

Fitvalue=Fitvalue'+203

%计算选择概率

fsum=sum(Fitvalue)

Pperpopulation=Fitvalue/fsum

%计算累计概率

cumsump(1)=Pperpopulation(1)

for i=2:popsize

cumsump(i)=cumsump(i-1)+Pperpopulation(i)

end

cumsump=cumsump'

%子程序:判断遗传运算是否需要进行交叉或变异,函数名称存储为IfCroIfMut.m

function pcc=IfCroIfMut(mutORcro)

test(1:100)=0

l=round(100*mutORcro)

test(1:l)=1

n=round(rand*99)+1

pcc=test(n)

%子程序:新种群变异 *** 作,函数名称存储为mutation.m

function snnew=mutation(snew,pmutation)

BitLength=size(snew,2)

snnew=snew

pmm=IfCroIfMut(pmutation)%根据变异概率决定是否进行变异 *** 作,1则是,0则否

if pmm==1

chb=round(rand*(BitLength-1))+1%在[1,BitLength]范围内随机产生一个变异位

snnew(chb)=abs(snew(chb)-1)

end

%子程序:新种群选择 *** 作,函数名称存储为selection.m

function seln=selection(population,cumsump)

%从种群中选择两个个体

for i=1:2

r=rand%产生一个随机数

prand=cumsump-r

j=1

while prand(j)<0

j=j+1

end

seln(i)=j%选中个体的序号

end

%子程序:对于优化最大值或极大值函数问题,目标函数可以作为适应度函数

%函数名称存储为targetfun.m

function y=targetfun(x)%目标函数

%子程序:将二进制数转换为十进制数,函数名称存储为transform2to10.m

function x=transform2to10(Population)

BitLength=size(Population,2)

x=Population(BitLength)

for i=1:BitLength-1

x=x+Population(BitLength-i)*power(2,i)

end

k=[0 0.1 0.2 0.3 0.5 1]

for i=1:1:5

%主程序:用遗传算法求解targetfun.m中目标函数在区间[-2,2]的最大值

clc

clear all

close all

global BitLength

global boundsbegin

global boundsend

bounds=[-2 2]%一维自变量的取值范围

precision=0.0001%运算精度

boundsbegin=bounds(:,1)

boundsend=bounds(:,2)

%计算如果满足求解精度至少需要多长的染色体

BitLength=ceil(log2((boundsend-boundsbegin)'./precision))

popsize=50%初始种群大小

Generationmax=12%最大代数

pcrossover=0.90%交配概率

pmutation=0.09%变异概率

%产生初始种群

population=round(rand(popsize,BitLength))

%计算适应度值,返回Fitvalue和累计概率cumsump

[Fitvalue,cumsump]=fitnessfun(population)

Generation=1

while Generation<Generationmax+1

for j=1:2:popsize

%选择 *** 作

seln=selection(population,cumsump)

%交叉 *** 作

scro=crossover(population,seln,pcrossover)

scnew(j,:)=scro(1,:)

scnew(j+1,:)=scro(2,:)

%变异 *** 作

smnew(j,:)=mutation(scnew(j,:),pmutation)

smnew(j+1,:)=mutation(scnew(j+1,:),pmutation)

end%产生了新种群

population=smnew

%计算新种群的适应度

[Fitvalue,cumsump]=fitnessfun(population)

%记录当前代最好的适应度和平均适应度

[fmax,nmax]=max(Fitvalue)

fmean=mean(Fitvalue)

ymax(Generation)=fmax

ymean(Generation)=fmean

%记录当前代的最佳染色体个体

x=transform2to10(population(nmax,:))

%自变量取值范围是[-2 2],需要把经过遗传运算的最佳染色体整合到[-2 2]区间

xx=boundsbegin+x*(boundsend-boundsbegin)/(power(2,BitLength)-1)

xmax(Generation)=xx

Generation=Generation+1

end

Generation=Generation-1

Bestpopuation=xx

Besttargetfunvalue=targetfun(xx)

%绘制经过遗传运算后的适应度曲线。一般地,如果进化过程中种群的平均适应度与最大适

%应度在曲线上有相互趋同的形态,表示算法收敛进行得很顺利,没有出现震荡;在这种前

%提下,最大适应度个体连续若干代都没有发生进化表明种群已经成熟

figure(1)

hand1=plot(1:Generation,ymax)

set(hand1,'linestyle','-','linewidth',1.8,'marker','*','markersize',6)

hold on

hand2=plot(1:Generation,ymean)

set(hand2,'color','r','linestyle','-','linewidth',1.8,'marker','h','markersize',6)

xlabel('进化代数')ylabel('(最大/平均适应度)')xlim([1 Generationmax])

legend('最大适应度','平均适应度')

box offhold off

y=(x(i)-k(i))^2-10*sin(2*pi*(x(i)-k(i)))+10

end

给你个例子stat.m:

function [mean,stdev] = stat(x)

n = length(x)

mean = avg(x,n)

stdev = sqrt(sum((x-avg(x,n)).^2)/n)

function mean = avg(x,n)

mean = sum(x)/n

在同一个.m文件中,定义了两个函数,其中stat(x)为主函数,avg(x,n)为子函数,主函数调用子函数

主函数必须与.m文件同名,子函数必须跟在主函数或其他子函数后

主函数在此文件外可见,子函数不可见,即主函数全局,子函数非全局

我发一些他们的源程序你,都是我在文献中搜索总结出来的:

% 下面举例说明遗传算法 %

% 求下列函数的最大值 %

% f(x)=10*sin(5x)+7*cos(4x) x∈[0,10] %

% 将 x 的值用一个10位的二值形式表示为二值问题,一个10位的二值数提供的分辨率是每为 (10-0)/(2^10-1)≈0.01 。 %

% 将变量域 [0,10] 离散化为二值域 [0,1023], x=0+10*b/1023, 其中 b 是 [0,1023] 中的一个二值数。 %

% %

%--------------------------------------------------------------------------------------------------------------%

%--------------------------------------------------------------------------------------------------------------%

% 编程

%-----------------------------------------------

% 2.1初始化(编码)

% initpop.m函数的功能是实现群体的初始化,popsize表示群体的大小,chromlength表示染色体的长度(二值数的长度),

% 长度大小取决于变量的二进制编码的长度(在本例中取10位)。

%遗传算法子程序

%Name: initpop.m

%初始化

function pop=initpop(popsize,chromlength)

pop=round(rand(popsize,chromlength))% rand随机产生每个单元为 {0,1} 行数为popsize,列数为chromlength的矩阵,

% roud对矩阵的每个单元进行圆整。这样产生的初始种群。

% 2.2.2 将二进制编码转化为十进制数(2)

% decodechrom.m函数的功能是将染色体(或二进制编码)转换为十进制,参数spoint表示待解码的二进制串的起始位置

% (对于多个变量而言,如有两个变量,采用20为表示,每个变量10为,则第一个变量从1开始,另一个变量从11开始。本例为1),

% 参数1ength表示所截取的长度(本例为10)。

%遗传算法子程序

%Name: decodechrom.m

%将二进制编码转换成十进制

function pop2=decodechrom(pop,spoint,length)

pop1=pop(:,spoint:spoint+length-1)

pop2=decodebinary(pop1)

% 2.4 选择复制

% 选择或复制 *** 作是决定哪些个体可以进入下一代。程序中采用赌轮盘选择法选择,这种方法较易实现。

% 根据方程 pi=fi/∑fi=fi/fsum ,选择步骤:

% 1) 在第 t 代,由(1)式计算 fsum 和 pi

% 2) 产生 {0,1} 的随机数 rand( .),求 s=rand( .)*fsum

% 3) 求 ∑fi≥s 中最小的 k ,则第 k 个个体被选中

% 4) 进行 N 次2)、3) *** 作,得到 N 个个体,成为第 t=t+1 代种群

%遗传算法子程序

%Name: selection.m

%选择复制

function [newpop]=selection(pop,fitvalue)

totalfit=sum(fitvalue)%求适应值之和

fitvalue=fitvalue/totalfit%单个个体被选择的概率

fitvalue=cumsum(fitvalue)%如 fitvalue=[1 2 3 4],则 cumsum(fitvalue)=[1 3 6 10]

[px,py]=size(pop)

ms=sort(rand(px,1))%从小到大排列

fitin=1

newin=1

while newin<=px

if(ms(newin))<fitvalue(fitin)

newpop(newin)=pop(fitin)

newin=newin+1

else

fitin=fitin+1

end

end

% 2.5 交叉

% 交叉(crossover),群体中的每个个体之间都以一定的概率 pc 交叉,即两个个体从各自字符串的某一位置

% (一般是随机确定)开始互相交换,这类似生物进化过程中的基因分裂与重组。例如,假设2个父代个体x1,x2为:

% x1=0100110

% x2=1010001

% 从每个个体的第3位开始交叉,交又后得到2个新的子代个体y1,y2分别为:

% y1=0100001

% y2=1010110

% 这样2个子代个体就分别具有了2个父代个体的某些特征。利用交又我们有可能由父代个体在子代组合成具有更高适合度的个体。

% 事实上交又是遗传算法区别于其它传统优化方法的主要特点之一。

%遗传算法子程序

%Name: crossover.m

%交叉

function [newpop]=crossover(pop,pc)

[px,py]=size(pop)

newpop=ones(size(pop))

for i=1:2:px-1

if(rand<pc)

cpoint=round(rand*py)

newpop(i,:)=[pop(i,1:cpoint),pop(i+1,cpoint+1:py)]

newpop(i+1,:)=[pop(i+1,1:cpoint),pop(i,cpoint+1:py)]

else

newpop(i,:)=pop(i)

newpop(i+1,:)=pop(i+1)

end

end

% 2.6 变异

% 变异(mutation),基因的突变普遍存在于生物的进化过程中。变异是指父代中的每个个体的每一位都以概率 pm 翻转,即由“1”变为“0”,

% 或由“0”变为“1”。遗传算法的变异特性可以使求解过程随机地搜索到解可能存在的整个空间,因此可以在一定程度上求得全局最优解。

%遗传算法子程序

%Name: mutation.m

%变异

function [newpop]=mutation(pop,pm)

[px,py]=size(pop)

newpop=ones(size(pop))

for i=1:px

if(rand<pm)

mpoint=round(rand*py)

if mpoint<=0

mpoint=1

end

newpop(i)=pop(i)

if any(newpop(i,mpoint))==0

newpop(i,mpoint)=1

else

newpop(i,mpoint)=0

end

else

newpop(i)=pop(i)

end

end

很多哈,也很麻烦,但是设计程序就是如此!得耐心点才行。 最近又作了些总结,要有兴趣百度HI我吧。我有M文件,运行成功


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7858916.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-10
下一篇 2023-04-10

发表评论

登录后才能评论

评论列表(0条)

保存