フィルターのクリア

I have two problems in my code: 1 - Genetic algorithm gets “stuck” in the first generation. 2 – lsqcurvefit is unable to fix it. Can anyone, please, help me?

13 ビュー (過去 30 日間)
Hello, I am trying to minimize the error between 2 curves using the least squares method. To accomplish that I am using a two-step fitting procedure with the GA and the lsqcurvefit. I have some kind of issue that I cannot fix: The genetic algorithm gets stuck in the first generation, i.e. the stopping criteria is always the stall generation number, no matter the changes I make in my code. As for the lsqcurvefit, I was hoping that this procedure could go around this GA issue but I was mistaken. Probably I am badly using the gaoptimset and optimset options, but I can’t figure it out what is missing. Many thanks in advance for any help.
I have 9 variables that I need to optimize. For each variable I have gave it a lower and an upper bound.
% Lower bound
LB = horzcat(15,5,20,1E5,1,1E7,0,0,0);
% Upper bound
UB = horzcat(25,15,40,1E7,1E2,1E8,1,1,1);
I am trying in a test case and I know that the optimal values are, in the same order:
19.1, 10.0, 31.0, 2E6, 4, 6.5E7, 0, 1, 0
GA code:
delta = @FittingObj.Fitting_GA;
nvars = numel(LB);
options_GA = gaoptimset('PlotFcn',{@gaplotrange,@gaplotbestf,@gaplotdistance});
options_GA = gaoptimset(options_GA,'PopInitRange',[LB;UB]);
options_GA = gaoptimset(options_GA,'Generations',150,'StallGenLimit',20);
options_GA = gaoptimset(options_GA,'PopulationSize',20);
% I tried both the 'StallGenLimit' and the 'PopulationSize' with 100 and the result is the same
options_GA = gaoptimset(options_GA,'SelectionFcn',{@selectiontournament,4});
options_GA = gaoptimset(options_GA,'CrossoverFcn',{@crossoverscattered});
options_GA = gaoptimset(options_GA,'MutationFcn',{@mutationuniform,0.10});
options_GA = gaoptimset(options_GA,'Display','iter');
% Run the GA solver.
[y,opt_delta_GA] = ga(delta,nvars,[],[],[],[],LB,UB,[],options_GA);
% And my objective function is:
function delta_GA = Fitting_GA(fit,y)
fE2 = y(1);
fE3 = y(2);
fE4 = y(3);
fA2 = y(4);
fA3 = y(5);
fA4 = y(6);
fb2 = y(7);
fb3 = y(8);
fb4 = y(9);
fit.ReWriteFile(fE2,fE3,fE4,fA2,fA3,fA4,fb2,fb3,fb4);
fit.pyr.InitPyrolysis();
fit.pyr.RunPyrolysis();
fit.RearrangeDimensions();
delta_2D = zeros(1,fit.pyr.NI);
delta_2D(1:fit.pyr.NI) = (fit.wt_loss_ref(1:fit.pyr.NI)-fit.pyr.wt_loss(1:fit.pyr.NI)).^2;
delta_1D = sum(delta_2D);
fit.delta_wt_loss = (fit.pyr.NI^(-1)*delta_1D)^(1/2);
delta_GA = log(1+10*fit.delta_wt_loss);
end
lsqcurvefit code:
% Run LSQ solver.
X0 = y(1:nvars);
options_LSQ = optimset('MaxFunEvals',1E5,'MaxIter',1E5);
[x,fit_error] = lsqcurvefit(@FittingObj.Fitting_LSQ,X0,PyrolysisObj.solver.x,FittingObj.wt_loss_ref,LB,UB,options_LSQ);
opt_delta = sqrt(fit_error/PyrolysisObj.NI);
% And my objective function is:
function mp = Fitting _LSQ(fit,x,~)
fE2 = x(1);
fE3 = x(2);
fE4 = x(3);
fA2 = x(4);
fA3 = x(5);
fA4 = x(6);
fb2 = x(7);
fb3 = x(8);
fb4 = x(9);
fit.ReWrite(fE2,fE3,fE4,fA2,fA3,fA4,fb2,fb3,fb4);
fit.pyr.InitPyrolysis();
fit.pyr.RunPyrolysis();
mp = fit.pyr.wt_loss(1:fit.pyr.NI);
end
and I get:
Initial point is a local minimum. Optimization completed because the size of the gradient at the initial point is less than the default value of the function tolerance.
And this is both the GA and lsqcurvefit optimum result:
15, 5, 20, 1E5,1,1E7,0,0.5528,1 (the first variables set chosen by GA)
I saved all the GA data in a .txt file that is attached.

採用された回答

Alan Weiss
Alan Weiss 2017 年 1 月 16 日
It is possible that lsqcurvefit gets stuck because you are trying to optimize a simulation: the tiny finite difference steps that lsqcurvefit makes in trying to estimate a gradient can lead to the simulation not changing its results at all. For suggestions about optimizing a simulation, see Optimizing a Simulation or ODE, especially the suggestions on finite differences.
Of course, I am just guessing, you didn't say that you were trying to optimize a simulation, it just looks that way to me.
And might I suggest that once you get lsqcurvefit working, ditch ga, and to find a global minimum, just run lsqcurvefit starting from multiple random points in the bounds, such as
x0 = lb + rand(size(lb)).*(ub-lb);
You could even just use MultiStart to do that.
Good luck,
Alan Weiss
MATLAB mathematical toolbox documentation
  6 件のコメント
Isabel
Isabel 2017 年 1 月 19 日
Thank you for everything :)
Isabel
Isabel 2017 年 1 月 20 日
To whom it may interest, I managed to solve the problem with the cleanup() function.
It is my first line of code in the ODE function:
function dydt = FunctionOde(pyr,t,y)
cleanup();
pyr.biopyrolysis = IdealGasMix('biomass_K.xml');
%...
end

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeSolver Outputs and Iterative Display についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by