Genetic Algorithm - Your fitness function must return a scalar value solution?

7 views (last 30 days)
Hello everyone,
I have been working on my GA code for some time. Have been getting some weird results with my code so I tried to implement it with example from documentation (https://www.mathworks.com/help/gads/constrained-minimization-using-ga.html). It seems that my fitness function is badly coded and is not returning scalar value. Therefore, the algorithm is unable to compare solutions and the code stops. I have pinpointed the problem - loading data inside function. Data are, among other, drive cycle (speed and acceleration - both 1x661 matrix). So my fitness function returns 1x661 matrix.
So my GA is not for optimizing a function of two variables, but optimizing a function of two variables at every instant of drive cycle (661 instances).
How can I load my drive cycle data (podaci_matlab.mat) in "one-by-one" manner so I can get a scalar value?
I have attached all necessary files.
Thanks in advance !
  1 Comment
Ste_M
Ste_M on 12 Jun 2022
Yes, interp2 will return an array if input queries are arrays. I was thinking about inputing scalar values as query points. Which means that data should be loaded one-by-one or be sorted out in some way.
Query points are functions of x1 and x2 as follows:
Te = f(x2)
ne = f(x1,x2)
Surface plot of inital data (surface map from which the code extracts y) is ploted in 2D and 3D (attachments).
Just for the record, to make it more clear. The aim of the code is to find optimal values of x(1) and x(2) such that y is minimized. Data for y is imported as a surface map y = f(ne,Te) where ne = f(x(1), x(2)) and Te = f(x(2)). Physical explanation is fuel consumption of a vehicle where x(1) and x(2) are variables in powertrain (gear ratio and motor speed). The problem is that I need to load drive cycle (speed and acceleration arrays) in order to calculate Te and ne. How can I import speed and acceleration data one element at a time efficiently so that ga doesnt jam with array output is the question here.

Sign in to comment.

Accepted Answer

Alan Weiss
Alan Weiss on 12 Jun 2022
I am not sure what you are trying to do. Your objective function has 661 components. Are you trying to solve for 661 different values of x(1) and x(2)? If so, you should write a loop and solve 661 different problems.
Or are you trying to use the same x(1) and x(2) for all 661 objectives? In that case, your problem is not well-defined. Undoubtedly, some values of x will optimize the first objective, but different values will optimize other objectives.
I did not talk about your constraints, but if you can answer the first question, then I would imagine that you can figure out if you have 661 different problems and you have potentially different constraints for each problem, or if you have a huge multiobjective problem.
You should definitely NOT call load within the loop, if as I suspect you have 661 different problems. Load the data once and then pass it into the loop.
And one more thing. It seems that your x(2) variable takes just five values. You should not use interpolation for this. Instead, you should declare x(2) to be integer-valued with lower bound 1 and upper bound 5, and then use roundTargets(round(x(2)) as the value. (I threw the round function in case x(2) is not exactly an integer. It might be superfluous.)
Good luck,
Alan Weiss
MATLAB mathematical toolbox documentation
  2 Comments
Ste_M
Ste_M on 12 Jun 2022
It is the first case, solving 661 different problems with different values for x(1) and x(2) for each instance.
I tried the loop with nested function. I loaded the data in the main app so I can feed it into the function. ObjectiveFunction seems to work, but ConstraintFunction does not. ConstraintFunction has two outputs, but for some reason I can not set up my parent function to have two outputs so the code won't run. Any advice or suggestion? The files are attached.
Maybe the mistake is in the entire nested function setup. I am not really experienced in matlab but I could say that the entire code looks kinda weird...
Alan Weiss
Alan Weiss on 13 Jun 2022
Edited: Alan Weiss on 13 Jun 2022
I am not sure that I got everything correct here, but you might find this code easier to follow and more correct than yours:
load podaci_matlab.mat %loads speed, acceleration, rpm, torque, fuelmap
% Define everything possible before the loop
N = length(vektor_brzine);
lb = [ -1800, 1]; % Lower bounds
ub = [1800 5]; % Upper bounds
% Arrays to hold solutions
sol = zeros(N,2);
fv = zeros(N,1);
roundTargets = [0.571048 0.833183 1.240949 1.842006 3.908194];
intcon = 2; % x(2) is integer
nvars = 2;
options = optimoptions('ga','Display','none','PlotFcn',@gaplotbestf);
rng default % For reproducibility
%% For loop
for i = 1:N
brzina = vektor_brzine(i);
ubrzanje = vektor_ubrzanja(i);
fun = @(x)objfun(x,brzina,ubrzanje,broj_obrtaja,obrtni_moment,gorivo,roundTargets);
nlcon = @(x)confun(x,brzina,ubrzanje,roundTargets);
[x,fval] = ga(fun,nvars,[],[],[],[],lb,ub, ...
nlcon,intcon,options);
fv(i) = fval;
sol(i,:) = x;
end
function y = objfun(x,brzina,ubrzanje,broj_obrtaja,obrtni_moment,gorivo,roundTargets)
x2 = roundTargets(round(x(2)));
wpt = brzina / 0.2577;
wptv = ubrzanje / 0.2577;
Tpt = (1330 + 0.58 * wpt^2 + 13850 * wptv) * 0.3;
To = Tpt / 5.786;
Th = To * (1+1/2.546);
Te = Th / x2;
wc = wpt * 5.786;
no = 30 * wc/pi;
nh = (x(1) + no*2.546)/(1+2.546); %parametar planetarnog prenosnika
ne = nh * x2;
y = interp2(broj_obrtaja, obrtni_moment, gorivo, ne, Te);
end
function [c,ceq] = confun(x,brzina,ubrzanje,roundTargets)
ceq = [];
x2 = roundTargets(round(x(2)));
wpt = brzina / 0.2577;
wptv = ubrzanje / 0.2577;
c = [ 700 - (x2 * (x(1) + 30 * (wpt * 5.786)/pi*2.546)/(1+2.546));
x2 * (x(1) + 30 * (wpt * 5.786)/pi*2.546)/(1+2.546) - 2500;
-(((1330 + 0.58* wpt ^ 2 + 13850* wptv) .* 0.3) / 5.786) * (1+1/2.546) / x2;
(((1330 + 0.58* wpt ^ 2 + 13850* wptv) * 0.3) / 5.786) * (1+1/2.546) / x2 - 1250;];
end
Alan Weiss
MATLAB mathematical toolbox documentation

Sign in to comment.

More Answers (0)

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!