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!
