NSGA_2 Matlab 算法详解完整代码 中文注释详解

文章目录一瞥

    • NSGA-2算法简介
    • NSGA_2算法主函数
        • 简单的错误检测Simple error checking
        • 目标函数Objective Function
        • 初始化种群Initialize the population
        • 对初始化种群进行排序Sort the initialized population
        • 开始进化过程Start the evolution process
        • 结果Result
        • 可视化Visualize
    • 函数详解
      • 目标函数Objective Function
      • 初始化种群Initialize the population
      • 对初始化种群进行排序Sort the initialized population
        • 非主导排序Non-Dominated sort.
        • 拥挤距离Crowding distance
      • 锦标赛选择过程tournament_selection
      • 评价目标函数evaluate_objective
      • 遗传算子genetic_operator
      • 染色体替换 replace_chromosome

NSGA-2算法简介

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。需要自己指定共享参数。该参数将对种群的多样性产生很大的影响。

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 - 目标函数的数量 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 = [];

非主导排序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 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;

拥挤距离Crowding distance

%拥挤距离计算如下,对于每个前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();

锦标赛选择过程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)
函数对给定的输入向量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

遗传算子genetic_operator

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;

染色体替换 replace_chromosome

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

你可能感兴趣的:(Ĵ进化计算)