Plot gaplotdistance in one plot for multiple runs of genetic algorithm
이전 댓글 표시
Dear all,
With the code below I managed to run the genetic algorithm multiple times.
gprMdl2 = fitrgp(X,Y1,'KernelFunction','squaredexponential','OptimizeHyperparameters','auto','HyperparameterOptimizationOptions',struct('AcquisitionFunctionName','expected-improvement-plus'));
for i = 1:3
options = optimoptions('ga','CrossoverFrac',0.9,'PopulationSize',50,'StallGen',50,'Generations',70,'PlotFcn', {'gaplotbestf','gaplotdistance'});
fun = @(X) [abs(((predict(gprMdl2,X)-MFR_exp)/MFR_exp))];
[x_opt, Obj, exitflag,output] = ga(fun,2,[],[],[],[],[0.1 0.1], [0.9 0.9],[],[],options);
end
With PlotFcn I will get the plot of the fitness value vs genration and the average distance vs generation (as shown below). How can I combine the plots of each run into one plot?

댓글 수: 7
Mario Malic
2020년 10월 28일
편집: Mario Malic
2020년 10월 28일
Hello,
You can make your own OutputFcn for ga that does what you want. You can do the plotting with plotyy function.
Tessa Kol
2020년 10월 28일
Mario Malic
2020년 10월 28일
편집: Mario Malic
2020년 10월 28일
First, backup the original gaplotdistance.m file and create your own, under different name and call that one.
In the case of PlotFcn, optimisation solver creates a figure on its own, outside of plot function, so in case of OutputFcn, you should do it prior to calling the solver and set a name or a tag so you can find it in the OutputFcn.
OptimAxes = axes(1)
set(OptimAxes, 'Name', 'CustomOptimPlot')
Regarding the custom output function: Actually plotyy is not recommended anymore, yyaxis should be used. In this example right yyaxis is considered to be gaplotbestf as it has additional case 'done'.
function state = gaplotdistance(options,state,flag)
%GAPLOTDISTANCE Averages several samples of distances between individuals.
% STATE = GAPLOTDISTANCE(OPTIONS,STATE,FLAG) plots an averaged distance
% between individuals.
%
% Example:
% Create an options structure that uses GAPLOTDISTANCE
% as the plot function
% options = optimoptions('ga','PlotFcn',@gaplotdistance);
%
% (Note: If calling gamultiobj, replace 'ga' with 'gamultiobj')
% Copyright 2003-2015 The MathWorks, Inc.
% Getting the handle for axes *** test if you can move this in case 'init'
Axes = findobj('Name', 'CustomOptimPlot')
% options for left - gaplotdistance.m
samples = 20;
choices = ceil(sum(options.PopulationSize) * rand(samples,2));
% options for right - gaplotbestf
if size(state.Score,2) > 1
msg = getString(message('globaloptim:gaplotcommon:PlotFcnUnavailable','gaplotbestf'));
title(msg,'interp','none');
return;
end
switch flag
case 'init'
yyaxis left
% Code for first PlotFcn
yyaxis right
% Code for second PlotFcn
case 'iter'
yyaxis left
% Code for first PlotFcn
yyaxis right
% Code for second PlotFcn
case 'done'
yyaxis right
% Code for second PlotFcn
end
There might be some options that interfere with each other, like titles and labels, so consider that as well.
Edit: I will update comment later on the saving the variables
Tessa Kol
2020년 10월 29일
Mario Malic
2020년 10월 29일
편집: Mario Malic
2020년 10월 29일
Unfortunately, I am not familiar with ga, if you're looking for all values of variable d, throughout all optimisations, this would be the way to do it.
function state = customgaplotdistance(options,state,flag)
%GAPLOTDISTANCE Averages several samples of distances between individuals.
% STATE = GAPLOTDISTANCE(OPTIONS,STATE,FLAG) plots an averaged distance
% between individuals.
%
% Example:
% Create an options structure that uses GAPLOTDISTANCE
% as the plot function
% options = optimoptions('ga','PlotFcn',@gaplotdistance);
%
% (Note: If calling gamultiobj, replace 'ga' with 'gamultiobj')
% Copyright 2003-2015 The MathWorks, Inc.
persistent testdist % change number 1
testdist(1,:) = [0 0]; % initialising the value
samples = 20;
choices = ceil(sum(options.PopulationSize) * rand(samples,2));
switch flag
case 'init'
population = state.Population;
distance = 0;
for i = 1:samples
d = population(choices(i,1),:) - population(choices(i,2),:);
distance = distance + sqrt( sum ( d.* d));
testdist(end+1,:) = d; % change number 2
end
plotDist = plot(state.Generation,distance/samples,'.');
set(gca,'xlimmode','manual','zlimmode','manual', ...
'alimmode','manual')
set(gca,'xlim',[1,options.MaxGenerations]);
set(plotDist,'Tag','gaplotdistance');
xlabel('Generation','interp','none');
ylabel('Average Distance');
title('Average Distance Between Individuals','interp','none')
case 'iter'
population = state.Population;
distance = 0;
for i = 1:samples
d = population(choices(i,1),:) - population(choices(i,2),:);
distance = distance + sqrt( sum ( d.* d));
testdist(end+1,:) = d; % change number 3
assignin('base', 'testdist', testdist) % it might be better to assign it and save it from the main file
% save('testdist.mat', 'testdist') % as it will save the file 3000+ times
end
plotDist = findobj(get(gca,'Children'),'Tag','gaplotdistance');
newX = [get(plotDist,'Xdata') state.Generation];
newY = [get(plotDist,'Ydata') distance/samples];
set(plotDist,'Xdata',newX,'Ydata',newY);
end
Mario Malic
2020년 10월 31일
편집: Mario Malic
2020년 10월 31일
Great to hear it works! Actually, I put the distance first, and then I thought, but it doesn't show every single distance out there, so I set it back to d.
채택된 답변
추가 답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 Install Products에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
