You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
GA error "your fitness function must return a scalar value"
6 views (last 30 days)
Show older comments
Hi all,
I am trying to use GA to minimize a function which is like this:
f=@(x) ((0.0011*(x(2:180)-x(1:179)))'*exp(-0.0078*x(Battery_num*180+1:Battery_num*180+179)))*Battery_cost/20+(0.0011*(x(182:360)-x(181:359)))'*exp(-0.0078*x(Battery_num*180+179+1:Battery_num*180+358))*Battery_cost/20+...
(0.0011*(x(362:540)-x(361:539)))'*exp(-0.0078*x(Battery_num*180+359:Battery_num*180+537))*Battery_cost/20+(0.0011*(x(542:720)-x(541:719)))'*exp(-0.0078*x(Battery_num*180+538:Battery_num*180+716))*Battery_cost/20+...
(0.0011*(x(722:900)-x(721:899)))'*exp(-0.0078*x(Battery_num*180+717:Battery_num*180+895))*Battery_cost/20+
(0.0011*(x(902:1080)-x(901:1079)))'*exp(-0.0078*x(Battery_num*180+896:Battery_num*180+1074))*Battery_cost/20+...
(0.0011*(x(1082:1260)-x(1081:1259)))'*exp(-0.0078*x(Battery_num*180+1075:Battery_num*180+1253))*Battery_cost/20;
however I get an error (after a long time), "Your fitness function must return a scalar value".
The problem is that the function f(x) gives a scalar value when I call it in the command window, so I don't understand why I get this error
any ideas?
thanks in advance
Nikolas
Accepted Answer
Geoff Hayes
on 3 Apr 2018
Nikolas - your objective function must return a scalar value. In the above, f is returning a matrix instead of the scalar. If I evaluate your f with some dummy data, then this function returns a 179x179 matrix. A scalar is needed so that the GA can compare the fitness of one member of the population against all other members...
21 Comments
Nikolas Spiliopoulos
on 3 Apr 2018
thanks for the answer, however I don't get it why is a matrix
i tried this putting random data in the function above:
Battery_num=7;
Battery_cost=1200;
x=ones(2513,1);
x(1:100,1)=10;
x(101:200,1)=20;
x(201:500,1)=100;
x(501:end)=300;
then I type f(x) and I get a value of 1.8437
many thanks
Nikolas
Geoff Hayes
on 3 Apr 2018
I guess it all depends on your x. If I change this to
x=ones(1,2513);
then the answer is a 179x179 matrix. Are you sure that the x being provided to your fitness function is a column and not a row?
Nikolas Spiliopoulos
on 3 Apr 2018
alright I see,
I had used fmicon before at the same problem so I was giving an initial vector for x like x=ones(2513,1). However with GA I assume it takes a random initial set on its own, so I don't set somewhere a value for x.
correct me if I'm wrong
thanks again
Nikolas
Nikolas Spiliopoulos
on 3 Apr 2018
Actually, I don't give an initial population by myself
I thought matlab does it itself
probably if I give an initial population in this x=ones (2513,1) will solve the problem? thanks
Geoff Hayes
on 4 Apr 2018
You may want to define a function to create your initial population. I suspect that you are just setting nvars (see number of variables to 2513 and then MATLAB is generating a 1x2513 array. Rather than using an anonymous function, you could create one that would guard against this problem
function [fitness] = myGAFunction(x)
if isrow(x)
x = x';
end
fitness = ((0.0011*(x(2:180)-x(1:179)))'*exp(-0.0078*x(Battery_num*180+1:Battery_num*180+179)))*Battery_cost/20+(0.0011*(x(182:360)-x(181:359)))'*exp(-0.0078*x(Battery_num*180+179+1:Battery_num*180+358))*Battery_cost/20+...
(0.0011*(x(362:540)-x(361:539)))'*exp(-0.0078*x(Battery_num*180+359:Battery_num*180+537))*Battery_cost/20+(0.0011*(x(542:720)-x(541:719)))'*exp(-0.0078*x(Battery_num*180+538:Battery_num*180+716))*Battery_cost/20+...
(0.0011*(x(722:900)-x(721:899)))'*exp(-0.0078*x(Battery_num*180+717:Battery_num*180+895))*Battery_cost/20+…
(0.0011*(x(902:1080)-x(901:1079)))'*exp(-0.0078*x(Battery_num*180+896:Battery_num*180+1074))*Battery_cost/20+...
(0.0011*(x(1082:1260)-x(1081:1259)))'*exp(-0.0078*x(Battery_num*180+1075:Battery_num*180+1253))*Battery_cost/20;
end
I'm assuming that the above function is nested within your main function and so has access to the battery_* variables.
Nikolas Spiliopoulos
on 4 Apr 2018
Edited: Nikolas Spiliopoulos
on 4 Apr 2018
Hi again, thanks for the reply. Yeah you're right I have set the nvars variable and matlab probably takes an array of 1x2513 instead of 2513x1.
However, being a beginner in matlab I don't really get it how should I write it in the script file. For the moment I have this:
f=@(x) ((0.0011*(x(2:180)-x(1:179)))'*exp(-0.0078*x(Battery_num*180+1:Battery_num*180+179)))*Battery_cost/20+(0.0011*(x(182:360)-x(181:359)))'*exp(-0.0078*x(Battery_num*180+179+1:Battery_num*180+358))*Battery_cost/20+...
(0.0011*(x(362:540)-x(361:539)))'*exp(-0.0078*x(Battery_num*180+359:Battery_num*180+537))*Battery_cost/20+(0.0011*(x(542:720)-x(541:719)))'*exp(-0.0078*x(Battery_num*180+538:Battery_num*180+716))*Battery_cost/20+...
(0.0011*(x(722:900)-x(721:899)))'*exp(-0.0078*x(Battery_num*180+717:Battery_num*180+895))*Battery_cost/20+(0.0011*(x(902:1080)-x(901:1079)))'*exp(-0.0078*x(Battery_num*180+896:Battery_num*180+1074))*Battery_cost/20+...
(0.0011*(x(1082:1260)-x(1081:1259)))'*exp(-0.0078*x(Battery_num*180+1075:Battery_num*180+1253))*Battery_cost/20;
options = gaoptimset('UseParallel',true,'Display','iter');
nvars=(N*Battery_num)+(N-1)*Battery_num;
[x,fval]=ga(f,nvars,A,b,Aeq,beq,lb,[],[],options);
can you please explain where i put the function? sorry for being a pain many thanks!!
Geoff Hayes
on 4 Apr 2018
Hi Nikolas - if we nest our objective function within the main function like
function myGAOptimization
Battery_num = 42;
Battery_cost= 24;
% other variables like A, b, etc.
function [fitness] = myGAFunction(x)
if isrow(x)
x = x';
end
fitness = ((0.0011*(x(2:180)-x(1:179)))'*exp(-0.0078*x(Battery_num*180+1:Battery_num*180+179)))*Battery_cost/20+(0.0011*(x(182:360)-x(181:359)))'*exp(-0.0078*x(Battery_num*180+179+1:Battery_num*180+358))*Battery_cost/20+...
(0.0011*(x(362:540)-x(361:539)))'*exp(-0.0078*x(Battery_num*180+359:Battery_num*180+537))*Battery_cost/20+(0.0011*(x(542:720)-x(541:719)))'*exp(-0.0078*x(Battery_num*180+538:Battery_num*180+716))*Battery_cost/20+...
(0.0011*(x(722:900)-x(721:899)))'*exp(-0.0078*x(Battery_num*180+717:Battery_num*180+895))*Battery_cost/20+...
(0.0011*(x(902:1080)-x(901:1079)))'*exp(-0.0078*x(Battery_num*180+896:Battery_num*180+1074))*Battery_cost/20+...
(0.0011*(x(1082:1260)-x(1081:1259)))'*exp(-0.0078*x(Battery_num*180+1075:Battery_num*180+1253))*Battery_cost/20;
end
options = gaoptimset('UseParallel',true,'Display','iter');
nvars=(N*Battery_num)+(N-1)*Battery_num;
[x,fval]=ga(myGAFunction,nvars,A,b,Aeq,beq,lb,[],[],options);
end
and save it to a file called myGAOptimization.m it should work. (I don't have the Optimization toolkit so can't verify.) See the attached file for an example.
Stephen23
on 4 Apr 2018
Edited: Stephen23
on 4 Apr 2018
If the original function works for an Nx1 vector, but ga provides it with a 1xN vector, then one simple solution would be to add a simple wrapper to reshape the vector:
f = @(x)... ; % your original function
g = @(x) f(x(:)); % convert any x to a column
...
[x,fval] = ga(g,...);
Nikolas Spiliopoulos
on 4 Apr 2018
thanks for the answer,
it seems that I am getting the same result though
with some dummy data I 'm getting the same value for
f(x) and g(x)!
Nikolas Spiliopoulos
on 4 Apr 2018
I also tried the answer that Geoff suggested however I'm getting the error "not enough input arguments" although I put also battery_num and battery cost inputs :(
function [fitness] = myGAfunction(x,Battery_num,Battery_cost)
Geoff Hayes
on 4 Apr 2018
Nikolas - because myGAfunction is nested within the main function, then it has access to the Battery_num and Battery_cost variables that have been declared in the "parent" function. The error "not enough input parameters" is because you have defined your objective function with three input parameters when the GA is providing only one input parameter. Try using the attached code.
Nikolas Spiliopoulos
on 5 Apr 2018
Hi again,
I tried the attached code and still getting the same error that's why I put more input variables in the myGAfunction.
Literally don't know how to fix it
thanks very much for the comments, I really appreciate it!
Nikolas Spiliopoulos
on 5 Apr 2018
Edited: Nikolas Spiliopoulos
on 5 Apr 2018
I tried it again, So I manage to run it!
however I get the same error ("about scalar value") don't know why :(
Geoff Hayes
on 5 Apr 2018
Try putting a break point in the objective/fitness function and then run your code to see what the input dimensions are and if they make sense.
Nikolas Spiliopoulos
on 5 Apr 2018
Edited: Nikolas Spiliopoulos
on 5 Apr 2018
I did it, I have a vector of x=2513X1 but afterwards the Initial population in the options it's empty ([]). I tried to put x as Initial population but I think it only takes a row!
Geoff Hayes
on 5 Apr 2018
Well if you put x as the initial population, aren't you saying that the population only has one member?
Nikolas Spiliopoulos
on 5 Apr 2018
Yeah, the problem is I cannot put as an initial population a matrix [2513x200], I can only put a [200x2513] that how the problem comes. Because I think matlab reads the rows so finally my fitness function gives a matrix and not a scalar.
Geoff Hayes
on 5 Apr 2018
ok but if you put the breakpoint in the myGAFunction function what are the dimensions of the input? If a row instead of column, then just transpose it.
Nikolas Spiliopoulos
on 6 Apr 2018
Well I tried something else, I transpose my fitness function so now you can input a row like 1x2513 and you get a scalar (before I was taking a matrix 179x179).
So thank you very much for all these comments!
the problem now is that it takes ages, but I guess tha'ts another question
thanks again!!
More Answers (0)
See Also
Categories
Find more on Logical in Help Center and File Exchange
Tags
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)