? ? ? ?遺傳算法是經(jīng)典的智能算法,?經(jīng)常被用來(lái)求解各種N-P問(wèn)題,?各種非線性函數(shù)的優(yōu)化等,?可以實(shí)現(xiàn)各類模型的非最優(yōu)解優(yōu)化.?遺傳算法穩(wěn)定性比較強(qiáng),?優(yōu)化的效果比較好,?不是特別依賴初值,?尤其對(duì)離散自變量的函數(shù)優(yōu)化是很合適的,?比較容易得到理論最優(yōu)解,?整體的運(yùn)行效率比較好,?對(duì)線性或非線性的約束都很友好.
? ? ? ? 遺傳算法的大體流程如下:
?流程包括:
(1)編碼的設(shè)計(jì)方案,?編碼就是染色體的編碼,?每一個(gè)染色體都與目標(biāo)函數(shù)的一個(gè)解是對(duì)應(yīng)的,?也就是遺傳算法的一個(gè)染色體是目標(biāo)函數(shù)解的一個(gè)單射,?一個(gè)染色體唯一對(duì)應(yīng)一個(gè)解(但反過(guò)來(lái)不一定,?不同的染色體可以對(duì)應(yīng)同樣的一個(gè)解).? 編碼的設(shè)計(jì)方案對(duì)于求目標(biāo)函數(shù)解的可行性和效率是非常重要的,?對(duì)于不同的問(wèn)題模型,?我們需要專門設(shè)計(jì)編碼方案,?比如對(duì)于離散的排序問(wèn)題,?我們可以設(shè)計(jì)一個(gè)自然數(shù)排序編碼 [1,3,2,5,4]這樣的排序編碼,?來(lái)映射排序問(wèn)題的自變量或解,?對(duì)于多維實(shí)數(shù)域的函數(shù)優(yōu)化問(wèn)題,?可以把編碼設(shè)計(jì)為[0.1,0.5,1.2,1.3,2.5]這樣的多維實(shí)數(shù)編碼,直接對(duì)應(yīng)自變量x.? 如何設(shè)計(jì)編碼是各類智能算法永恒的課題.
(2)讀取或設(shè)置問(wèn)題模型的數(shù)據(jù)和參數(shù).
(3)設(shè)置遺傳算法參數(shù),?如種群數(shù),?迭代次數(shù),?交叉率,?變異率.
(4)初始化種群,?一般采用隨機(jī)產(chǎn)生一組染色體作為算法的初始染色體.
(5)開始迭代,?進(jìn)行染色體的變異操作.
(6)對(duì)染色體進(jìn)行交叉操作.
(7)對(duì)染色體進(jìn)行解碼,??這個(gè)過(guò)程就是把染色體映射到解
(8)根據(jù)解計(jì)算目標(biāo)函數(shù)值和約束,,?再把解帶入問(wèn)題模型,得到目標(biāo)函數(shù)值以及是否滿足約束等.
(9)根據(jù)解得到的目標(biāo)函數(shù)對(duì)染色體進(jìn)行選擇,?這個(gè)選擇的操作方法也是比較關(guān)鍵的,?這里面體現(xiàn)了進(jìn)化論的思想,?也即適者生存,?或者適者被選中的概率更大,?久而久之,隨著迭代的進(jìn)行,?適應(yīng)性更好的染色體會(huì)存活下來(lái),?最后得到的是較優(yōu)解,?當(dāng)然如果迭代次數(shù)夠充分,?種群數(shù)夠大,?往往是可以得到理論最優(yōu)解的,?但并不能保證你得到.
(10)輸出結(jié)果,?一般包括迭代曲線和最優(yōu)編碼,最優(yōu)解,?最優(yōu)目標(biāo)函數(shù)等.?進(jìn)而完成了整個(gè)算法的構(gòu)建和問(wèn)題模型的求解.
? ? ? ? 那么如何用MATLAB實(shí)現(xiàn)遺傳算法呢?根據(jù)以上的步驟,? 我們的問(wèn)題模型是:?
其中xi∈[0,1], N=5
? ? ? ?那么我們可直接采用5維實(shí)數(shù)編碼構(gòu)造染色體(見染色體函數(shù)mygenchrome.m) ,?
初始化染色體
N=5,?上下限維[0,1]區(qū)間,? 則一個(gè)合法的染色體可表示為[0.1,0.5,0.6,1.0,0.4],?完全均勻隨機(jī)產(chǎn)生, 見染色體函數(shù)mygenchrome.m.
變異(采用單點(diǎn)變異)
(1) 產(chǎn)生一個(gè)隨機(jī)自然數(shù)r1,r1表示第r1位的基因發(fā)生變異
(2) 采用隨機(jī)變異的方式將第r1位的基因進(jìn)行變異.
舉例:
r1=2, 那么染色體的變異為
[0.1,0.5,0.6,1.0,0.4]→[0.1,0.2,0.6,1.0, 0.4]
交叉
(1) 隨機(jī)選擇兩個(gè)染色體作為父本
(2) 產(chǎn)生2個(gè)隨機(jī)自然數(shù)r1和r2
(3) 將兩個(gè)父本染色體r1至r2之間的基因片段進(jìn)行交換, 得到兩個(gè)子代染色體
舉例:
選擇的兩個(gè)父本染色體
[0.1,0.5,0.6,1.0,0.4] ?[0.1,0.5,0.6,0.70,0.54]
r1=2, r2=4
那么交叉過(guò)程為
[0.1,0.5,0.6,1.0,0.4] ?[0.1,0.5,0.6,0.7,0.54]
交叉后
[0.1,0.5,0.6,0.7, 0.4] ?[0.1,0.5,0.6,1.0, 0.54]
其他目標(biāo)函數(shù)何選擇函數(shù)等較為簡(jiǎn)單,?不再贅述.
? ? ? ? ? MATLAB是設(shè)計(jì)遺傳算法以及其他智能算法的非常好的工具,?下面給大家提供下遺傳算法的完整程序:?
主程序main.m
%% 遺傳算法 優(yōu)化函數(shù)
clc;close all;clear all;warning off;%清除變量
rand('seed', 100);
randn('seed', 100);
format long g;
my_N=10; % 設(shè)定優(yōu)化問(wèn)題維數(shù)
% 設(shè)定遺傳算法參數(shù)
my_popsize=500;% 設(shè)定遺傳算法種群數(shù)
my_maxgen=1000;% 設(shè)定遺傳算法迭代次數(shù)
my_PM=0.1;% 設(shè)定變異概率
my_PC=0.8;% 設(shè)定交叉概率
lb=0*ones(1,my_N);
ub=1*ones(1,my_N);
%% 遺傳算法主程序
my_tracemat=zeros(my_maxgen,2);% 設(shè)定性能跟蹤
my_gen=0;
tic;
Chrom_my=mygenchrome(my_popsize,my_N,lb,ub);% 建立種群
Value_my=mydecodingfun(Chrom_my,my_popsize);% 解碼染色體
[vmin_my,indexmin_my]=min(Value_my);
bestChrom_my=Chrom_my(indexmin_my,:);% 記錄最優(yōu)染色體
bestValue_my=vmin_my;% 記錄的最優(yōu)值
%% 遺傳算法優(yōu)化的主循環(huán)
while my_gen<my_maxgen
%% 遺傳算子
FitnV=myranking(Value_my);% 分配適應(yīng)度值
Chrom_my=myselect('rws',Chrom_my,FitnV,1);% 選擇
Chrom_my=mymutationga(Chrom_my,my_popsize,my_PM,my_N,lb,ub);% 種群變異,單點(diǎn)變異
Chrom_my=mycrossga(Chrom_my,my_popsize,my_PC,my_N);% 種群交叉,2點(diǎn)交叉
Value_my=mydecodingfun(Chrom_my,my_popsize);% 解碼染色體
%% 計(jì)算最優(yōu)
[vmin_my,indexmin_my]=min(Value_my);
my_gen=my_gen+1;
%% 記錄最優(yōu)
if bestValue_my>vmin_my
bestValue_my=vmin_my;%記錄的最優(yōu)值
bestChrom_my=Chrom_my(indexmin_my,:);
end
my_tracemat(my_gen,2)=mean(Value_my);
my_tracemat(my_gen,1)=bestValue_my;% 保留最優(yōu)
end
disp('算法運(yùn)行時(shí)間');
runtime_ga_my=toc
% 顯示結(jié)果
disp('遺傳算法優(yōu)化得到的最優(yōu)目標(biāo)函數(shù)值');
bestValue_my
disp('遺傳算法優(yōu)化得到的最優(yōu)染色體');
bestChrom_my
figure;
plot(my_tracemat(:,1),'r-','linewidth',1);
hold on;
plot(my_tracemat(:,2),'b-','linewidth',1);
legend({'種群最優(yōu)值','種群均值'},'fontname','宋體');
xlabel('迭代次數(shù)','fontname','宋體');
ylabel('目標(biāo)函數(shù)值','fontname','宋體');
title('遺傳算法迭代曲線','fontname','宋體');
交叉函數(shù) mycrossga.m
function Chrom=mycrossga(Chrom,popsize,PC,N)
% 種群交叉,2點(diǎn)交叉
index100=randperm(popsize);
long1=fix(popsize/2);
set1=index100(1:long1);
set2=index100(long1+1:long1*2);
for i=1:long1
a=rand;
if a<PC%小于交叉率開始交叉
index201=set1(i);
index202=set2(i);
R1=Chrom(index201,:);
R2=Chrom(index202,:);
rmat=randi([1,N],1,2);%
r1=min(rmat);
r2=max(rmat);
S1=R1(r1:r2);%交叉位置的節(jié)點(diǎn)
S2=R2(r1:r2);%交叉位置的節(jié)點(diǎn)
R1(r1:r2)=S2;
R2(r1:r2)=S1;
%更新染色體
Chrom(index201,:)=R1;
Chrom(index202,:)=R2;
end
end
解碼函數(shù)mydecodingfun.m
function Value = mydecodingfun(Chrom,popsize)
%解碼染色體
Value=zeros(popsize,1);
for i=1:popsize
x=Chrom(i,:);
y=myfun(x);
Value(i,1)=y;
end
目標(biāo)函數(shù)myfun.m
function y=myfun(x)
y=sum((x-0.5).^2);
初始染色體函數(shù)mygenchrome.m
function Chrom=mygenchrome(popsize,N,lb,ub)
% 建立種群
Chrom=zeros(popsize,N);
for i=1:popsize
for j=1:N
Chrom(i,j)=lb(j)+(ub(j)-lb(j))*rand(1,1);
end
end
染色體變異函數(shù)mymutationga.m
function Chrom=mymutationga(Chrom,popsize,PM,N,lb,ub)
% 種群變異,單點(diǎn)變異
for i=1:popsize
a=rand;
if a<PM
r=unidrnd(N);
Chrom(i,r)=lb(r)+(ub(r)-lb(r))*rand(1,1);
end
end
?
分配適應(yīng)度函數(shù)
function FitnV = myranking(ObjV, RFun, SUBPOP);
% Identify the vector size (Nind)
[Nind,ans] = size(ObjV);
if nargin < 2, RFun = []; end
if nargin > 1, if isnan(RFun), RFun = []; end, end
if prod(size(RFun)) == 2,
if RFun(2) == 1, NonLin = 1;
elseif RFun(2) == 0, NonLin = 0;
else error('Parameter for ranking method must be 0 or 1'); end
RFun = RFun(1);
if isnan(RFun), RFun = 2; end
elseif prod(size(RFun)) > 2,
if prod(size(RFun)) ~= Nind, error('ObjV and RFun disagree'); end
end
if nargin < 3, SUBPOP = 1; end
if nargin > 2,
if isempty(SUBPOP), SUBPOP = 1;
elseif isnan(SUBPOP), SUBPOP = 1;
elseif length(SUBPOP) ~= 1, error('SUBPOP must be a scalar'); end
end
if (Nind/SUBPOP) ~= fix(Nind/SUBPOP), error('ObjV and SUBPOP disagree'); end
Nind = Nind/SUBPOP; % Compute number of individuals per subpopulation
% Check ranking function and use default values if necessary
if isempty(RFun),
% linear ranking with selective pressure 2
RFun = 2*[0:Nind-1]'/(Nind-1);
elseif prod(size(RFun)) == 1
if NonLin == 1,
% non-linear ranking
if RFun(1) < 1, error('Selective pressure must be greater than 1');
elseif RFun(1) > Nind-2, error('Selective pressure too big'); end
Root1 = roots([RFun(1)-Nind [RFun(1)*ones(1,Nind-1)]]);
RFun = (abs(Root1(1)) * ones(Nind,1)) .^ [(0:Nind-1)'];
RFun = RFun / sum(RFun) * Nind;
else
% linear ranking with SP between 1 and 2
if (RFun(1) < 1 | RFun(1) > 2),
error('Selective pressure for linear ranking must be between 1 and 2');
end
RFun = 2-RFun + 2*(RFun-1)*[0:Nind-1]'/(Nind-1);
end
end;
FitnV = [];
% loop over all subpopulations
for irun = 1:SUBPOP,
% Copy objective values of actual subpopulation
ObjVSub = ObjV((irun-1)*Nind+1:irun*Nind);
% Sort does not handle NaN values as required. So, find those...
NaNix = isnan(ObjVSub);
Validix = find(~NaNix);
% ... and sort only numeric values (smaller is better).
[ans,ix] = sort(-ObjVSub(Validix));
% Now build indexing vector assuming NaN are worse than numbers,
% (including Inf!)...
ix = [find(NaNix) ; Validix(ix)];
% ... and obtain a sorted version of ObjV
Sorted = ObjVSub(ix);
% Assign fitness according to RFun.
i = 1;
FitnVSub = zeros(Nind,1);
for j = [find(Sorted(1:Nind-1) ~= Sorted(2:Nind)); Nind]',
FitnVSub(i:j) = sum(RFun(i:j)) * ones(j-i+1,1) / (j-i+1);
i =j+1;
end
% Finally, return unsorted vector.
[ans,uix] = sort(ix);
FitnVSub = FitnVSub(uix);
% Add FitnVSub to FitnV
FitnV = [FitnV; FitnVSub];
end
選擇函數(shù)myselect.m
function SelCh = myselect(SEL_F, Chrom, FitnV, GGAP, SUBPOP);
% Check parameter consistency
if nargin < 3, error('Not enough input parameter'); end
% Identify the population size (Nind)
[NindCh,Nvar] = size(Chrom);
[NindF,VarF] = size(FitnV);
if NindCh ~= NindF, error('Chrom and FitnV disagree'); end
if VarF ~= 1, error('FitnV must be a column vector'); end
if nargin < 5, SUBPOP = 1; end
if nargin > 4,
if isempty(SUBPOP), SUBPOP = 1;
elseif isnan(SUBPOP), SUBPOP = 1;
elseif length(SUBPOP) ~= 1, error('SUBPOP must be a scalar'); end
end
if (NindCh/SUBPOP) ~= fix(NindCh/SUBPOP), error('Chrom and SUBPOP disagree'); end
Nind = NindCh/SUBPOP; % Compute number of individuals per subpopulation
if nargin < 4, GGAP = 1; end
if nargin > 3,
if isempty(GGAP), GGAP = 1;
elseif isnan(GGAP), GGAP = 1;
elseif length(GGAP) ~= 1, error('GGAP must be a scalar');
elseif (GGAP < 0), error('GGAP must be a scalar bigger than 0'); end
end
% Compute number of new individuals (to select)
NSel=max(floor(Nind*GGAP+.5),2);
% Select individuals from population
SelCh = [];
for irun = 1:SUBPOP,
FitnVSub = FitnV((irun-1)*Nind+1:irun*Nind);
ChrIx=feval(SEL_F, FitnVSub, NSel)+(irun-1)*Nind;
SelCh=[SelCh; Chrom(ChrIx,:)];
end
% End of function
選擇函數(shù)用輪盤賭子函數(shù)rws.m
function NewChrIx = rws(FitnV,Nsel)
% 輪盤賭選擇
[Nind,ans] = size(FitnV);
cumfit = cumsum(FitnV);
trials = cumfit(Nind) .* rand(Nsel, 1);
Mf = cumfit(:, ones(1, Nsel));
Mt = trials(:, ones(1, Nind))';
[NewChrIx, ans] = find(Mt < Mf & ...
[ zeros(1, Nsel); Mf(1:Nind-1, :) ] <= Mt);
程序結(jié)果如下:
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-648708.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-648708.html
到了這里,關(guān)于遺傳算法及其MATLAB實(shí)現(xiàn)(附完整代碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!