在matlab中intcon什么意思,GADST,你为何这么叼?(一)
一周前,我的遺傳算法在數值優化上再次失敗。在此之前我嘗試過遺傳算法結合局部搜索(隨機爬山、SQP、模式搜索),由于INTJ型人格認為結合局部信息的進化不是好進化,轉而嘗試了其他的方法:小生境技術(niching),以適應度共享的手段來維持種群的多樣性——在某些函數上取得了極好的效果,而參數的自適應控制卻非常困難;多種群技術(MPGA)——由于我的遷徙算法錯誤使得我的程序本質上就是用不同的控制參數進行多次計算;正交技術(OGA),通過構造正交矩陣,使得在初始化種群和產生子代時能夠均勻搜索整個解空間——在幾個測試函數上都取得了不錯的成果,但是后來我意識到這明明就是帶啟發式策略的網格搜索(grid
search),以及在一次離散事件仿真模擬的優化上得到了很糟糕的結果,加上計算開銷大、運算速度慢,很快被我打入冷宮。再加上遺傳算法在集合覆蓋問題、TSP、Packing問題上令我蛋疼的表現,一度我對遺傳算法的態度是“雞肋,還不如用分支定界”,轉而研究傳統優化算法——序列二次規劃(sequential
quadratic programming,SQP),在組合優化上也開始關注遺傳算法結合回溯搜索。
由于在五月份的對仿真模擬的優化問題上,我使用的NPMEA算法在處理帶約束的問題上讓我印象深刻(之前我只用著名的G8函數做過測試),上周我懷著極大的信心采用它的單純形交叉算子和自適應的高斯變異來做無約束優化(或者說是bound
constraint),但令人失望的是在某個五元函數上幾乎連全局最優點的附近都搜索不到,增加了多種群和小生境運算速度又太慢,實在令人垂頭喪氣。
最后我抱著死馬當活馬醫的態度打開gatool——我對這東西從來不屑一顧的,花里胡哨,不如自己coding來得快——結果太可怕了,一切參數采用默認設置,Schaffer函數以1的概率收斂到全局最優,顛覆三觀!!我當時又是失落又是激動,心里只有兩個字:“GADST,你為何這么叼?”一怒之下,把GADST的ga.m拆了,恍然大悟。
二、拆ga.m
step1:ga.m設置默認defaultopt
%-----------------------------e.g.---------------------------------
%代碼取自ga.m 181th~202th rows
%默認編碼類型為雙精度編碼
%默認生成初始種群向量下界為0上界為1
%默認種群大小為20
%默認使用gacreationuniform函數來生成均勻隨機分布的初始種群
defaultopt = struct('PopulationType', 'doubleVector', ...
'PopInitRange', [0;1],
...
'PopulationSize', 20,
...
'CreationFcn',@gacreationuniform);
step2:ga.m作各種檢查和判斷
%-----------------------------e.g.---------------------------------
%代碼取自ga.m 251th~277th rows
%檢查第十個輸入變量,若存在且是結構體,則為整數約束規劃
if nargin == 10 &&
isstruct(intcon)
options = intcon;
intcon = [];
end
%檢查輸入的FitnessFcn是不是function handles或者inlines,若不是則返回error
if isempty(FitnessFcn) ||
~(isa(FitnessFcn,'inline') ||
isa(FitnessFcn,'function_handle'))
error(message('globaloptim:ga:needFunctionHandle'));
end
step3:ga.m對空的options結構域使用默認defaultopt
%-----------------------------e.g.---------------------------------
%代碼取自ga.m 304th~308th rows
%若options為空,則使用默認的defaultopt
if ~isempty(options) &&
~isa(options,'struct')
error(message('globaloptim:ga:optionsNotAStruct'));
elseif isempty(options)
options =
defaultopt;
end
step4:ga.m調用子函數gacommon判斷問題類型和種群編碼類型
%-----------------------------e.g.---------------------------------
%代碼取自gacommon.m
14th~33th rows
%若結構體nonlcon非空則為非線性約束規劃,若線性等式約束矩陣非空則為線性約束規劃,若上下界矩陣非空
%則為邊界約束規劃,若都為空則為無約束規劃
if ~isempty(nonlcon)
type =
'nonlinearconstr';
elseif ~isempty(Aeq) || ~isempty(beq) || ~isempty(Aineq) ||
~isempty(bineq)
type =
'linearconstraints';
elseif ~isempty(lb) || ~isempty(ub)
type =
'boundconstraints';
else
type =
'unconstrained';
end
step5:ga.m對不同類型的問題調用不同子求解器
%-----------------------------e.g.---------------------------------
%代碼取自ga.m 349th~359th rows
%'unconstrained'調用無約束規劃求解器gaunc,'boundconstraints'和'linearconstraints'調用線性規劃求解
%器galincon,'nonlinearconstr'調用非線性規劃求解器gacon。
switch (output.problemtype)
case
'unconstrained'
[x,fval,exitFlag,output,population,scores] =
gaunc(FitnessFcn,nvars, ...
options,output,Iterate);
case
{'boundconstraints', 'linearconstraints'}
[x,fval,exitFlag,output,population,scores] =
galincon(FitnessFcn,nvars, ...
Aineq,bineq,Aeq,beq,lb,ub,options,output,Iterate);
case
'nonlinearconstr'
[x,fval,exitFlag,output,population,scores] =
gacon(FitnessFcn,nvars, ...
Aineq,bineq,Aeq,beq,lb,ub,NonconFcn,options,output,Iterate,type);
end
(下面以boundconstraints為例,調用galincon)
step6:在galincon.m中調用子函數makeState來初始化結構數組state
%-----------------------------e.g.---------------------------------
%代碼取自makeState.m 10th~30th rows
%初始化當前進化代數和當前停止代數
state.Generation = 0;
state.LastImprovement = 1;
%調用options.CreationFcn里的函數來生成初始種群,見step7
state.Population =
feval_r(options.CreationFcn,GenomeLength,FitnessFcn,options,
options.CreationFcnArgs{:});
(下面以默認的gacreationuniform函數為例,生成初始種群)
step7:在gacreationuniform.m里通過用戶提供的初始種群和初始種群范圍來隨機生產種群
%-----------------------------e.g.---------------------------------
%代碼取自gacreationuniform.m 42th~46th rows
%在PopInitRange范圍內生成均勻分布的隨機初始種群
%等價于Population=
unifrnd(lb,ub,initPopProvided+1,PopSize);
range = options.PopInitRange;
lowerBound = range(1,:);
span = range(2,:) - lowerBound;
Population(initPopProvided+1:end,:) =
repmat(lowerBound,individualsToCreate,1) + ...
repmat(span,individualsToCreate,1) .*
rand(individualsToCreate,GenomeLength);
step8:在galincon.m中調用子函數gadsplot繼續初始化結構數組state,為作圖做準備
略..
step9:在galincon.m中判斷是否滿足進化結束條件,若不滿足則進化一次
%-----------------------------e.g.---------------------------------
%代碼取自galincon.m 48th~91th rows
while isempty(exitFlag)
%進化代數加一
state.Generation =
state.Generation + 1;
%函數stepGA內完成排序\選擇\交叉\變異和種群的進化,見step10
[score,population,state]
=
stepGA(score,population,options,state,GenomeLength,FitnessFcn);
%記錄最佳個體
best =
min(state.Score);
generation =
state.Generation;
state.Best(generation) =
best;
%判斷和進行遷徙操作(僅針對多種群)
state =
migrate(FitnessFcn,GenomeLength,options,state);
%更新圖像輸出
state =
gadsplot(options,state,currentState,'Genetic Algorithm');
end
step10:stepGA.m產生精英后代、交叉后代和變異后代
%-----------------------------e.g.---------------------------------
%代碼取自stepGA.m 9th~36th rows
%精英后代數目
nEliteKids = options.EliteCount;
%交叉后代數目
nXoverKids = round(options.CrossoverFraction *
(size(thisPopulation,1) - nEliteKids));
%變異后代數目
nMutateKids = size(thisPopulation,1) - nEliteKids -
nXoverKids;
%用于產生交叉和變異所需的父代數目
nParents = 2 * nXoverKids + nMutateKids;
%適應度排序操作,見step11
state.Expectation =
feval_r(options.FitnessScalingFcn,thisScore,nParents,...
options.FitnessScalingFcnArgs{:});
%選擇交叉和變異所需的后代,見step12
parents =
feval_r(options.SelectionFcn,state.Expectation,nParents,options,...
options.SelectionFcnArgs{:});
[unused,k] = sort(thisScore);
%產生精英后代
eliteKids ?=
thisPopulation(k(1:options.EliteCount),:);
%產生交叉后代,見step13
xoverKids ?= feval_r(options.CrossoverFcn,
parents(1:(2 * nXoverKids)),options,GenomeLength,...
FitnessFcn,thisScore,thisPopulation,options.CrossoverFcnArgs{:});
%產生交叉后代,見step14
mutateKids = feval_r(options.MutationFcn,
parents((1 + 2 * nXoverKids):end),
options,GenomeLength,
FitnessFcn,state,thisScore,thisPopulation,options.MutationFcnArgs{:});
step11:在stepGA.m中調用options.FitnessScalingFcn中的適應度排序函數進行適應度排序操作
這里用默認的fitscalingrank函數
%-----------------------------e.g.---------------------------------
%代碼取自fitscalingrank.m 16th~21th rows
%expectation將score映射到從1開始的整數的平方根的倒數,并作比例處理
[~,i] = sort(scores);
expectation = zeros(size(scores));
expectation(i) = 1 ./ ((1:length(scores)) ?.^
0.5);
expectation = nParents * expectation ./
sum(expectation);
step12:在stepGA.m中調用options.SelectionFcn中的選擇函數,根據各父代的適應度選出參與交叉變異的父代。
這里用默認的selectionstochunif函數
%-----------------------------e.g.---------------------------------
%代碼取自selectionstochunif.m 22th~44th rows
%對expectation累計求和及對[0,1]等分為stepSize后,position從第一等分的任意位置開始,找到第一個大于
%position的wheel的索引作為選出的一個子代,position前進一個stepSize
wheel = cumsum(expectation) / nParents;
stepSize = 1/nParents;
position = rand * stepSize;
lowest = 1;
for i = 1:nParents % for each parent needed,
for j =
lowest:length(wheel)
if(position <
wheel(j))
parents(i)
= j;
lowest =
j;
break;
end
end
position = position +
stepSize;
end
step13:在stepGA.m中調用options.CrossoverFcn中的交叉函數,產生交叉后代。
這里用默認的selectionstochunif函數
%-----------------------------e.g.---------------------------------
%代碼取自crossoverscattered.m 42th~48th rows
%對子代的每個位置,取[0,1]隨機數,若隨機數大于0.5則取父代A對應位置的數,反之取父代B
for j = 1:GenomeLength
if(rand >
0.5)
xoverKids(i,j) = thisPopulation(r1,j);
else
xoverKids(i,j) = thisPopulation(r2,j);
end
end
step14:在stepGA.m中調用options.MutationFcn中的變異函數,讓選出的父代變異產生后代。
MATLAB默認的mutationadaptfeasible函數采用了復雜的算法來確定變異的搜索方向(search
directions)
%-----------------------------e.g.---------------------------------
%代碼簡化自mutationadaptfeasible.m 58th~126th rows
%MeshSize是自適應網格步長,和模式搜索類似,當遺傳算法進化一代搜索到更優解時步長擴大為四倍,反之縮
%小為四分之一
%注意到MeshSize = 2^(-4^k),可知pollParam一定為整數
pollParam = 1/sqrt(MeshSize);
%等價于lowerT?=?tril(unidrnd(pollParam,?nGenome,?nGenome));
lowerT = tril((round((pollParam+1)*rand(nGenome) -
0.5)),-1);
%等價于diagtemp = unidrnd(2*pollParam,?nGenome)
-?pollParam;
diagtemp = pollParam*sign(rand(nGenome,1) - 0.5);
diagT ?= diag(diagtemp);
Basis = lowerT + diagT;
order = randperm(nGenome);
%方陣Basis每一列決定一個搜索方向向量
Basis = Basis(order,order);
%隨機取搜索方向向量和方向符號來生成后代
indexVec = [1:nGenome 1:nGenome];
dirSign = [ones(1,nGenome) -ones(1,nGenome)];
OrderVec = randperm(2*nGenome);
for jj = 1:2*nGenome
direction =
dirSign(jj).*Basis(:,indexVec(OrderVec(jj)));
mutant = Parent(ii,:) +
MeshSize*direction';
%若生成后代滿足約束則不再搜索其他方向
if all(mutant
>= lb & mutant <=
ub)
Kid(ii,:) = mutant;
break;
else
Kid(ii,:) = Parent(ii,:);
end
end
總結
以上是生活随笔為你收集整理的在matlab中intcon什么意思,GADST,你为何这么叼?(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用C++模板编写的序列化框架
- 下一篇: win2003下面显示dbgprint的