昊 天

遗传算法工具箱(GOAT)的注释
goat这个工具箱是网上流传最广的一个,我仅仅针对其主函数做了注释。

function [x,endPop,bPop,traceInfo] = ga(bounds,evalFN,evalOps,startPop,opts,...
termFN,termOps,selectFN,selectOps,xOverFNs,xOverOps,mutFNs,mutOps)
% GA run a genetic algorithm
% function [x,endPop,bPop,traceInfo]=ga(bounds,evalFN,evalOps,startPop,opts,
%                                       termFN,termOps,selectFN,selectOps,
%                                       xOverFNs,xOverOps,mutFNs,mutOps)
%                               
% Output Arguments:
%   x            - the best solution found during the course of the run 求得的最优解
%   endPop       - the final population 最终得到的种群
%   bPop         - a trace of the best population 最优种群的一个搜索轨迹
%   traceInfo    - a matrix of best and means of the ga for each generation 每一代种群的最优个体和均值
%
% Input Arguments:
%   bounds       - a matrix of upper and lower bounds on the variables 代表变量上下界的矩阵
%   evalFN       - the name of the evaluation .m function 适应度函数所在的m文件
%   evalOps      - options to pass to the evaluation function ([NULL]) 传递给适应度函数的参数
%   startPop     - a matrix of solutions that can be initialized 初始种群
%                  from initialize.m
%   opts         - [epsilon prob_ops display] change required to consider two
%                  solutions different, prob_ops 0 if you want to apply the
%                  genetic operators probabilisticly to each solution, 1 if
%                  you are supplying a deterministic number of operator
%                  applications and display is 1 to output progress 0 for
%                  quiet. ([1e-6 1 0])
%   1e-6:变量进行二进制编码时指定的精度,1:选择浮点编码,0:为二进制编码,并指定精度,为第三个0时结束
%   termFN       - name of the .m termination function (['maxGenTerm']) 终止函数所在的m文件
%   termOps      - options string to be passed to the termination function 传递个终止函数的参数,一般为需要遗传的代数
%                  ([100]).
%   selectFN     - name of the .m selection function (['normGeomSelect']) 选择函数的名称
%   selectOpts   - options string to be passed to select after 传递给选择函数的参数,一般为变异概率
%                  select(pop,#,opts) ([0.08])
%   xOverFNS     - a string containing blank seperated names of Xover.m 交叉函数名称表,以空格分开
%                  files (['arithXover heuristicXover simpleXover'])
%   xOverOps     - A matrix of options to pass to Xover.m files with the 传递给交叉函数的参数表
%                  first column being the number of that xOver to perform
%                  similiarly for mutation ([2 0;2 3;2 0])
%   mutFNs       - a string containing blank seperated names of mutation.m 变异函数表%                  files (['boundaryMutation multiNonUnifMutation ...
%                           nonUnifMutation unifMutation'])
%   mutOps       - A matrix of options to pass to Xover.m files with the 传递给变异函数的参数表
%                  first column being the number of that xOver to perform
%                  similiarly for mutation ([4 0 0;6 100 3;4 100 3;4 0 0])

% Binary and Real-Valued Simulation Evolution for Matlab
% Copyright (C) 1996 C.R. Houck, J.A. Joines, M.G. Kay
%
% C.R. Houck, J.Joines, and M.Kay. A genetic algorithm for function
% optimization: A Matlab implementation. ACM Transactions on Mathmatical
% Software, Submitted 1996.
%
% This program is free software; you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation; either version 1, or (at your option)
% any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details. A copy of the GNU
% General Public License can be obtained from the
% Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

%%$Log: ga.m,v $
%Revision 1.10  1996/02/02  15:03:00  jjoine
% Fixed the ordering of imput arguments in the comments to match
% the actual order in the ga function.
%
%Revision 1.9  1995/08/28  20:01:07  chouck
% Updated initialization parameters, updated mutation parameters to reflect
% b being the third option to the nonuniform mutations
%
%Revision 1.8  1995/08/10  12:59:49  jjoine
%Started Logfile to keep track of revisions
%


n=nargin;%nargin得到函数的参数个数
if n<2 | n==6 | n==10 | n==12
  disp('Insufficient arguements')
end
if n<3 %Default evalation opts.
  evalOps=[];%适应度函数的参数为空
end
if n<5
  opts = [1e-6 1 0];%进行二进制编码,并指定精度
end
if isempty(opts)
  opts = [1e-6 1 0];%默认情况下为二进制编码
end

if any(evalFN<48) %Not using a .m file
  if opts(2)==1 %Float ga,opts函数的第二个参数为1,则使用浮点数编码
    e1str=['x=c1; c1(xZomeLength)=', evalFN ';']; 
    e2str=['x=c2; c2(xZomeLength)=', evalFN ';']; 
  else %Binary ga,opts函数的第二个参数为0,则使用二进制编码
    e1str=['x=b2f(endPop(j,:),bounds,bits); endPop(j,xZomeLength)=',...
 evalFN ';'];
  end
else %Are using a .m file
  if opts(2)==1 %Float ga,opts函数的第二个参数为1,则使用浮点数编码
    e1str=['[c1 c1(xZomeLength)]=' evalFN '(c1,[gen evalOps]);']; 
    e2str=['[c2 c2(xZomeLength)]=' evalFN '(c2,[gen evalOps]);']; 
  else %Binary ga,opts函数的第二个参数为0,则使用二进制编码
    e1str=['x=b2f(endPop(j,:),bounds,bits);[x v]=' evalFN ...
 '(x,[gen evalOps]); endPop(j,:)=[f2b(x,bounds,bits) v];']; 
  end
end


if n<6 %Default termination information,默认终止函数信息
  termOps=[100];%默认遗传100代
  termFN='maxGenTerm';
end
if n<12 %Default muatation information,默认变异信息
  if opts(2)==1 %Float GA,浮点数编码
  mutFNs=['boundaryMutation multiNonUnifMutation nonUnifMutation unifMutation'];
    mutOps=[4 0 0;6 termOps(1) 3;4 termOps(1) 3;4 0 0];
  else %Binary GA,二进制编码
    mutFNs=['binaryMutation'];%采用二进制变异
    mutOps=[0.05];%默认变异率为0.05
  end
end
if n<10 %Default crossover information,默认交叉信息
  if opts(2)==1 %Float GA,浮点数编码
    xOverFNs=['arithXover heuristicXover simpleXover'];
    xOverOps=[2 0;2 3;2 0];
  else %Binary GA,二进制编码
    xOverFNs=['simpleXover'];
    xOverOps=[0.6];
  end
end
if n<9 %Default select opts only i.e. roullete wheel.默认为轮盘赌选择算法
  selectOps=[];
end
if n<8 %Default select info
  selectFN=['normGeomSelect'];
  selectOps=[0.08];
end
if n<6 %Default termination information,默认终止函数信息
  termOps=[100];%默认遗传100代
  termFN='maxGenTerm';
end
if n<4 %No starting population passed given,没有给定初始化的种群
  startPop=[];
end
if isempty(startPop) %Generate a population at random,如果没有给定初始种群,则随机生成
  %startPop=zeros(80,size(bounds,1)+1);
  startPop=initializega(80,bounds,evalFN,evalOps,opts(1:2));%生成初始化的种群
end

if opts(2)==0 %binary,二进制编码
  bits=calcbits(bounds,opts(1));%找出在bounds范围内满足精度的bit位数
end

xOverFNs=parse(xOverFNs);%分析交叉函数
mutFNs=parse(mutFNs);%分析变异函数

xZomeLength  = size(startPop,2);  %Length of the xzome=numVars+fittness,返回个体的变量数目加上适值所占一位
numVar       = xZomeLength-1;   %Number of variables,得到变量数目
popSize      = size(startPop,1);  %Number of individuals in the pop,得到个体大小
endPop       = zeros(popSize,xZomeLength); %A secondary population matrix,下一代种群矩阵
c1           = zeros(1,xZomeLength);  %An individual,得到一个个体,为交叉准备
c2           = zeros(1,xZomeLength);  %An individual,得到另一个个体,为交叉准备
numXOvers    = size(xOverFNs,1);  %Number of Crossover operators,交叉操作的数目
numMuts      = size(mutFNs,1);   %Number of Mutation operators,变异操作数目
epsilon      = opts(1);                 %Threshold for two fittness to differ,表示二进制的精度
oval         = max(startPop(:,xZomeLength)); %Best value in start pop,适值最大的个体,也就是最后好的个体在一代中
bFoundIn     = 1;    %Number of times best has changed,最优个体改变的数目
done         = 0;           %Done with simulated evolution,进化是否结束的标志
gen          = 1;    %Current Generation Number,当前的种群数
collectTrace = (nargout>3);   %Should we collect info every gen,是否每代都进行信息收集
floatGA      = opts(2)==1;          %Probabilistic application of ops,是否是浮点编码
display      = opts(3);             %Display progress,显示过程

while(~done)    %当模拟进化没有进行的时候
  %Elitist Model
  [bval,bindx] = max(startPop(:,xZomeLength)); %Best of current pop,得到当前种群中最优的个体
  best =  startPop(bindx,:);

  if collectTrace %如果需要收集数据
    traceInfo(gen,1)=gen;             %current generation,当前代数
    traceInfo(gen,2)=startPop(bindx,xZomeLength);       %Best fittness,当前最优的适值
    traceInfo(gen,3)=mean(startPop(:,xZomeLength));     %Avg fittness,当前代中平均适值
    traceInfo(gen,4)=std(startPop(:,xZomeLength));      %当前代中适值的标准差
  end
 
  if ( (abs(bval - oval)>epsilon) | (gen==1)) %If we have a new best sol,如果产生了新的更优的个体,或者是第一代计算
    if display %如果需要显示计算过程
      fprintf(1,'\n%d %f\n',gen,bval);          %Update the display,显示当前的代数和最优适值
    end
    if floatGA
      bPop(bFoundIn,:)=[gen startPop(bindx,:)]; %Update bPop Matrix,同时改变最优的适值和个体,并记录
    else
      bPop(bFoundIn,:)=[gen b2f(startPop(bindx,1:numVar),bounds,bits)...
   startPop(bindx,xZomeLength)]; %返回最优个体和最优值的浮点数信息
    end
    bFoundIn=bFoundIn+1;                      %Update number of changes,增加一次改变
    oval=bval;                                %Update the best val,更新最优的适值
  else
    if display
      fprintf(1,'%d ',gen);               %Otherwise just update num gen,仅仅显示当前的代数
    end
  end
 
  endPop = feval(selectFN,startPop,[gen selectOps]); %Select,通过选择,得到下一代的种群
 
  if floatGA %Running with the model where the parameters are numbers of ops
    for i=1:numXOvers, %对每一个交叉函数
      for j=1:xOverOps(i,1),
 a = round(rand*(popSize-1)+1);  %Pick a parent,随机得到交叉的父代
 b = round(rand*(popSize-1)+1);  %Pick another parent
 xN=deblank(xOverFNs(i,:));  %Get the name of crossover function,得到要交叉的函数
 [c1 c2] = feval(xN,endPop(a,:),endPop(b,:),bounds,[gen xOverOps(i,:)]); %通过交叉,得到新的两个个体
 
 if c1(1:numVar)==endPop(a,(1:numVar)) %Make sure we created a new %确保得到的个体区别于父体,如果相同,直接将适值赋值
   c1(xZomeLength)=endPop(a,xZomeLength); %solution before evaluating
 elseif c1(1:numVar)==endPop(b,(1:numVar))
   c1(xZomeLength)=endPop(b,xZomeLength);
 else
   %[c1(xZomeLength) c1] = feval(evalFN,c1,[genevalOps]);,如果不相同,得到个体,并计算适值函数值
   eval(e1str);
 end
 if c2(1:numVar)==endPop(a,(1:numVar)) %另一个个体的操作同上
   c2(xZomeLength)=endPop(a,xZomeLength);
 elseif c2(1:numVar)==endPop(b,(1:numVar))
   c2(xZomeLength)=endPop(b,xZomeLength);
 else
   %[c2(xZomeLength) c2] = feval(evalFN,c2,[gen evalOps]);
   eval(e2str);
 end     
 
 endPop(a,:)=c1; %用新的个体代替原有的个体
 endPop(b,:)=c2;
      end
    end
 
    for i=1:numMuts, %对每一个变异函数
      for j=1:mutOps(i,1),
 a = round(rand*(popSize-1)+1); %随机产生变异的个体
 c1 = feval(deblank(mutFNs(i,:)),endPop(a,:),bounds,[gen mutOps(i,:)]); %对每个函数,将选择变异的个体进行变异
 if c1(1:numVar)==endPop(a,(1:numVar)) %确保产生了新的个体
   c1(xZomeLength)=endPop(a,xZomeLength);
 else
   %[c1(xZomeLength) c1] = feval(evalFN,c1,[gen evalOps]);
   eval(e1str); %得到新的个体,并得到适值
 end
 endPop(a,:)=c1; %用新的个体代替原有的个体
      end
    end
   
  else %We are running a probabilistic model of genetic operators,在概率下进行交叉
    for i=1:numXOvers, %对每一个交叉函数运算
      xN=deblank(xOverFNs(i,:));  %Get the name of crossover function,得到交叉函数
      cp=find(rand(popSize,1)<xOverOps(i,1)==1);
      if rem(size(cp,1),2) cp=cp(1:(size(cp,1)-1)); end
      cp=reshape(cp,size(cp,1)/2,2);
      for j=1:size(cp,1)
 a=cp(j,1); b=cp(j,2);
 [endPop(a,:) endPop(b,:)] = feval(xN,endPop(a,:),endPop(b,:),...
   bounds,[gen xOverOps(i,:)]);
      end
    end
    for i=1:numMuts %对每一个变异操作
      mN=deblank(mutFNs(i,:)); %得到变异函数
      for j=1:popSize
 endPop(j,:) = feval(mN,endPop(j,:),bounds,[gen mutOps(i,:)]); %变异并产生适值
 eval(e1str);
      end
    end
  end
 
  gen=gen+1; %代数加一
  done=feval(termFN,[gen termOps],bPop,endPop); %See if the ga is done,是否满足结束条件
  startPop=endPop;    %Swap the populations,替换新的种群
 
  [bval,bindx] = min(startPop(:,xZomeLength)); %Keep the best solution
  startPop(bindx,:) = best;   %replace it with the worst
end

[bval,bindx] = max(startPop(:,xZomeLength)); %得到最优的个体,并显示
if display
  fprintf(1,'\n%d %f\n',gen,bval);  
end

x=startPop(bindx,:); %得到当代的最优解
if opts(2)==0 %binary,如果是二进制编码,得到他的浮点数表示形式
  x=b2f(x,bounds,bits);
  bPop(bFoundIn,:)=[gen b2f(startPop(bindx,1:numVar),bounds,bits)...
      startPop(bindx,xZomeLength)];
else
  bPop(bFoundIn,:)=[gen startPop(bindx,:)];
end

if collectTrace %记录下来遗传的轨迹
  traceInfo(gen,1)=gen;   %current generation
  traceInfo(gen,2)=startPop(bindx,xZomeLength); %Best fittness
  traceInfo(gen,3)=mean(startPop(:,xZomeLength)); %Avg fittness
end

posted on 2006-07-20 14:58  Tutuya  阅读(4289)  评论(1)    收藏  举报