# Error when using genetic algorithm

23 views (last 30 days)
Kah Wei on 29 Jul 2014
Answered: Geoff Hayes on 1 Aug 2014
Currently I am trying to use genetic algorithm to optimize the parameters of the controller. The optimized controller then is to be applied on a multivariable space robot. In the simulation process I encounter an error which bother me for quite some time and I cant find any solution about it.
I always receive the error message " Failure in user-supplied fitness function evaluation. GA cannot continue." when ever I try to activate the simulation.Anyone can kindly give me some advice on how to solve this error? The attachments are the program and the simulink model that I am using. The main file is "Main_Genetic_Algorithm.m"

Geoff Hayes on 30 Jul 2014
So you are saying that, the reason why I am encountering this error because my fitness function only accepts two inputs but I am having 11 variables that need to be optimized???I hope I get your point correct.
Not quite, Kah. The documentation for this function states that The fitness function should accept a row vector of length nvars and return a scalar value. So your fitness function, that which you are trying to minimize, can only accept a single row vector of length 11 (which is what you have set nvars to). Your fitness function, calculation_error, expects two row vectors and I think that is where you are experiencing the problem.
The GA is creating a population of 300 members, each of which starts with a random 1x11 vector of data that is taken from the interval (for each of the 11 variables) that you have provided. The GA then evaluates the fitness of each member by passing each member's vector into your fitness function. But your fitness function is expecting two vectors...not just the one.
Here's an example. Suppose I have the following fitness function for a function of three variables
function [val] = fitness_func(data)
x = data(1);
y = data(2);
z = data(3);
val = (x-1)^2 + (y-2)^2 + (z-3)^2;
So I want to find the minimum of the function (x-1)^2 + (y-2)^2 + (z-3)^2. So the GA creates a fixed-sized population of N members, assigns each a random vector of three variables (in whatever interval I have defined for each) and evolves a solution over successive generations/iterations. Ideally, at the end of X generations/iterations, one such solution would be x==1,y==2,z==3 as these three inputs produce the value of zero which is the minimum for this function.
Your fitness function must do something similar. Given the vector of 11 variables, it must evaluate in some manner to indicate if these variables "help" to minimize the function or not.
Just to see if we can get past the error, in the Main_Genetic_Algorithm.m file, replace
fitnessfunction = @calculation_error;
with
fitnessfunction = @(X)calculation_error(X,zeros(1,11));
This will allow you to use your calculation_error function with dummy data for the second input parameter. If the GA is just supplying the one input vector of 11 variables, then the above should work correctly...in the sense that we won't see the error, but you will get the wrong answer.
Kah Wei on 1 Aug 2014
Thanks Geoff.
I adopted your suggestion and I am not encountering the error mentioned anymore.I think I got the correct idea now on how to make the GA works in MATLAB.
I will need to modify the fitness function based on the example shown by you for my system.Thanks again Geoff for the guidance and spending time to answer my questions. :)
Geoff Hayes on 1 Aug 2014
Great, Kah - glad I was able to help! I'm going to summarize some of the findings in a solution (below) so that others will know what to look for if they encounter a similar problem.

Geoff Hayes on 1 Aug 2014
The error message Failure in user-supplied fitness function evaluation. GA cannot continue indicated that there was a problem with the fitness function, calculation_error. In Main_Genetic_Algorithm.m, the fitness function and options to the genetic algorithm were being set as
%Place function handle to the function above
fitnessfunction = @calculation_error;
%Number of variables to be optimized
nvar = 11;
%Perform optimization via genetic algorithm
%Set the settings for the genetic algorithm
%Define the population size, stall generation limit and plot functions
options = gaoptimset('PopulationSize',300,'StallGenLimit',100,'PlotFcns',
{@gaplotbestf,@gaplotstopping});
%Define the initial range for the variables
options = gaoptimset(options,'PopInitRange',[1.454 3.331 1.046 0.08953 1.335 2.435 0.5701 2.285
0.4707 0.7709 4.299;2.577 6.711 2.045 0.7713 3.811 3.484 0.944 4.478 0.7994 1.838 4.99]);
% options = gaoptimset(options,'PopInitRange',[1.454;2.577]);
%Define the information to be seen on the command window
options = gaoptimset(options,'Display','diagnose');
%Define the setting for the mutation
options = gaoptimset(options,'MutationFcn',{@mutationuniform,.1});
%Switch on vectorization
options=gaoptimset(options,'Vectorize','on');
%Set population type
options=gaoptimset(options,'PopulationType','doubleVector');
x = ga(fitnessfunction,nvar,[],[],[],[],[],[],[],[],options);
From the documentation on the input fitness function, see GA Fitness Function for details, it stated that
The fitness function should accept a row vector of length nvars and return a scalar value. When the 'Vectorized' option is 'on', fitnessfcn should accept a pop-by-nvars matrix, where pop is the current population size. In this case fitnessfcn should return a vector the same length as pop containing the fitness function values. fitnessfcn should not assume any particular size for pop, since ga can pass a single member of a population even in a vectorized calculation.
Given that the defined GA options included the Vectorize being set to on, then this would have meant that the calculation_error code should be expecting a matrix input rather than a vector. As this fitness function wasn't designed to handle a matrix, we removed the Vectorize set to on statement.
As well, the fitness function must only accept one input row vector of 11 variables (for each member of the population). The function signature for calculation_error was defined to be
function error = calculation_error(output1,output2)
with two inputs rather than the expected one. When we tested out the fitness function defined as
fitnessfunction = @(X)calculation_error(X,zeros(1,11));
with a dummy set of data for the second input, then the error (from before) was no longer evident.
A review of the fitness function is needed to ensure that it meets the requirements of the GA, and that is written in such a way that when provided an input (from any member within the population) then the output is such that it can be determined whether the input minimizes the function (or not).