NSGA_2 Matlab 算法詳解完整代碼 中文註釋詳解

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

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