GA stepGA - индекс превышает размеры матрицы - PullRequest
1 голос
/ 09 июля 2019

Я пишу Пользовательские функции GA в MATLAB для смешанной целочисленной задачи.Подробнее о моей проблеме здесь и здесь .

После того, как колесо рулетки выбор завершен, 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

Выбор колеса My Roullete:

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 :

Функция возвращает родителей, вектор строки длины nParents, содержащий индексы выбранных вами родителей.

Я неправильно вернул из выбора?И почему 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 размер .

1 Ответ

1 голос
/ 10 июля 2019
  • RouletteWheelSelection не возвращает родителей с двумя лицами
  • Предполагается, что численность населения составляет 10 особей
  • Во времяRouletteWheelSelection вас попросят выбрать nParents из 10, 5, например

Очевидно, nParents не должно превышать PopulationSize

Вы установили nParents = 16, в то время как 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];

Измените пользовательскую функцию выбора на эту

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...