updatestate.m

来自「The Source of Genetic Programming develo」· M 代码 · 共 222 行

M
222
字号
function [state,pop]=updatestate(params,state,data,pop)
%UPDATESTATE    Updates the GPLAB algorithm state variables.
%   UPDATESTATE(PARAMS,STATE,POP) returns the state variables updated
%   with the latest measures of rank, fitness and level history.
%
%   [STATE,POP]=UPDATESTATE(PARAMS,STATE,POP) also returns some
%   additional population info that may have been needed.
%
%   Input arguments:
%      PARAMS - the running parameters (struct)
%      STATE - the state before the update (struct)
%      DATA - the dataset for the algorithm to use (struct)
%      POP - current population (array)
%   Output arguments:
%      STATE - the state after the update (struct)
%      POP - current population, updated info (array)
%
%   Copyright (C) 2003-2007 Sara Silva (sara@dei.uc.pt)
%   This file is part of the GPLAB Toolbox

% first measure fitness on any individuals still with empty fitness:
[pop,state]=calcpopfitness(pop,params,data,state);
state.popfitness=[pop.fitness];
state.popadjustedfitness=[pop.adjustedfitness];

% variable population size and generation gap:
% first check what proportion of population is gengap:
oldpopsize=state.popsize;
p=state.gengap/oldpopsize;
% update population size:
state.popsize=length(pop);
state.popsizehistory(end+1)=state.popsize;
% update generation gap:
state.gengap=max([round(p*state.popsize) 1]);
state.gengaphistory(end+1)=state.gengap;
% now update all the things that depend on pop size or gen gap:
% (tournament size:)
if params.tournamentsize<1 % tournamentsize is a proportion of popsize
    state.tournamentsize=max([round(params.tournamentsize*state.popsize) 2]);
end
% (adaptwindow size:)
oldadaptwindowsize=state.adaptwindowsize;
currentadaptwindowsize=length(state.adaptwindow);
% (old and current sizes may not match because adaptwindow may not be full)
p=oldadaptwindowsize/oldpopsize;
newadaptwindowsize=max([round(p*state.popsize) 1]);
if currentadaptwindowsize>newadaptwindowsize % if the population was reduced
    state.adaptwindow=state.adaptwindow(currentadaptwindowsize-newadaptwindowsize+1:end);
end
state.adaptwindowsize=newadaptwindowsize;

% ranking:
if params.lowerisbetter
   state.popranking=ranking(state.popadjustedfitness,0);
   % (use adjusted fitness because ranking is used in the selection process)
else
   state.popranking=ranking(state.popadjustedfitness,1);
end
% (ranking.m is used instead of sort so we can get rankings like 1,2,2,3,4,4,5,...)

% empty these so they are updated in the next generation (if needed):
state.popnormfitness=[];
state.popexpected=[];

% we will need nodes for various things, even if calccomplexity=0:
for i=1:state.popsize
    if isempty(pop(i).nodes)
        pop(i).nodes=nodes(pop(i).tree);
    end
end

if params.calccomplexity
	% average nodes, average introns, and average level (history):
	for i=1:state.popsize
        if isempty(pop(i).level)
        	pop(i).level=treelevel(pop(i).tree);
        end
        if isempty(pop(i).introns)
            [pop(i).introns,state]=intronnodes(pop(i).tree,params,data,state);
        end
	end
   
   poplevels=[pop.level];
   popnodes=[pop.nodes];
   popintrons=[pop.introns];
   
   state.avglevelhistory(end+1)=mean(poplevels);
   state.avgnodeshistory(end+1)=mean(popnodes);
   state.avgintronshistory(end+1)=mean(popintrons);
   
   % tree fill percentage:
   mlevel=max(poplevels);
   avgkids=mean(state.arity(find(state.arity>0)));
   avgkids=repmat(avgkids,state.popsize,mlevel);
   alllevels=repmat(0:1:mlevel-1,state.popsize,1);
   poplevels=repmat(poplevels',1,size(alllevels,2));
   avgkids(alllevels>=poplevels)=0;
   sumparts=avgkids.^alllevels;
   sumlines=sum(sumparts,2);
   fillratio=popnodes'./sumlines;
   state.avgtreefillhistory(end+1)=100*mean(fillratio);
end % if params.calccomplexity

% bestsofar and bestsofarhistory:
bestindex=find(state.popranking==1);
if length(bestindex)>1 % there may be more than one, in each case we choose the simpler
    minlevelindex=[];
    for i=1:length(bestindex)
        if strcmp(params.depthnodes,'1')
            if isempty(pop(bestindex(i)).level)
                pop(bestindex(i)).level=treelevel(pop(bestindex(i)).tree);
            end
            if isempty(minlevelindex) || pop(bestindex(i)).level<pop(minlevelindex).level
                minlevelindex=bestindex(i);
            end
        else
            if isempty(pop(bestindex(i)).nodes)
                pop(bestindex(i)).nodes=nodes(pop(bestindex(i)).tree);
            end
            if isempty(minlevelindex) || pop(bestindex(i)).nodes<pop(minlevelindex).nodes
                minlevelindex=bestindex(i);
            end
        end
    end
    bestindex=minlevelindex;
end

if isempty(state.bestsofar) || ((params.lowerisbetter && pop(bestindex).fitness<state.bestsofar.fitness) || (~params.lowerisbetter && pop(bestindex).fitness>state.bestsofar.fitness))
    state.bestsofar=pop(bestindex);
end

% cross validation (and save bestsofar.fitness and eventually bestsofar.testfitness):
if params.usetestdata
   testindividual=calcfitness(state.bestsofar,params,data.test,state,1); % (1 = test data)
   state.bestsofar.testfitness=testindividual.fitness;
   state.bestsofar.testadjustedfitness=testindividual.adjustedfitness;
   state.bestfithistory(end+1,:)=[state.bestsofar.fitness state.bestsofar.testfitness];
else   
   state.bestfithistory(end+1)=state.bestsofar.fitness;
end
if isempty(state.bestsofar.nodes)
   state.bestsofar.nodes=nodes(state.bestsofar.tree);
end
if isempty(state.bestsofar.introns)
   [nintrons,state]=intronnodes(state.bestsofar.tree,params,data,state);
   state.bestsofar.introns=nintrons;
end
if isempty(state.bestsofar.level)
   state.bestsofar.level=treelevel(state.bestsofar.tree);
end
if isempty(state.bestsofarhistory) || (state.bestsofar.id~=state.bestsofarhistory{end,2}.id)
   state.bestsofarhistory{end+1,1}=state.generation;
   state.bestsofarhistory{end,2}=state.bestsofar;
end

% get maximum, minimum, average, median, stddev fitness:
if params.lowerisbetter
   state.maxfitness=min(state.popfitness);
   state.minfitness=max(state.popfitness);
else
   state.maxfitness=max(state.popfitness);
   state.minfitness=min(state.popfitness);
end
state.avgfitness=mean(state.popfitness);
if isempty(state.bestavgfitnesssofar) || ((params.lowerisbetter)&&(state.avgfitness<state.bestavgfitnesssofar)) || ((~params.lowerisbetter)&&(state.avgfitness>state.bestavgfitnesssofar))
   state.bestavgfitnesssofar=state.avgfitness;
end
state.medianfitness=median(state.popfitness);
state.stdfitness=std(state.popfitness);

% save fitness measures in fithistory:
g=state.generation+1; % +1 because generation 0 is also saved
state.fithistory(g,1)=state.maxfitness;
state.fithistory(g,2)=state.minfitness;
state.fithistory(g,3)=state.avgfitness;
state.fithistory(g,4)=state.medianfitness;
state.fithistory(g,5)=state.stdfitness;

% save level, best level, best introns, op and op freqs history:
state.levelhistory(end+1)=state.maxlevel;
state.bestlevelhistory(end+1)=state.bestsofar.level;
state.bestnodeshistory(end+1)=state.bestsofar.nodes;
state.bestintronshistory(end+1)=state.bestsofar.introns;
state.ophistory(end+1,:)=state.operatorprobs;
state.opfreqhistory(end+1,:)=state.operatorfreqs;
state.reproductionhistory(end+1)=state.reproductions;
state.cloninghistory(end+1,:)=state.clonings;
state.reproductions=0;
state.clonings=zeros(1,length(params.operatornames));

% record natural resources values:
if isempty(state.maxresources)
   % if no value was given yet, the maximum resources are
   % the amount used by the initial population
   for i=1:state.popsize
   	  if isempty(pop(i).nodes)
      	pop(i).nodes=nodes(pop(i).tree);
      end
   end
   state.maxresources=sum([pop.nodes]);
end
state.usedresources=sum([pop.nodes]);
state.maxresourceshistory(end+1)=state.maxresources;
state.usedresourceshistory(end+1)=state.usedresources;

% diversity:
for i=1:length(params.calcdiversity)
   newdiversity = feval(params.calcdiversity{i},params,state,data,pop);
   eval(['state.diversityhistory.' params.calcdiversity{i} '(end+1)=newdiversity;']);
end

   % just to remind,
   % the simple measure from population genetics:
   
   %popindividuals={pop.str};
   %uniqueindividuals=unique(popindividuals);
   %reppopindividuals=repmat(popindividuals',1,length(uniqueindividuals));
   %repuniqueindividuals=repmat(uniqueindividuals,1,length(popindividuals))';
   %uniquematch=strcmp(reppopindividuals,repuniqueindividuals);
   %uniquefreqs=sum(uniquematch,1)/state.popsize;
   %state.diversityhistory(end+1)=1-(sum(uniquefreqs.*uniquefreqs));
   

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?