NSGA2主要是对NSGA算法的改进。NSGA是N. Srinivas 和 K. Deb在1995年发表的一篇名为《Multiobjective function optimization using nondominated sorting genetic algorithms》的论文中提出的该算法在快速找到Pareto前沿和保持种群多样性方面都有很好的效果,不过在这么多年的应用中也出现了如下的一些问题:
1。非支配排序的时间复杂的很大,为O(MN3)。其中M为目标函数的数量,N为种群规模。
2。不支持精英策略。精英策略在保持好的个体及加速向Pareto前沿收敛方面都有很好的表现。
3。需要自己指定共享参数。该参数将对种群的多样性产生很大的影响。
该函数基于求解多目标最优解的进化算法,即目标的帕累托前沿。最初只输入种群大小和回采标准,或算法自动停止的总代数。
您将被要求输入目标函数的数量、决策变量的数量以及决策变量的范围空间。您还必须通过编辑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 代数
检查参数的数量。运行这个函数需要两个输入参数。
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);
目标函数描述包含有关目标函数的信息。
M是目标空间的维数,
V是决策变量空间的维度,
min_range和max_range是决策变量空间中变量的范围。
用户必须使用决策变量来定义目标函数。确保编辑“evaluate_objective”功能以满足您的需求。
[M, V, min_range, max_range] = objective_description_function();
使用在指定范围内的随机值初始化群体。每条染色体由决策变量组成。此外,目标函数,等级和拥挤距离信息的值也被添加到染色体向量中,但是仅对具有决策变量的向量的元素进行操作以执行诸如交叉和变异的遗传操作。
chromosome = initialize_variables(pop, M, V, min_range, max_range);
使用非支配排序对种群进行排序。这为每个体返回两列,这些列是等级和拥挤距离,对应于它们所属的前方位置。在此阶段,每个染色体的等级和拥挤距离被添加到染色体载体中以便于计算。
chromosome = non_domination_sort_mod(chromosome, M, V);
以下是在每一代中进行选择适合繁殖的父母选择父母的进行交叉和突变算子从父母和后代执行选择用适合的个体替换不适合的个体以保持不变的种群大小。
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
Save the result in ASCII text format.
save solution.txt chromosome -ASCII
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
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
使用在指定范围内的随机值初始化群体。每条染色体由决策变量组成。此外,目标函数,等级和拥挤距离信息的值也被添加到染色体向量中,但是仅对具有决策变量的向量的元素进行操作以执行诸如交叉和变异的遗传操作。
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
function f = non_domination_sort_mod(x,M,V)
此函数根据非支配对当前popultion进行排序。
第一个前面的所有个体的等级为1,
第二个前面的个体被赋予等级2,
依此类推。在分配等级之后,计算每个前沿中的拥挤度。
N - 目标空间总体大小
M - 目标函数的数量 2
V - 决策变量的数量
[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 = [];
初始化种群是基于非支配性排序的。下面将分别描述快速排序算法
for i = 1 : N
% Number of individuals that dominate this individual 支配的个体数目
individual(i).n = 0;
% Individuals which this individual dominate p 支配的个体集合
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 设置前沿为1 加入前沿集合
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) 如果前沿的i个个体不为空
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;
%拥挤距离计算如下,对于每个前Fi, n是个体的数量。初始化所有个体的距离为0,即Fi(dj) = 0,其中j对应于前Fi中的第j个个体,对于每个目标函数m
根据目标m对前面的个体进行排序,即I = Sort (Fi,m)。为每个个体的边界值指定无限距离Fi中的,即I(d1) = ?I(dn) = ?k = 2到(n ?1)
I(dk) = I(dk) + (I(k + 1).m ?I(k ?1). m)/ fmax(m)- fmin(m)%I(k)
m是第k个目标函数的第m个值I中的个人百分比
求出每个前面个体的拥挤距离
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();
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
function f = evaluate_objective(x, M, V)
函数对给定的输入向量x的目标函数进行评估,是决策变量和f(1)、f(2)等的目标函数。
算法总是最小化目标函数因此,如果你想最大化函数,然后将函数乘以负的函数。
M是目标函数的numebr
V是决策变量的数量。
这个函数基本上是由定义他/她自己的目标函数的用户写的。确保M和V匹配初始用户输入。确保
下面给出一个目标函数。它有两个六个决策变量是两个目标函数。
% 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.
目标数目为2 ,可以任意有5个之内的任意决策变量
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
function f = genetic_operator(parent_chromosome, M, V, mu, mum, l_limit, u_limit)
这个功能被用来从母体染色体中产生后代。遗传操作符交叉和突变在最初设计的基础上进行了微小的修改。
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;
function f = replace_chromosome(intermediate_chromosome,pro,pop)
这个函数根据等级和拥挤距离替换染色体。开始时,直到达到总体大小,每个前端都是一个接一个地添加,直到添加一个完整的前端,从而导致超过总体大小。在这一点上,前面的染色体随后根据拥挤距离被添加到种群中。
[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