関数値最も遺伝的アルゴリズム
I.はじめに
これは、関数があります。
f(x) = x + 10*sin(5*x) + 7*cos(4*x);
次のように、画像を描画するのは簡単です:
最初の関数の最大値を選択する必要があり、読者はすでに非常に多くのアイデアを持っていることが、この記事では、遺伝的アルゴリズムは、このような問題を解決する方法について説明します。
遺伝的アルゴリズムに1.はじめに
あなたは、アルゴリズムの実装の詳細を気にしない場合は、遺伝的アルゴリズムは、以下のプロセス記述を使用することができます。
これは、得られた生物学的集団と抽象の自然な進化を描く基本的なフローチャートです。以下に説明するフローチャートの様々なステップです。
コーディング
我々はすべて知っているように、生物は、材料のその遺伝情報を記憶している-染色体、遺伝子情報の染色体レコード-個々の生物の遺伝的に決定された形質性能、それは単純に考えてもよいユニークな生物学的個人を識別染色体。
染色体は、コンピュータシミュレーションは非現実的で、その構造は非常に複雑であり、基本的にタンパク質です。したがって、遺伝的アルゴリズムは、単に染色体とみなす二進数字の文字列からなる配列(すなわち、配列のすべての要素の集合から取られました{0,1}
)。
Aという名前と仮定生物、所定の長さが8である、あなたは個人を得ることができ、染色体系列:
[0,1,0,0,1,0,1,1]
初期集団
明らかに一つだけの個々の生物学的な人口を含んでいない、それは利便性の原理を説明するためには、人口の大きさを指定することができ、それは、そのサイズ4の規定です。初期集団はランダムに生成することができます。次のように:
[1,1,1,1,1,1,0,0]
[1,1,1,1,0,1,1,0]
[1,0,1,0,0,0,0,1]
[0,0,0,1,0,1,0,1]
人口の個々の適性評価
生物学的集団の存在の盛衰と環境に適応する能力に依存します。バイナリビットを表す個々のシーケンスの場合、あなたは常に環境に適応するために、個人の能力を評価するための機能を見つけることができます。関数を定義することができます:
f(x) = int(x)
# x是输入的一个个体,如[0,1,0,0,1,0,1,1]
# 返回值是该二进制序列表示的整数
また、上述した機能は、個々の適応度が高ければ高いほど、所定の値(整数)を返すことができます。明らかにフィットネスが最高個人であります:
[1,1,1,1,1,1,1,1]
選択
個体の集団における生存の確率が高いために選択したオプションは、これらの個人は、新たな集団を形成します。もちろん、個々の生存確率の高い個々の適性が高いです。だから、新しい人口を選出するルーレットアルゴリズムを使用することができます。ルーレットアルゴリズムの重要な原則は、この記事ではありませんが、省略され、その実装コードは、以下を参照してください。
クロス
クロスオーバーは、遺伝的プロセスを抽象化したものです。2つの個々の生物、生殖過程のこれらの二つの生殖の個人は、それは、染色体交換を越え、新たな染色体を生成し、乗算新しい染色体を運ぶ新しい個人を来る、があります。
次のようにそれは、2つの個々の生物が備えられています。
[1,1,1,1,1,1,0,0]
[1,1,1,1,0,1,1,0]
二つの特定の生物個体の交叉確率を持って設けられ、クロスオーバーは、ビットのシーケンス内の特定の位置で発生しなければなりません。この位置を選択してもランダムです。以下の工程、(1から数えて)ビット5が重複し始めると仮定する。
[1,1,1,1,1,1,0,0]
[1,1,1,1,0,1,1,0]
->
[1,1,1,1,1],[1,0,0]
[1,1,1,1,0],[1,1,0]
->
[1,1,1,1,1],[1,1,0]
[1,1,1,1,0],[1,0,0]
->
[1,1,1,1,1,1,1,0]
[1,1,1,1,0,1,0,0]
バリエーション
環境の影響を受け、自然環境中の生物、それは永久に遺伝情報発生を変更することができる、それがバリエーションです。遺伝的アルゴリズムは、ビットの突然変異配列がランダム否定の順序で選択された特定の確率を意味することを提供します。ポジション2は、以下の手順で変異と仮定します。
[0,1,0,0,1,0,1,1]
->
[0],1,[0,0,1,0,1,1]
->
[0],0,[0,0,1,0,1,1]
->
[0,0,0,0,1,0,1,1]
概要
集団におけるすべての個体のような、(すなわち、収束)と同じになるまで上記のフローチャートに示す各ステップで実行されます。
[1,0,1,0,0,0,0,1]
[1,0,1,0,0,0,0,1]
[1,0,1,0,0,0,0,1]
[1,0,1,0,0,0,0,1]
またはメインループ反復が所定の回数を超えて、アルゴリズムは出力を停止します。
Matlabの入門
この記事では、MATLABでアルゴリズムを記述し、そのためのMatlabのいくつかの知識を持っている必要があります。ヘルプの読者を取得するが、Matlabのは、マニュアルは、読者が迅速にMATLABを得るのを助けることができますことをお勧めします、私たちの仕事ではありません。
https://ww2.mathworks.cn/help/pdf_doc/matlab/getstart_zh_CN.pdf
MATLABは、フリーソフトウェアで、ソフトウェアを実行しているのパフォーマンスは、一定の要件を持っているので、あなたは無料のオープンソースを使用することができますし、次のようにその公式サイト、代用としてオクターブ少ないリソースを取ります
https://www.gnu.org/software/octave/
以下は基本的に同じ、非互換性をMATLABを使用してオクターブの構文規則:
https://en.wikibooks.org/wiki/MATLAB_Programming/Differences_between_Octave_and_MATLAB
コードを実行するためにMATLABを使用する必要がある場合には、MATLABでテストされていない、駆け抜けるオクターブ上のコードこれに付随するので、あなたは互換性をチェックする必要があります。
アルゴリズム
function retval = main (input1, input2)
% 主函数,input1,input2,以及retval都没有实际作用
clear all;
close all;
clc;
NP = 50; % 种群大小
L = 16; % 染色体序列长度
Pc = 0.8; % 交叉概率
Pm = 0.1; % 变异概率
G = 50; % 主循环迭代次数
Xs = 10; % 所求函数的定义域的最大值
Xx = 0; % 所求函数的定义域的最小值
S = 10; % 什么意思自己悟吧,我只是不想硬编码成10
pop = initPop(NP,L);
for i = 1:G
dpop = decode(pop);
xpop = getX(dpop,L,Xx,Xs);
fit = fitValue(xpop);
if all(fit == fit(1)) % 如果收敛,停止主循环
break;
endif
[maxFit,maxIndex] = max(fit);
maxX(i) = getX(decode(pop(maxIndex,:)),L,Xx,Xs);
maxY(i) = maxFit;
pop = select(pop,fit,xpop);
pop = crossOver(pop,Pc);
pop = mutation(pop,Pm);
endfor
x = Xx:(Xs-Xx)/(2^L-1)/S:Xs;
y = targetFunc(x);
subplot(2,1,1);
plot(x,y); % 绘制函数图像
hold on;
plot(maxX,maxY,'r*'); % 绘制历次迭代生成的最大值点
[px,py] = size(maxY);
x = 1:py;
y = maxY;
subplot(2,1,2);
plot(x,y); % 绘制历次生成的最大值点关于迭代次数的折线图
hold off;
endfunction
function pop = initPop(NP,L)
pop = round(rand(NP,L));
endfunction
function res = targetFunc(x)
res = x + 10*sin(5*x) + 7*cos(4*x);
endfunction
function res = decode(pop)
% 用于将二进制位序列转化成整数
[px,py] = size(pop);
res = ones(px,1);
for j = 1:py
res(:,j) = 2.^(py-j)*pop(:,j);
endfor
res = sum(res,2);
endfunction
function res = getX(dpop,L,Xx,Xs)
% 缩放二进制位序列表示成的整数到
% 定义域中
res = dpop./(2^L-1).*(Xs-Xx);
endfunction
function res = fitValue(xpop)
res = targetFunc(xpop);
endfunction
function newpop = select(pop,fit,xpop)
% 赌轮盘算法的实现
[maxFit,maxIndex] = max(fit);
[minFit,minIndex] = min(fit);
[px,py] = size(pop);
newpop = ones(px,py);
fit = (fit-minFit)./(maxFit-minFit);
fit = fit./sum(fit);
cumfit = cumsum(fit);
ms = sort(rand(px,1));
fiti = 1;
newi = 1;
while newi <= px
if ms(newi) < cumfit(fiti)
newpop(newi,:) = pop(fiti,:);
newi = newi + 1;
else
fiti = fiti + 1;
endif
endwhile
endfunction
function newpop = crossOver(pop,Pc)
% 交叉操作
[px,py] = size(pop);
newpop = ones(size(pop));
for i = 1:2:px-1
if rand<Pc
cpoint = ceil(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,:);
endif
endfor
endfunction
function newpop = mutation(pop,Pm)
% 变异操作
[px,py] = size(pop);
newpop = ones(px,py);
for i = 1:px
if rand<Pm
mpoint=ceil(rand*py);
newpop(i,mpoint) = 1 - pop(i,mpoint);
newpop(i,:) = pop(i,:);
else
newpop(i,:) = pop(i,:);
endif
endfor
endfunction
次のように描画結果は以下の通りでした。