matlab手書き遺伝アルゴリズムによる一元関数の最値問題の解決(例)

3830 ワード

質問:y=x 4-4 x 3+3 x+5(x通[0,6])の[0,6]間の最小値を見つけます.
構想:33ビット0,1変数でx,3ビット符号化整数,30ビット符号化小数.理論上30ビット符号化小数は、最小値に対応するxを小数点後9ビットまで正確にすることができる.
次は私がこの問題を解決するすべての関数で、コピーは実行できます.
スワップ値の関数:
function [x,y]=exchange(x,y)
   temp=x;
   x=y;
   y=temp;
end

交差の実行:
% 
function [A,B]=cross(A,B)
  L=length(A);
  if L<10
      W=L;
  elseif((L/10)-floor(L/10))>=rand&&L>10
      W=ceil(L/10)+8;
  else
      W=floor(L/10)+8;
  end
  p=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

変異過程は,関数の2番目のパラメータを調節することによって個体ごとの変異率を変化させ,異なる問題に対してある程度より良い効果を達成できる.
function a=Mutation(A,fitness)
  nnper=randperm(size(A,2));
  if (A(1,nnper(1)))==1
      A(1,nnper(1))=0;
  elseif(A(1,nnper(1))==0)&(rand>fitness)
      A(1,nnper(1))=1;
  end
  a=A;
end

復号化とは、バイナリ文字列を10進数に変換することです.
function dePop=decode(pop)
   [lengthx,lengthy]=size(pop);
   dePop=zeros(lengthx,1);
   for i=1:lengthx
       for j=1:lengthy
           dePop(i)=dePop(i)+pop(i,j)*2^(3-j);
       end
   end
end

適応度関数とは、xごとに対応する関数値を計算し、-1を乗じることで、関数値が大きいほど適応度が小さくなり、関数値が小さいほど適応度が大きくなる
function fitness=fit(dePop)
   dePop=dePop.^4-4*dePop.^3+3*dePop+5;
   fitness=-dePop;
end

主関数は上の関数を呼び出し,Cで反復回数を変更し,popでクラスタサイズと暗号子長を変更できる.私の反復は5000回で、10万個の個体の中から最も優れたものを選ぶことに相当します.
clear;
clc;
M = 20;% 
C = 5000; % 
m = 2; % 
Pmutation = 0.2; % 
Pc = 0.4;% 
pop=rand(20,33);  % 

%%%% %%%%

fitness=decode(pop);
fitness=fit(fitness);
maxfitness=max(fitness);
rr=find(fitness==maxfitness);
R=pop(rr(1,1),:);
fprintf(' :%.12f
',-fitness(rr)); while C>=0 fprintf(' %d
',C); %%%% %%%% [px,py]=size(pop); ms=sort(rand(px)); fitin=1; nn=1; while nn<=px if (ms(nn))px fitin=floor(rand*(px-1))+1; end else fitin=fitin+1; if fitin>px fitin=floor(rand*(px-1))+1; end end end %%%% %%%% 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:M pick=rand; while pick==0 pick=rand; end if pick<=Pmutation pop_sel(i,:)=Mutation(pop_sel(i,:),0.5); end end %%%% %%%% pop=pop_sel; fitness=decode(pop); fitness=fit(fitness); maxfitness=max(fitness); rr=find(fitness==maxfitness); R=-fitness(rr(1)); fprintf(' =%.14f ',-fitness(rr(1))); C=C-1; end

答えは次のとおりです.
現在の最小値=13.13000339865731反復22回目
現在の最小値=13.13000339865731反復21回目
現在の最小値=13.13000339865731反復20回目
現在の最小値=13.13000339865731反復19回目
現在の最小値=13.13000339865731反復18回目
現在の最小値=13.13000339865731反復17回目
現在の最小値=13.13000339865731反復16回目
現在の最小値=13.13000339865731反復15回目
現在の最小値=13.13000339865731反復14回目
現在の最小値=13.13000339865731反復13回目
現在の最小値=13.13000339865731反復12回目
現在の最小値=13.13000339865731反復11回目
現在の最小値=13.13000339865731反復10回目
現在の最小値=13.13000339865731反復9回目
現在の最小値=13.13000339865731反復8回目
現在の最小値=13.13000339865731反復7回目
現在の最小値=13.13000339865731反復6回目
現在の最小値=13.13000339865731反復5回目
現在の最小値=13.13000339865731反復4回目
現在の最小値=13.13000339865731反復3回目
現在の最小値=13.13000339865731反復2回目
現在の最小値=13.13000339865731反復1回目
現在の最小値=13.13000339865731反復0回目
 
 
他の方法で検証したが,結果は最後に小数点の後10位に正確になった.