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ビットまで正確にすることができる.
次は私がこの問題を解決するすべての関数で、コピーは実行できます.
スワップ値の関数:
交差の実行:
変異過程は,関数の2番目のパラメータを調節することによって個体ごとの変異率を変化させ,異なる問題に対してある程度より良い効果を達成できる.
復号化とは、バイナリ文字列を10進数に変換することです.
適応度関数とは、xごとに対応する関数値を計算し、-1を乗じることで、関数値が大きいほど適応度が小さくなり、関数値が小さいほど適応度が大きくなる
主関数は上の関数を呼び出し,Cで反復回数を変更し,popでクラスタサイズと暗号子長を変更できる.私の反復は5000回で、10万個の個体の中から最も優れたものを選ぶことに相当します.
答えは次のとおりです.
現在の最小値=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位に正確になった.
構想: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位に正確になった.