GA stepGA - 索引超出矩阵维度

GA stepGA - Index exceeds matrix dimensions

我正在为混合整数问题编写 MATLAB 中的自定义 GA 函数。更多关于我的问题 here and here

轮盘选择结束后,Matlab报错:

 Index exceeds matrix dimensions.

Error in stepGA (line 34)
xoverKids  = feval(options.CrossoverFcn, parents(1:(2 * nXoverKids)),options,GenomeLength,FitnessFcn,thisScore,thisPopulation,options.CrossoverFcnArgs{:});

Error in galincon (line 62)
        [score,population,state] = stepGA(score,population,options,state,GenomeLength,FitnessFcn);

Error in ga (line 374)
            [x,fval,exitFlag,output,population,scores] = galincon(FitnessFcn,nvars, ...

它在 stepGA.m 中断:

xoverKids  = feval(options.CrossoverFcn, parents(1:(2 * nXoverKids)),options,GenomeLength,FitnessFcn,thisScore,thisPopulation,options.CrossoverFcnArgs{:});

更准确地说 parents(1:(2 * nXoverKids))

当时我的变量

nXoverKids = 7
nParents = 16
nEliteKids = 1
nMutateKids = 2
parents = 1 1

我的轮盘选择:

function parents = RouletteWheelSelection(expectation, nParents, options)
% ---------------------------------------------------------
% Roulette Wheel Selection Algorithm. A set of weights
% represents the probability of selection of each
% individual in a group of choices. It returns the chosen chromosome.
% ---------------------------------------------------------
  r1 = rand;
  r2 = rand;
  index1 = sum(r1 >= cumsum([0, expectation']));
  index2 = sum(r2 >= cumsum([0, expectation']));

  parents = [index1, index2];
end

来自 Matlab documentation:

The function returns parents, a row vector of length nParents containing the indices of the parents that you select.

我从选择中返回错误吗?为什么 nParents 设置为 16

我对 GA 的其他选择:

options = gaoptimset(...
                      'PopulationSize',    10, ...
                      'Generations',       50, ...
                      'InitialPopulation', population.chromosomes(1,:),...
                      'SelectionFcn',      @RouletteWheelSelection, ...
                      'CrossoverFcn',      @Crossover, ...
                      'MutationFcn',       @Mutation
                     );
lb = 1;  % Lower bound on x
ub = 3;  % Upper bound on x
nvars = 81;

rules = population.chromosomes(1, :);



 x = ga(@(x)GaFitness(rules, sim_obj, EV_input_time_first, EV_input_time_second, inpxpath, layxpath, Results),...
       nvars,[],[],[],[],lb,ub,[],[],options);    

还有我的 InitialPopulation population.chromosomes(1,:)1x81 尺寸.

  • RouletteWheelSelection doesn't return parents with 2 individuals
  • 假设人口包含10个人
  • RouletteWheelSelection 期间,系统会要求您从 10 中选择 nParents,例如 5

Obviously nParents should not exceed PopulationSize

You have set nParents = 16 while PopulationSize = 10

  • 正确的词应该是 nIndividuals 而不是 nParents
  • expectation表示概率,一个介于0和1之间的值,也叫relative fitness
expectation(individual_1) = fitness(individual_1)/sum(fitness(ALL_individuals)); 

ga参数设置示例

% lower bound
lb = -2;
% upper bound
ub = 2;

% Population size
individuals = 10;
% Fitness function
fitness = @(x) -x.^2;

% Given population, 10 individuals

pop = linspace(lb, ub, individuals);

% All Population individuals Fitness
pop_fitness = fitness(pop);

% All Population individuals relative Fitness 
rfit = pop_fitness./sum(pop_fitness);

% All Population individuals cumulative fitness, sum up to 1
cumulative_relative_fit = cumsum(rfit);

% Number of individuals to be selected out of 10
nparents = 5;
sel = zeros(1, nparents);

% Indices of individuals in population
index = 1:numel(pop);

% Roulette Wheel Selection starts here

for i = 1 : nparents
    rnd = rand;
if rnd <=  cumulative_relative_fit(1)
    % Selected the first individual 
    % if first Cumulative relative fitness is higher than
    % generated random number 
    sel(i) = 1;
else
     % Find indices where generated random number is higher than 
     % Cumulative relative fitness
     ind = rnd >=  cumulative_relative_fit;
     
     
     ALL_Indices_Above_Cum = index(ind);
     % Choose the one with the highest Cumulative relative fitness
     sel(i) = ALL_Indices_Above_Cum(end);
end

end

已选个人

nParents = 5;
Population Size = 10;
sel = [4     9     1     7     1];

Change your custom selection function to this

function parents = RouletteWheelSelection(expectation, nParents, 'ga')
% ---------------------------------------------------------
% Roulette Wheel Selection Algorithm. A set of weights
% represents the probability of selection of each
% individual in a group of choices. It returns the chosen chromosome.
% ---------------------------------------------------------
    % Population individuals indices
    index = 1 : numel(expectation);
    
    % Indices of individuals to be selected 
    parents = zeros(1, nParents);

    % Cumulative relative fitness, the last one is 1
    cumulative_relative_fit = cumsum(expectation); 
    
    
    for i = 1:  nParents
        rnd = rand;
        % Selected the first individual 
        % if first Cumulative relative fitness is higher than
        % generated random number 
        
        if rnd <=  cumulative_relative_fit(1)
            parents(i) = 1;
        else
             % Find indices where generated random number is higher than 
             % Cumulative relative fitness
             ind = rnd >=  cumulative_relative_fit;

             ALL_Indices_Above_Cum = index(ind);
             % Choose the one with the highest Cumulative relative fitness            
             parents(i) = ALL_Indices_Above_Cum(end);
        end
    end
 
end