Erroneous error: Index exceeds the number of array elements. Index must not exceed 0. Any idea on how to fix this problem?

1 view (last 30 days)
Hey guys I am having a problem with a Matlab code of mine. The code is a genetic alogrithm that should find the parameters a1, a2, a3, b1, b2, b3 for this following function:
The code is composed of a main function called GAFunctionFinder.m and 6 functions that the main script calls, as following:
GAFunctionFinder.m
populationSize = 100; % modify as desired (but should be even)
numberOfGenerations = 10000; % modify as desired
maximumParameterValue = 2; % parameters range from -2 to 2 (do not change)
tournamentProbability = 0.75; % modify as desired
crossoverProbability = 0.75; % modify as desired
mutationProbability = 0.125; % modify as desired
creepProbability = 0.5; % modify as desired
creepRate = 0.01; % modify as desired
functionData = LoadFunctionData();
format long
numberOfParameters = 6;
bestIndividual = zeros(numberOfParameters, 1); %% Best values of the a_i and b_i parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Initialize population
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
population = InitializePopulation(populationSize, numberOfParameters);
fitness = zeros(populationSize,1);
maximumFitness = 0.0;
for iGeneration = 1:numberOfGenerations
maximumFitnessInCurrentGeneration = 0;
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Evaluate individuals
%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i = 1:populationSize
chromosome = population(i,:);
fitness(i) = EvaluateIndividual(chromosome,functionData); %% Write this function
if (fitness(i) > maximumFitnessInCurrentGeneration)
maximumFitnessInCurrentGeneration = fitness(i);
iBestIndividual = i;
if (fitness(i) > maximumFitness)
maximumFitness = fitness(i);
bestIndividual = chromosome;
fprintf('%d %12.8f\n',iGeneration, maximumFitness);
end
end
end
%% Add plot of maximum fitness, either here or at the end of the
%% run. In the latter case, at least make sure to store the
%% maximum fitness for each generation, so that you can later make the plot.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Generate new population, unless the last generation has been evaluated
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (iGeneration < numberOfGenerations)
temporaryPopulation = population;
for i = 1:2:populationSize
i1 = TournamentSelect(fitness,tournamentProbability); %% Write this function
i2 = TournamentSelect(fitness,tournamentProbability); %% Write this function
r = rand;
if (r < crossoverProbability)
chromosome1 = population(i1,:);
chromosome2 = population(i2,:);
newIndividualPair = Cross(chromosome1, chromosome2); %% Write this function
temporaryPopulation(i,:) = newIndividualPair(1,:);
temporaryPopulation(i+1,:) = newIndividualPair(2,:);
else
temporaryPopulation(i,:) = population(i1,:);
temporaryPopulation(i+1,:) = population(i2,:);
end
end
temporaryPopulation(1,:) = population(iBestIndividual,:); %% Elitism, prevents maximum fitness from decreasing.
for i = 2:populationSize
originalChromosome = temporaryPopulation(i,:);
mutatedChromosome = Mutate(originalChromosome, mutationProbability,creepProbability,creepRate); %% Write this function
temporaryPopulation(i,:) = mutatedChromosome;
end
population = temporaryPopulation;
end
end
LoadFunctionData.m:
function functionData = LoadFunctionData
functionData = load('data_ga.txt')
InitializePopulation.m:
function population = InitializePopulation(populationSize, numberOfParameters)
population = -2 + (4*rand(populationSize, numberOfParameters));
end
EvaluateIndividual.m:
function fitness = EvaluateIndividual(chromosome, functionData)
% This function generates (as output) the fitness value; see the problem
% formulation for details. Note: It is not always a good idea to pass a data
% set as a parameter, but here the data set is small, so it is OK.
g = @(x,y) (1+chromosome(1)*x+chromosome(2)*x.^2+chromosome(3)*x.^3) ./ ...
(1+chromosome(4)*y+chromosome(5)*y.^2+chromosome(6)*y.^3);
f = @(g,g_hat) sqrt(mean((g - g_hat).^2));
x = functionData(:,1);
y = functionData(:,2);
g_hat = g(x,y);
g_true = functionData(:,3);
fitness = exp(-f(g_true, g_hat));
end
TournamentSelect.m
function selectedIndex = TournamentSelect(fitness, tournamentProbability)
populationSize = length(fitness);
tournamentSize = 2;
tournamentWinners = zeros(1, tournamentSize);
for i = 1:tournamentSize
candidates = randperm(populationSize, tournamentSize);
candidateFitnesses = fitness(candidates);
[~, winnerIndex] = max(candidateFitnesses);
tournamentWinners(i) = candidates(winnerIndex);
end
selectedIndex = tournamentWinners(rand < tournamentProbability) ;
end
Cross.m
function newIndividualPair = Cross(chromosome1, chromosome2)
n = length(chromosome1);
crossoverPoint = randi([2, n-1]); % Ensure that crossover point is not too close to the ends
offspring1 = [chromosome1(1:crossoverPoint) chromosome2(crossoverPoint+1:end)];
offspring2 = [chromosome2(1:crossoverPoint) chromosome1(crossoverPoint+1:end)];
newIndividualPair=[offspring1;offspring2];
end
Mutate.m
function mutatedChromosome = Mutate(originalChromosome, mutationProbability, creepProbability, creepRate)
% originalChromosome: the chromosome to be mutated
% mutationProbability: the probability of each gene being mutated
% creepProbability: the probability of a gene undergoing a creep mutation
% creepRate: the magnitude of the creep mutation
% Get the chromosome length
chromLen = length(originalChromosome);
% Initialize the mutated chromosome
mutatedChromosome = originalChromosome;
% Loop through all genes in the chromosome
for i = 1:chromLen
% Check if the gene should be mutated
if rand < mutationProbability
% Decide whether to do a creep mutation or full-range mutation
if rand < creepProbability
% Creep mutation
mutatedChromosome(i) = mutatedChromosome(i) + creepRate * (rand - 0.5);
else
% Full-range mutation
mutatedChromosome(i) = rand;
end
end
end
So without getting into too much details, the error I am getting has to do with the cross function. When I run the code from the main script I basically get two types of error:
Unable to perform assignment because the size of the left side is 1-by-6 and the size of the right side is 0-by-6.
Error in GAFunctionFinder (line 104)
temporaryPopulation(i+1,:) = population(i2,:);
%%%%OR
Index exceeds the number of array elements. Index must not exceed 0.
Error in Cross (line 38)
offspring2 = [chromosome2(1:crossoverPoint) chromosome1(crossoverPoint+1:end)];
Error in GAFunctionFinder (line 99)
newIndividualPair = Cross(chromosome1, chromosome2); %% Write this function
This is a bit confusing as without changing anything in the code I am getting two different errors depending on the run. The error is not in the main files as I've been handed this script. The error should be in the cross function. Although I have used different approaches to solve this problem, I am still getting the same errors over and over again. So in this cross function below, I have tried changing IMIN in the randi from 2 to 1, without any luck. Also, what this functions does, in short terms, is that it randomly select a crossover point, and this crossover point is then used to generate a new pair of chromosomes called offsprings.
function newIndividualPair = Cross(chromosome1, chromosome2)
n = length(chromosome1);
crossoverPoint = randi([2, n-1]); % Ensure that crossover point is not too close to the ends
offspring1 = [chromosome1(1:crossoverPoint) chromosome2(crossoverPoint+1:end)];
offspring2 = [chromosome2(1:crossoverPoint) chromosome1(crossoverPoint+1:end)];
newIndividualPair=[offspring1;offspring2];
end
If anyone has an idea, it would be greatly appreciated!

Answers (1)

Torsten
Torsten on 23 Apr 2023
Moved: Cris LaPierre on 24 Apr 2023
rand < tournamentProbability becomes "false" for all elements of "tournamentProbability" in "TournamentSelect". Thus the output of the function is empty.

Categories

Find more on Genomics and Next Generation Sequencing in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!