matlab手写遗传算法解决一元函数最值问题(实例)
問題:找出y=x4-4x3+3x+5 (x?[0,6])在[0,6]之間的最小值。
思路:用33位0,1變量來(lái)編碼x,3位編碼整數(shù),30位編碼小數(shù)。理論上30位編碼小數(shù)可以將最小值對(duì)應(yīng)的x精確到小數(shù)點(diǎn)后九位.
下面是我解決這個(gè)問題所有的函數(shù),復(fù)制就可以運(yùn)行了。
交換值的函數(shù):
function [x,y]=exchange(x,y)temp=x;x=y;y=temp; end執(zhí)行交叉:
%交叉操作 function [A,B]=cross(A,B)L=length(A);if L<10W=L;elseif((L/10)-floor(L/10))>=rand&&L>10W=ceil(L/10)+8;elseW=floor(L/10)+8;endp=unidrnd(L-W+1);for i=1:W[A(1,p+i-1),B(1,p+i-1)]=exchange(A(1,p+i-1),B(1,p+i-1));end end變異過程,通過調(diào)節(jié)函數(shù)的第二個(gè)參數(shù)來(lái)改變每個(gè)個(gè)體的變異率,這樣從一定程度上能對(duì)不同問題達(dá)到更好的效果
function a=Mutation(A,fitness)nnper=randperm(size(A,2));if (A(1,nnper(1)))==1A(1,nnper(1))=0;elseif(A(1,nnper(1))==0)&(rand>fitness)A(1,nnper(1))=1;enda=A; end解碼操作,就是將二進(jìn)制字符串轉(zhuǎn)化成十進(jìn)制數(shù):
function dePop=decode(pop)[lengthx,lengthy]=size(pop);dePop=zeros(lengthx,1);for i=1:lengthxfor j=1:lengthydePop(i)=dePop(i)+pop(i,j)*2^(3-j);endend end適應(yīng)度函數(shù),就是將每個(gè)x對(duì)應(yīng)的函數(shù)值計(jì)算出來(lái),再乘以-1,這樣函數(shù)值越大,適應(yīng)度反而越小,函數(shù)值越小,適應(yīng)度越大
function fitness=fit(dePop)dePop=dePop.^4-4*dePop.^3+3*dePop+5;fitness=-dePop; end主函數(shù)調(diào)用上面函數(shù),可以通過C修改迭代次數(shù),pop修改種群大小和密碼子長(zhǎng)度。我的迭代是5000次,相當(dāng)于從10萬(wàn)個(gè)個(gè)體中挑選出最優(yōu)的一個(gè)。
clear; clc; M = 20;%種群個(gè)數(shù) C = 5000; %迭代次數(shù) m = 2; %適應(yīng)值歸一淘汰加速指數(shù) Pmutation = 0.2; %變異概率 Pc = 0.4;%交叉概率 pop=rand(20,33); %種群%%%%初始化種群及其適應(yīng)函數(shù)%%%%fitness=decode(pop); fitness=fit(fitness); maxfitness=max(fitness); rr=find(fitness==maxfitness); R=pop(rr(1,1),:); fprintf('當(dāng)前種群最優(yōu)個(gè)體:%.12f\n',-fitness(rr));while C>=0fprintf('迭代第%d次\n',C);%%%%選擇操作%%%%[px,py]=size(pop);ms=sort(rand(px));fitin=1;nn=1;while nn<=pxif (ms(nn))<fitness(fitin)pop_sel(nn,:)=pop(fitin,:);nn=nn+1;fitin=fitin+1;if fitin>pxfitin=floor(rand*(px-1))+1;endelsefitin=fitin+1;if fitin>pxfitin=floor(rand*(px-1))+1;endendend%%%%保留最優(yōu)個(gè)體%%%%maxfitness=max(fitness);rr=find(fitness==maxfitness);pop_sel(1,:)=pop(rr(1),:);%%%%交叉操作%%%%nnper=randperm(M);A=pop_sel(nnper(1),:);B=pop_sel(nnper(2),:);for i=1:M*Pc[A,B]=cross(A,B);pop_sel(nnper(1),:)=A;pop_sel(nnper(2),:)=B;end%%%%變異操作%%%%for i=1:Mpick=rand;while pick==0pick=rand;endif pick<=Pmutationpop_sel(i,:)=Mutation(pop_sel(i,:),0.5);endend%%%%求適應(yīng)度函數(shù)%%%%pop=pop_sel;fitness=decode(pop);fitness=fit(fitness);maxfitness=max(fitness);rr=find(fitness==maxfitness);R=-fitness(rr(1));fprintf('當(dāng)前最小值=%.14f ',-fitness(rr(1)));C=C-1; end答案如下:
當(dāng)前最小值=-13.13000339865731 迭代第22次
當(dāng)前最小值=-13.13000339865731 迭代第21次
當(dāng)前最小值=-13.13000339865731 迭代第20次
當(dāng)前最小值=-13.13000339865731 迭代第19次
當(dāng)前最小值=-13.13000339865731 迭代第18次
當(dāng)前最小值=-13.13000339865731 迭代第17次
當(dāng)前最小值=-13.13000339865731 迭代第16次
當(dāng)前最小值=-13.13000339865731 迭代第15次
當(dāng)前最小值=-13.13000339865731 迭代第14次
當(dāng)前最小值=-13.13000339865731 迭代第13次
當(dāng)前最小值=-13.13000339865731 迭代第12次
當(dāng)前最小值=-13.13000339865731 迭代第11次
當(dāng)前最小值=-13.13000339865731 迭代第10次
當(dāng)前最小值=-13.13000339865731 迭代第9次
當(dāng)前最小值=-13.13000339865731 迭代第8次
當(dāng)前最小值=-13.13000339865731 迭代第7次
當(dāng)前最小值=-13.13000339865731 迭代第6次
當(dāng)前最小值=-13.13000339865731 迭代第5次
當(dāng)前最小值=-13.13000339865731 迭代第4次
當(dāng)前最小值=-13.13000339865731 迭代第3次
當(dāng)前最小值=-13.13000339865731 迭代第2次
當(dāng)前最小值=-13.13000339865731 迭代第1次
當(dāng)前最小值=-13.13000339865731 迭代第0次
?
?
我用其它方法驗(yàn)證過,結(jié)果最后精確到了小數(shù)點(diǎn)的后10位。
總結(jié)
以上是生活随笔為你收集整理的matlab手写遗传算法解决一元函数最值问题(实例)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 湫湫系列故事——消灭兔子
- 下一篇: C#winform实现鼠标响应左键按下,