NSGA_2 Matlab 算法详解

NSGA_2算法主函数

该函数基于求解多目标最优解的进化算法,即目标的帕累托前沿。最初只输入种群大小和回采标准,或算法自动停止的总代数。
您将被要求输入目标函数的数量、决策变量的数量以及决策变量的范围空间。您还必须通过编辑evaluate_objective()函数来定义自己的目标函数。
在evaluate_objective.m中描述了一个示例目标函数。请确保您定义的目标函数与您输入的目标数量以及您输入的决策变量数量匹配。该函数的决策变量空间是连续的,但目标空间可能是连续的,也可能不是连续的。原算法NSGA-II是由坎普尔遗传算法Labarotary的研究人员开发的,更多信息请访问他们的网站 http://www.iitk.ac.in/kangal/
function nsga_2(pop,gen)
一个多目标优化函数,其中输入参数为
pop - Population size
gen - Total number of generation

简单的错误检测Simple error checking

检查参数的数量。运行这个函数需要两个输入参数。

if nargin < 2
    error('NSGA-II: Please enter the population size and number of generations as input arguments.');
end
% Both the input arguments need to of integer data type
if isnumeric(pop) == 0 || isnumeric(gen) == 0
    error('Both input arguments pop and gen should be integer datatype');
end
% Minimum population size has to be 20 individuals
if pop < 20
    error('Minimum population for running this function is 20');
end
if gen < 5
    error('Minimum number of generations is 5');
end
% Make sure pop and gen are integers
pop = round(pop);
gen = round(gen);

目标函数Objective Function

目标函数描述包含有关目标函数的信息。
M是目标空间的维数,
V是决策变量空间的维度,
min_range和max_range是决策变量空间中变量的范围。
用户必须使用决策变量来定义目标函数。确保编辑“evaluate_objective”功能以满足您的需求。

[M, V, min_range, max_range] = objective_description_function();

初始化种群Initialize the population

使用在指定范围内的随机值初始化群体。每条染色体由决策变量组成。此外,目标函数,等级和拥挤距离信息的值也被添加到染色体向量中,但是仅对具有决策变量的向量的元素进行操作以执行诸如交叉和变异的遗传操作。

chromosome = initialize_variables(pop, M, V, min_range, max_range);

对初始化种群进行排序Sort the initialized population

使用非支配排序对种群进行排序。这为每个体返回两列,这些列是等级和拥挤距离,对应于它们所属的前方位置。在此阶段,每个染色体的等级和拥挤距离被添加到染色体载体中以便于计算。

chromosome = non_domination_sort_mod(chromosome, M, V);

开始进化过程Start the evolution process

以下是在每一代中进行选择适合繁殖的父母选择父母的进行交叉和突变算子从父母和后代执行选择用适合的个体替换不适合的个体以保持不变的种群大小。

for i = 1 : gen
%选择父节点
%选择亲本进行繁殖以产生后代的
%原始NSGA-II使用基于二进制锦标赛选择拥挤度比较算子的参数是
%pool ——匹配池的大小。通常是种群大小的一半
%tour——锦标赛比赛规模。最初的NSGA-II使用了一个二进制锦标赛
%选择,但要看比赛大小的影响,这是由用户选择任意大小。
    pool = round(pop/2);
    tour = 2;
   %选择过程
   %在NSGA-II中使用二进制锦标赛选择。在一个二进制比赛选择过程随机选择两个人并比较了它们的适应度。适应度较好的人是选择为父代。选拔赛选择将一直进行到交配池已填满。基本上,池的大小就是父节点的数量%将被选择。函数的输入参数% ent_selection是染色体、池、环。这个函数使用来自染色体载体中最后两个元素的信息。
   %最后一个元素具有拥挤距离信息,
   % 倒数第二个元素具有秩信息。
   选择是基于等级和如果遇到相同等级的个体,拥挤比较距离
   %一个秩越低,拥挤距离越大就是选择标准。
    parent_chromosome = tournament_selection(chromosome, pool, tour);

 % Perfrom交叉和变异算子原始的NSGA-II算法使用了模拟的二进制交叉(SBX)和%多项式变异。
 交叉概率pc = 0.9,突变概率为pm = 1/n,
 其中n为决策变量个数。实际编码的遗传算法和二进制编码的遗传算法都是在原系统中实现的
 %算法,而在本程序中只考虑实码遗传算法。
 交叉算子和变异算子的分布指标mu = 20和mum=20。
    mu = 20;
    mum = 20;
    offspring_chromosome = ...
        genetic_operator(parent_chromosome, ...
        M, V, mu, mum, min_range, max_range);

中间种群是指父代和当前的后代的组合种群。种群规模是2乘以初始总体。

    [main_pop,temp] = size(chromosome);
    [offspring_pop,temp] = size(offspring_chromosome);
    % temp is a dummy variable.
    clear temp
中间染色体是当前种群和
后代种群的连接。
    intermediate_chromosome(1:main_pop,:) = chromosome;
    intermediate_chromosome(main_pop + 1 : main_pop + offspring_pop,1 : M+V) = ...
        offspring_chromosome;

  %非占主导地位的中间群体根据非支配排序再次对中间种群进行排序
%,然后对中间体执行替换操作的人口。
    intermediate_chromosome = ...
        non_domination_sort_mod(intermediate_chromosome, M, V);
 %进行选择
 一旦中间种群被排序,只有最佳的解决方案是根据它的等级和拥挤距离选择%。每个前沿按照升序排列,直到加到达到总体大小的为止。最后一个前沿是包含在个体的最小拥挤度。
    chromosome = replace_chromosome(intermediate_chromosome, M, V, pop);
    if ~mod(i,100)
        clc
        fprintf('%d generations completed\n',i);
    end
end

结果Result

Save the result in ASCII text format.

save solution.txt chromosome -ASCII

可视化Visualize

The following is used to visualize the result if objective space dimension is visualizable.

if M == 2
plot(chromosome(:,V + 1),chromosome(:,V + 2),’’);
elseif M ==3
plot3(chromosome(:,V + 1),chromosome(:,V + 2),chromosome(:,V + 3),’
’);
end

函数详解

目标函数Objective Function

function [number_of_objectives,number_of_decision_variables,min_range_of_decesion_variable,max_range_of_decesion_variable] = objective_description_function()
此函数用于完整描述目标函数和决策变量空间等的范围。提示用户输入目标数,决策变量的数量,每个决策变量的最大和最小范围,最后函数等待供用户修改

g = sprintf('Input the number of objective: ');    % Obtain the number of objective function
number_of_objectives = input(g);
g = sprintf('\nInput the number of decision variables: ');
% Obtain the number of decision variables
number_of_decision_variables = input(g);
clc
for i = 1 : number_of_decision_variables
    clc
    g = sprintf('\nInput the minimum value for decision variable %d : ', i);
    % Obtain the minimum possible value for each decision variable
    min_range_of_decesion_variable(i) = input(g);
    g = sprintf('\nInput the maximum value for decision variable %d : ', i);
    % Obtain the maximum possible value for each decision variable
    max_range_of_decesion_variable(i) = input(g);
    clc
end
g = sprintf('\n Now edit the function named "evaluate_objective" appropriately to match your needs.
\n Make sure that the number of objective functions and decision variables match your numerical input. 
\n Make each objective function as a corresponding array element. 
\n After editing do not forget to save. \n Press "c" and enter to continue... ');
% Prompt the user to edit the evaluate_objective function and wait until
% 'c' is pressed.
x = input(g, 's');
if isempty(x)
    x = 'x';
end
while x ~= 'c'
    clc
    x = input(g, 's');
    if isempty(x)
        x = 'x';
    end
end

初始化种群Initialize the population

使用在指定范围内的随机值初始化群体。每条染色体由决策变量组成。此外,目标函数,等级和拥挤距离信息的值也被添加到染色体向量中,但是仅对具有决策变量的向量的元素进行操作以执行诸如交叉和变异的遗传操作。

function f = initialize_variables(N,M,V,min_tange,max_range)
N - 总体大小
M - 目标函数的数量
V - 决策变量的数量
min_range - 十进制值的向量,指示每个决策变量的最小值。
max_range - 决策变量的最大可能值的向量。

初始化决策变量基于可能的最大和最小值,V 是决策变量的个数,从最大最小值之间随机选出一个值作为每一个决策变量
对于简化计算处理染色体的数据和目标方程有着串联的关系,V+1到K 具有目标方程的值,一次目标评价函数带一个染色体,事实上,只有决策变量被传递给函数关于目标函数的数量处理并返回目标函数的值。 这个值存在染色体的最后

min = min_range;
max = max_range;
K = M + V;
Initialize each chromosome
For each chromosome perform the following (N is the population size)
for i = 1 : N
    for j = 1 : V
        f(i,j) = min(j) + (max(j) - min(j))*rand(1);
    end
    f(i,V + 1: K) = evaluate_objective(f(i,:), M, V);
end

对初始化种群进行排序Sort the initialized population

function f = non_domination_sort_mod(x,M,V)
此函数根据非支配对当前popultion进行排序。第一个前面的所有个体的等级为1,第二个前面的个体被赋予等级2,依此类推。在分配等级之后,计算每个前沿中的拥挤。

[N, m] = size(x);
clear m

% Initialize the front number to 1. 初始化前沿是1
front = 1;

% There is nothing to this assignment, used only to manipulate easily in
% MATLAB.
F(front).f = [];
individual = [];

非主导排序Non-Dominated sort.

初始化种群是基于非支配性排序的。下面将分别描述快速排序算法

  • 对于主要人群中的每个个体p, p执行以下操作
    初始化Sp =[ ]。这个集合将包含所有以p主导的个体。
    初始化np = 0。这就是p主导个体的数目。
    for q in P
    begin
    if p主导q·将q添加到集合Sp,即Sp = Sp ?{q}
    else if q主导p· 增加主导计数器 np即np = np + 1
    if np = 0,即没有个体支配p,那么p属于第一个前沿;
    将个体p的秩设置为1 i。更新第一前设置通过添加p到前一个 F1 = F1 ?p
    end
  • 对主要种群P中的所有个体都进行了这项研究。
    将前沿初始化为1。i = 1
    当第i个面非空时,进行如下操作,即Fi != []% - Q =[]。用于存储(i + 1)前面的个体的集合。%
    -对于在前沿Fi中的每个p
    *对于Sp中的每个个体q (Sp是个体p占主导的集合)
    ·nq = nq?1 递减单个q的支配计数。
    ·如果nq = 0,则后面的个体都不存在% front将主导q,因此设置qrank = i + 1。更新集合Q与单独的Q,即Q = Q ?q
    前沿增加1
    -现在集合Q是下一个前沿,因此Fi = Q
    该算法比原NSGA有更好的性能是利用了一下两个信息
    个体支配的集合(Sp)和占主导地位的个体的数目(np)。
for i = 1 : N
    % Number of individuals that dominate this individual
    individual(i).n = 0;
    % Individuals which this individual dominate
    individual(i).p = [];
    for j = 1 : N
        dom_less = 0;
        dom_equal = 0;
        dom_more = 0;
        for k = 1 : M
            if (x(i,V + k) < x(j,V + k))
                dom_less = dom_less + 1;
            elseif (x(i,V + k) == x(j,V + k))
                dom_equal = dom_equal + 1;
            else
                dom_more = dom_more + 1;
            end
        end
        if dom_less == 0 && dom_equal ~= M
            individual(i).n = individual(i).n + 1;
        elseif dom_more == 0 && dom_equal ~= M
            individual(i).p = [individual(i).p j];
        end
    end
    if individual(i).n == 0
        x(i,M + V + 1) = 1;
        F(front).f = [F(front).f i];
    end
end
% Find the subsequent fronts
while ~isempty(F(front).f)
   Q = [];
   for i = 1 : length(F(front).f)
       if ~isempty(individual(F(front).f(i)).p)
        	for j = 1 : length(individual(F(front).f(i)).p)
            	individual(individual(F(front).f(i)).p(j)).n = ...
                	individual(individual(F(front).f(i)).p(j)).n - 1;
        	   	if individual(individual(F(front).f(i)).p(j)).n == 0
               		x(individual(F(front).f(i)).p(j),M + V + 1) = ...
                        front + 1;
                    Q = [Q individual(F(front).f(i)).p(j)];
                end
            end
       end
   end
   front =  front + 1;
   F(front).f = Q;
end

[temp,index_of_fronts] = sort(x(:,M + V + 1));
for i = 1 : length(index_of_fronts)
    sorted_based_on_front(i,:) = x(index_of_fronts(i),:);
end
current_index = 0;

拥挤距离Crowding distance

%The crowing distance is calculated as below
% • For each front Fi, n is the number of individuals.
%   – initialize the distance to be zero for all the individuals i.e. Fi(dj ) = 0,
%     where j corresponds to the jth individual in front Fi.
%   – for each objective function m
%       * Sort the individuals in front Fi based on objective m i.e. I =
%         sort(Fi,m).
%       * Assign infinite distance to boundary values for each individual
%         in Fi i.e. I(d1) = ? and I(dn) = ?
%       * for k = 2 to (n ? 1)
%           · I(dk) = I(dk) + (I(k + 1).m ? I(k ? 1).m)/fmax(m) - fmin(m)
%           · I(k).m is the value of the mth objective function of the kth
%             individual in I

% Find the crowding distance for each individual in each front
for front = 1 : (length(F) - 1)
%    objective = [];
    distance = 0;
    y = [];
    previous_index = current_index + 1;
    for i = 1 : length(F(front).f)
        y(i,:) = sorted_based_on_front(current_index + i,:);
    end
    current_index = current_index + i;
    % Sort each individual based on the objective
    sorted_based_on_objective = [];
    for i = 1 : M
        [sorted_based_on_objective, index_of_objectives] = ...
            sort(y(:,V + i));
        sorted_based_on_objective = [];
        for j = 1 : length(index_of_objectives)
            sorted_based_on_objective(j,:) = y(index_of_objectives(j),:);
        end
        f_max = ...
            sorted_based_on_objective(length(index_of_objectives), V + i);
        f_min = sorted_based_on_objective(1, V + i);
        y(index_of_objectives(length(index_of_objectives)),M + V + 1 + i)...
            = Inf;
        y(index_of_objectives(1),M + V + 1 + i) = Inf;
         for j = 2 : length(index_of_objectives) - 1
            next_obj  = sorted_based_on_objective(j + 1,V + i);
            previous_obj  = sorted_based_on_objective(j - 1,V + i);
            if (f_max - f_min == 0)
                y(index_of_objectives(j),M + V + 1 + i) = Inf;
            else
                y(index_of_objectives(j),M + V + 1 + i) = ...
                     (next_obj - previous_obj)/(f_max - f_min);
            end
         end
    end
    distance = [];
    distance(:,1) = zeros(length(F(front).f),1);
    for i = 1 : M
        distance(:,1) = distance(:,1) + y(:,M + V + 1 + i);
    end
    y(:,M + V + 2) = distance;
    y = y(:,1 : M + V + 2);
    z(previous_index:current_index,:) = y;
end
f = z();

锦标赛选择过程tournament_selection

function tournament_selection(chromosome, pool_size, tour_size)
是为交配池选择个体的选择策略。选择基于锦标赛选择。参数染色体是在进行比赛选择后,从当前的世代种群中选择个体形成一个size pool_size的交配池,比赛的size变为tour_size。通过改变比赛规模,选择压力可以调整。但是对于NSGA-II, tour_size被固定为2,但是用户可以自由地尝试不同的锦标赛大小。此外,人们还注意到,一场锦标赛规模超过5是没有任何意义的。
锦标赛选择过程
在一个锦标赛的选择过程中,n个人被随机选择,其中n等于tour_size。从这些个体中只选择一个,并添加到交配池中,其中交配池的大小为pool_size。选择是基于两个标准执行的。首先也是最重要的是解决方案所处的位置。选择级别较低的个人。其次,如果两个个体的秩相同,则比较拥挤距离。选择拥挤距离较大的个体。

Contents
Tournament selection process

% Get the size of chromosome. The number of chromosome is not important
% while the number of elements in chromosome are important.
[pop, variables] = size(chromosome);
% The peunltimate element contains the information about rank.  倒数第二个元素含着rank
rank = variables - 1;
% The last element contains information about crowding distance. 最后一个元素蕴藏拥挤度
distance = variables;

% Until the mating pool is filled, perform tournament selection 直到交配池满了,执行锦标赛选择
for i = 1 : pool_size
    % Select n individuals at random, where n = tour_size 随机选择n个个体
    for j = 1 : tour_size
        % Select an individual at random
        candidate(j) = round(pop*rand(1));
        % Make sure that the array starts from one.
        if candidate(j) == 0
            candidate(j) = 1;
        end
        if j > 1
            % Make sure that same candidate is not choosen.
            while ~isempty(find(candidate(1 : j - 1) == candidate(j)))
                candidate(j) = round(pop*rand(1));
                if candidate(j) == 0
                    candidate(j) = 1;
                end
            end
        end
    end
    % Collect information about the selected candidates. 收集被选择候选人的信息
    for j = 1 : tour_size
        c_obj_rank(j) = chromosome(candidate(j),rank);
        c_obj_distance(j) = chromosome(candidate(j),distance);
    end
    % Find the candidate with the least rank  找到最小的候选人
    min_candidate = ...
        find(c_obj_rank == min(c_obj_rank));
    % If more than one candiate have the least rank then find the candidate
    % within that group having the maximum crowding distance.
    if length(min_candidate) ~= 1
        max_candidate = ...
        find(c_obj_distance(min_candidate) == max(c_obj_distance(min_candidate)));
        % If a few individuals have the least rank and have maximum crowding
        % distance, select only one individual (not at random).
        if length(max_candidate) ~= 1
            max_candidate = max_candidate(1);
        end
        % Add the selected individual to the mating pool 把被选择的候选人加入交配池里
        f(i,:) = chromosome(candidate(min_candidate(max_candidate)),:);
    else
        % Add the selected individual to the mating pool 
        f(i,:) = chromosome(candidate(min_candidate(1)),:);
    end
end

评价目标函数evaluate_objective

function f = evaluate_objective(x, M, V)
Function to evaluate the objective functions for the given input vector x. x is an array of decision variables and f(1), f(2), etc are the objective functions. The algorithm always minimizes the objective function hence if you would like to maximize the function then multiply the function by negative one. M is the numebr of objective functions and V is the number of decision variables.

This functions is basically written by the user who defines his/her own objective function. Make sure that the M and V matches your initial user input. Make sure that the

An example objective function is given below. It has two six decision variables are two objective functions.


% f = [];
% %% Objective function one
% % Decision variables are used to form the objective function.
% f(1) = 1 - exp(-4*x(1))*(sin(6*pi*x(1)))^6;
% sum = 0;
% for i = 2 : 6
%     sum = sum + x(i)/4;
% end
% %% Intermediate function
% g_x = 1 + 9*(sum)^(0.25);
%
% %% Objective function two
% f(2) = g_x*(1 - ((f(1))/(g_x))^2);
Kursawe proposed by Frank Kursawe.
Take a look at the following reference A variant of evolution strategies for vector optimization. In H. P. Schwefel and R. Männer, editors, Parallel Problem Solving from Nature. 1st Workshop, PPSN I, volume 496 of Lecture Notes in Computer Science, pages 193-197, Berlin, Germany, oct 1991. Springer-Verlag.

Number of objective is two, while it can have arbirtarly many decision variables within the range -5 and 5. Common number of variables is 3.

f = [];
% Objective function one
sum = 0;
for i = 1 : V - 1
    sum = sum - 10*exp(-0.2*sqrt((x(i))^2 + (x(i + 1))^2));
end
% Decision variables are used to form the objective function.
f(1) = sum;

% Objective function two
sum = 0;
for i = 1 : V
    sum = sum + (abs(x(i))^0.8 + 5*(sin(x(i)))^3);
end
% Decision variables are used to form the objective function.
f(2) = sum;
Check for error
if length(f) ~= M
    error('The number of decision variables does not match you previous input. Kindly check your objective function');
end

遗传算子genetic_operator

function f = genetic_operator(parent_chromosome, M, V, mu, mum, l_limit, u_limit)
This function is utilized to produce offsprings from parent chromosomes. The genetic operators corssover and mutation which are carried out with slight modifications from the original design. For more information read the document enclosed.

parent_chromosome - the set of selected chromosomes. M - number of objective functions V - number of decision varaiables mu - distribution index for crossover (read the enlcosed pdf file) mum - distribution index for mutation (read the enclosed pdf file) l_limit - a vector of lower limit for the corresponding decsion variables u_limit - a vector of upper limit for the corresponding decsion variables

The genetic operation is performed only on the decision variables, that is the first V elements in the chromosome vector.


[N,m] = size(parent_chromosome);

clear m
p = 1;
% Flags used to set if crossover and mutation were actually performed.
was_crossover = 0;
was_mutation = 0;


for i = 1 : N
    % With 90 % probability perform crossover
    if rand(1) < 0.9
        % Initialize the children to be null vector.
        child_1 = [];
        child_2 = [];
        % Select the first parent
        parent_1 = round(N*rand(1));
        if parent_1 < 1
            parent_1 = 1;
        end
        % Select the second parent
        parent_2 = round(N*rand(1));
        if parent_2 < 1
            parent_2 = 1;
        end
        % Make sure both the parents are not the same.
        while isequal(parent_chromosome(parent_1,:),parent_chromosome(parent_2,:))
            parent_2 = round(N*rand(1));
            if parent_2 < 1
                parent_2 = 1;
            end
        end
        % Get the chromosome information for each randomnly selected
        % parents
        parent_1 = parent_chromosome(parent_1,:);
        parent_2 = parent_chromosome(parent_2,:);
        % Perform corssover for each decision variable in the chromosome.
        for j = 1 : V
            % SBX (Simulated Binary Crossover).
            % For more information about SBX refer the enclosed pdf file.
            % Generate a random number
            u(j) = rand(1);
            if u(j) <= 0.5
                bq(j) = (2*u(j))^(1/(mu+1));
            else
                bq(j) = (1/(2*(1 - u(j))))^(1/(mu+1));
            end
            % Generate the jth element of first child
            child_1(j) = ...
                0.5*(((1 + bq(j))*parent_1(j)) + (1 - bq(j))*parent_2(j));
            % Generate the jth element of second child
            child_2(j) = ...
                0.5*(((1 - bq(j))*parent_1(j)) + (1 + bq(j))*parent_2(j));
            % Make sure that the generated element is within the specified
            % decision space else set it to the appropriate extrema.
            if child_1(j) > u_limit(j)
                child_1(j) = u_limit(j);
            elseif child_1(j) < l_limit(j)
                child_1(j) = l_limit(j);
            end
            if child_2(j) > u_limit(j)
                child_2(j) = u_limit(j);
            elseif child_2(j) < l_limit(j)
                child_2(j) = l_limit(j);
            end
        end
        % Evaluate the objective function for the offsprings and as before
        % concatenate the offspring chromosome with objective value.
        child_1(:,V + 1: M + V) = evaluate_objective(child_1, M, V);
        child_2(:,V + 1: M + V) = evaluate_objective(child_2, M, V);
        % Set the crossover flag. When crossover is performed two children
        % are generate, while when mutation is performed only only child is
        % generated.
        was_crossover = 1;
        was_mutation = 0;
    % With 10 % probability perform mutation. Mutation is based on
    % polynomial mutation.
    else
        % Select at random the parent.
        parent_3 = round(N*rand(1));
        if parent_3 < 1
            parent_3 = 1;
        end
        % Get the chromosome information for the randomnly selected parent.
        child_3 = parent_chromosome(parent_3,:);
        % Perform mutation on eact element of the selected parent.
        for j = 1 : V
           r(j) = rand(1);
           if r(j) < 0.5
               delta(j) = (2*r(j))^(1/(mum+1)) - 1;
           else
               delta(j) = 1 - (2*(1 - r(j)))^(1/(mum+1));
           end
           % Generate the corresponding child element.
           child_3(j) = child_3(j) + delta(j);
           % Make sure that the generated element is within the decision
           % space.
           if child_3(j) > u_limit(j)
               child_3(j) = u_limit(j);
           elseif child_3(j) < l_limit(j)
               child_3(j) = l_limit(j);
           end
        end
        % Evaluate the objective function for the offspring and as before
        % concatenate the offspring chromosome with objective value.
        child_3(:,V + 1: M + V) = evaluate_objective(child_3, M, V);
        % Set the mutation flag
        was_mutation = 1;
        was_crossover = 0;
    end
    % Keep proper count and appropriately fill the child variable with all
    % the generated children for the particular generation.
    if was_crossover
        child(p,:) = child_1;
        child(p+1,:) = child_2;
        was_cossover = 0;
        p = p + 2;
    elseif was_mutation
        child(p,:) = child_3(1,1 : M + V);
        was_mutation = 0;
        p = p + 1;
    end
end
f = child;

染色体替换 replace_chromosome

function f = replace_chromosome(intermediate_chromosome,pro,pop)
This function replaces the chromosomes based on rank and crowding distance. Initially until the population size is reached each front is added one by one until addition of a complete front which results in exceeding the population size. At this point the chromosomes in that front is added subsequently to the population based on crowding distance.

[N, m] = size(intermediate_chromosome);

% Get the index for the population sort based on the rank
[temp,index] = sort(intermediate_chromosome(:,M + V + 1));

clear temp m

% Now sort the individuals based on the index
for i = 1 : N
    sorted_chromosome(i,:) = intermediate_chromosome(index(i),:);
end

% Find the maximum rank in the current population
max_rank = max(intermediate_chromosome(:,M + V + 1));

% Start adding each front based on rank and crowing distance until the
% whole population is filled.
previous_index = 0;
for i = 1 : max_rank
    % Get the index for current rank i.e the last the last element in the
    % sorted_chromosome with rank i.
    current_index = max(find(sorted_chromosome(:,M + V + 1) == i));
    % Check to see if the population is filled if all the individuals with
    % rank i is added to the population.
    if current_index > pop
        % If so then find the number of individuals with in with current
        % rank i.
        remaining = pop - previous_index;
        % Get information about the individuals in the current rank i.
        temp_pop = ...
            sorted_chromosome(previous_index + 1 : current_index, :);
        % Sort the individuals with rank i in the descending order based on
        % the crowding distance.
        [temp_sort,temp_sort_index] = ...
            sort(temp_pop(:, M + V + 2),'descend');
        % Start filling individuals into the population in descending order
        % until the population is filled.
        for j = 1 : remaining
            f(previous_index + j,:) = temp_pop(temp_sort_index(j),:);
        end
        return;
    elseif current_index < pop
        % Add all the individuals with rank i into the population.
        f(previous_index + 1 : current_index, :) = ...
            sorted_chromosome(previous_index + 1 : current_index, :);
    else
        % Add all the individuals with rank i into the population.
        f(previous_index + 1 : current_index, :) = ...
            sorted_chromosome(previous_index + 1 : current_index, :);
        return;
    end
    % Get the index for the last added individual.
    previous_index = current_index;
end

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章