当前位置:   article > 正文

进化计算(六)——NSGA II代码实现(Matlab)_sbx分布参数

sbx分布参数

写在前边:本文在原作者基础上补充了自己的理解,并将代码改成了更适宜本人理解的方式,总体算法没有做较多的改动,更多内容可移步博客,代码下载可移步NSGA-II代码。如果有需要本文代码的可移步下载,也可以在评论区留言邮箱。留言邮箱的话麻烦给本篇博文点一下赞哦,或者关注一下博主也可以,你的鼓励是博主更新的最大动力^_^

代码流程图

请添加图片描述

Code

Main

clear;
clc;

%%----------代码中用到的一些变量------------
% pop:种群规模
% gen:迭代次数
% pc:交叉概率
% pm:变异概率
% yita1:SBX分布参数
% yita2:多项式变异分布参数
% f_num:目标函数个数
% x_num:决策变量个数
% x_min:决策变量取值范围下界
% x_max:决策变量取值范围上界
% F:pareto等级为pareto_rank的集合
% n:支配当前解的解个数
% s:当前解支配的解个数

%%----------chromo矩阵的组成-----------
% 前x_num列:决策变量值
% x_num+1:x_num+f_num列:当前决策向量对应的目标函数值
% x_num+f_num+1列:rank值
% x_num+f_num+1+1列:拥挤度值

%-------------------------------------------
%% 函数选择
disp('please input a function you want to optimize')
fun = input('from ZDT1—ZDT6、DTLZ1、DTLZ2: ','s');
tic; % 开启计时器
[f_num,x_num,x_min,x_max] = function_select(fun);

%% 参数设置
pop=100;%种群大小100
gen=250;%250进化代数  进化代数越高越接近PF
pc=0.9;%交叉概率
pm=1/x_num;%变异概率,x-num为决策变量个数
yita1=20;%SBX分布参数
yita2=20;%多项式变异分布参数

%% 种群初始化
chromo=initialize(pop,f_num,x_num,x_min,x_max,fun);%该函数中调用了目标函数表达式
%%初始种群的非支配排序
[F1,chromo_non]=non_domination_sort(pop,chromo,f_num,x_num);
%F为pareto等级为pareto_rank的集合,%p为每个个体p的集合(包括每个个体p的被支配个数n和该个体支配的解的集合s),chromo最后一列加入个体的等级
%%计算拥挤度
chromo=crowding_distance_sort(F1,chromo_non,f_num,x_num);
i=1;

%% 循环开始
for i=1:gen
    %%二进制竞赛选择(每次取pop/2,所以选两次,保证选择后的种群数量为100)
    chromo_parent1 = tournament_selection(chromo); %50
    chromo_parent2 = tournament_selection(chromo); %50
    chromo_parent = [chromo_parent1;chromo_parent2]; %100
%   chromo_parent = tournament_selection(chromo); 
%   只选一次也能满足后续操作,但是没有选两次的效果好

    %%模拟二进制交叉与多项式变异
    chromo_offspring=cross_mutation(chromo_parent,f_num,x_num,x_min,x_max,pc,pm,yita1,yita2,fun );
    
    %%精英保留策略
    %将父代和子代合并
    [pop_parent,~]=size(chromo);
    [pop_offspring,~]=size(chromo_offspring);
    combine_chromo(1:pop_parent,1:(f_num+x_num))=chromo(:,1:(f_num+x_num));
    combine_chromo((pop_parent+1):(pop_parent+pop_offspring),1:(f_num+x_num))=chromo_offspring(:,1:(f_num+x_num));
    %快速非支配排序
    [pop2,~]=size(combine_chromo);
    [F2,combine_chromo1]=non_domination_sort(pop2,combine_chromo,f_num,x_num);
    %计算拥挤度进行排序
    combine_chromo2=crowding_distance_sort(F2,combine_chromo1,f_num,x_num);
    %精英保留产生下一代种群
    chromo=elitism(pop,combine_chromo2,f_num,x_num);
    if mod(i,10) == 0
        fprintf('%d gen has completed!\n',i);
    end
end
toc;%读取计时器中的数
aaa=toc;%输出计时时间

hold on
if(f_num==2)%f-num为目标函数个数
    plot(chromo(:,x_num+1),chromo(:,x_num+2),'r*');
end
if(f_num==3)
    plot3(chromo(:,x_num+1),chromo(:,x_num+2),chromo(:,x_num+2),'r*');
end

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88

函数选择

function [f_num,x_num,x_min,x_max] = function_select(fun)
%% 函数选择
%定义 决策变量取值范围,决策变量个数,目标函数个数
%导入 已知PF最前沿
%--------------------ZDT1--------------------
if strcmp(fun,'ZDT1') %strcmp:字符串之间比较
    f_num=2;%目标函数个数
    x_num=30;%决策变量个数
    x_min=zeros(1,x_num);%决策变量的最小值
    x_max=ones(1,x_num);%决策变量的最大值
    load('ZDT1.txt');%导入正确的前端解
    plot(ZDT1(:,1),ZDT1(:,2),'g*');
    PP=ZDT1;
end
%--------------------ZDT2--------------------
if strcmp(fun,'ZDT2')
    f_num=2;%目标函数个数
    x_num=30;%决策变量个数
    x_min=zeros(1,x_num);%决策变量的最小值
    x_max=ones(1,x_num);%决策变量的最大值
    load('ZDT2.txt');%导入正确的前端解
    plot(ZDT2(:,1),ZDT2(:,2),'g*');
    PP=ZDT2;
end
%--------------------ZDT3--------------------
if strcmp(fun,'ZDT3')
    f_num=2;%目标函数个数
    x_num=30;%决策变量个数
    x_min=zeros(1,x_num);%决策变量的最小值
    x_max=ones(1,x_num);%决策变量的最大值
    load('ZDT3.txt');%导入正确的前端解
    plot(ZDT3(:,1),ZDT3(:,2),'g*');
    PP=ZDT3;
end
%--------------------ZDT4--------------------
if strcmp(fun,'ZDT4')
    f_num=2;%目标函数个数
    x_num=10;%决策变量个数
    x_min=[0,-5,-5,-5,-5,-5,-5,-5,-5,-5];%决策变量的最小值
    x_max=[1,5,5,5,5,5,5,5,5,5];%决策变量的最大值
    load('ZDT4.txt');%导入正确的前端解
    plot(ZDT4(:,1),ZDT4(:,2),'g*');
    PP=ZDT4;
end
%--------------------ZDT6--------------------
if strcmp(fun,'ZDT6')
    f_num=2;%目标函数个数
    x_num=10;%决策变量个数
    x_min=zeros(1,x_num);%决策变量的最小值
    x_max=ones(1,x_num);%决策变量的最大值
    load('ZDT6.txt');%导入正确的前端解
    plot(ZDT6(:,1),ZDT6(:,2),'g*');
    PP=ZDT6;
end
%--------------------------------------------
%--------------------DTLZ1--------------------
if strcmp(fun,'DTLZ1')
    f_num=3;%目标函数个数
    x_num=10;%决策变量个数
    x_min=zeros(1,x_num);%决策变量的最小值
    x_max=ones(1,x_num);%决策变量的最大值
    load('DTLZ1.txt');%导入正确的前端解
%     plot3(DTLZ1(:,1),DTLZ1(:,2),DTLZ1(:,3),'g*');
    PP=DTLZ1;
end
%--------------------------------------------
%--------------------DTLZ2--------------------
if strcmp(fun,'DTLZ2')
    f_num=3;%目标函数个数
    x_num=10;%决策变量个数
    x_min=zeros(1,x_num);%决策变量的最小值
    x_max=ones(1,x_num);%决策变量的最大值
    load('DTLZ2.txt');%导入正确的前端解
%     plot3(DTLZ2(:,1),DTLZ2(:,2),DTLZ2(:,3),'g*');
    PP=DTLZ2;
end

end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

种群初始化

function chromo = initialize( pop,f_num,x_num,x_min,x_max,fun )
%   种群初始化
for i=1:pop
    for j=1:x_num
        chromo(i,j)=x_min(j)+(x_max(j)-x_min(j))*rand(1);
    end
    %计算决策向量对应的目标向量并将其放在决策向量后边
    chromo(i,x_num+1:x_num+f_num) = object_fun(chromo(i,:),f_num,x_num,fun);
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

非支配排序

function [F,chromo] = non_domination_sort( pop,chromo,f_num,x_num )
%% 初始化
pareto_rank=1; %初始pareto等级为1
F(pareto_rank).ss=[];%pareto等级为pareto_rank的集合
p=[];%每个个体p的集合
%% 计算所有个体的n、s集,并选出F1中的个体(n=0for i=1:pop
    %%%计算出种群中每个个体p的被支配个数n和该个体支配的解的集合s
    p(i).n=0;%被支配个体数目n初始化为0
    p(i).s=[];%支配解的集合s
    for j=1:pop
        less=0;%y'的目标函数值小于个体的目标函数值数目
        equal=0;%y'的目标函数值等于个体的目标函数值数目
        greater=0;%y'的目标函数值大于个体的目标函数值数目
        for k=1:f_num
            if(chromo(i,x_num+k)<chromo(j,x_num+k))
                less=less+1;
            elseif(chromo(i,x_num+k)==chromo(j,x_num+k))
                equal=equal+1;
            else
                greater=greater+1;
            end
        end
        if(less==0 && equal~=f_num)
            p(i).n=p(i).n+1;%被支配个体数目n+1
        elseif(greater==0 && equal~=f_num)
            p(i).s=[p(i).s j];
        %若less和greater都不等于0,证明两者互不支配 
        end
    end
    %%%判断当前个体n是否为0,若为0,则将其放入集合F(1)if(p(i).n==0)
        chromo(i,f_num+x_num+1)=1;%在决策向量+目标向量后存储个体的等级信息 
        F(pareto_rank).ss=[F(pareto_rank).ss i];
    end
end
%% 在F1层的基础上,继续进行分层

while ~isempty(F(pareto_rank).ss) %直到某层个体数为0就可以结束分层
    temp=[];
    for i=1:length(F(pareto_rank).ss)
        if ~isempty(p(F(pareto_rank).ss(i)).s)
            for j=1:length(p(F(pareto_rank).ss(i)).s)
                 %n=0个体对应的s集中所有的n-1
                p(p(F(pareto_rank).ss(i)).s(j)).n=p(p(F(pareto_rank).ss(i)).s(j)).n - 1;
                if p(p(F(pareto_rank).ss(i)).s(j)).n==0 %若s集中的个体n-1等于0,则放到下一层上
                    chromo(p(F(pareto_rank).ss(i)).s(j),f_num+x_num+1)=pareto_rank+1;%储存个体的等级信息
                    temp=[temp p(F(pareto_rank).ss(i)).s(j)]; %把放到下一层的个体单独存放在temp中
                end
            end
        end
    end
    pareto_rank=pareto_rank+1;
    F(pareto_rank).ss=temp; %下一次非支配排序基于下一层个体
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

拥挤度计算

function chromo = crowding_distance_sort( F,chromo,f_num,x_num )
%% 计算拥挤度
%% 按照pareto等级对种群中的个体进行排序,便于逐层求解拥挤度

[~,index]=sort(chromo(:,f_num+x_num+1));
[~,mm1]=size(chromo);
temp=zeros(length(index),mm1);
for i=1:length(index)%=pop
    temp(i,:)=chromo(index(i),:);%按照pareto等级排序后种群
end

%% 对于每个等级的个体开始计算拥挤度
current_index = 0;
for pareto_rank=1:(length(F)-1)
%计算F的循环时多了一次空(直到s集中n-1=0的个体数为0时才跳出循环),所以减掉


%%%当前等级拥挤度计算初始化
    nd=[];
    nd(:,1)=zeros(length(F(pareto_rank).ss),1);
    %y=[];%储存当前处理的等级的个体
    [~,mm2]=size(temp);
    y=zeros(length(F(pareto_rank).ss),mm2);%储存当前处理的等级的个体
    previous_index=current_index + 1;
    for i=1:length(F(pareto_rank).ss)
        y(i,:)=temp(current_index + i,:);
    end
    current_index=current_index + i;
    
    
%%%针对每一个目标函数fm计算相邻两解的函数差值
%根据函数值排序,边界点差值直接设为inf,计算中间点差值后附在决策向量+目标向量+rank后
    for i=1:f_num
        %%根据该目标函数值对该等级的个体进行排序
        [~,index_objective]=sort(y(:,x_num+i));
        %objective_sort=[];%通过目标函数排序后的个体
        [~,mm3]=size(y);
        objective_sort=zeros(length(index_objective),mm3);%通过目标函数排序后的个体
        for j=1:length(index_objective)
            objective_sort(j,:)=y(index_objective(j),:);
        end
        %%记fmax为最大值,fmin为最小值
        fmin=objective_sort(1,x_num+i);
        fmax=objective_sort(length(index_objective),x_num+i);
        %%对排序后的两个边界拥挤度设为1d和nd设为无穷
        y(index_objective(1),f_num+x_num+1+i)=Inf;
        y(index_objective(length(index_objective)),f_num+x_num+1+i)=Inf;
        %%计算nd=nd+(fm(i+1)-fm(i-1))/(fmax-fmin)
        for j=2:(length(index_objective)-1)
            pre_f=objective_sort(j-1,x_num+i);
            next_f=objective_sort(j+1,x_num+i);
            if (fmax-fmin==0)
                y(index_objective(j),f_num+x_num+1+i)=Inf;
            else
                y(index_objective(j),f_num+x_num+1+i)=(next_f-pre_f)/(fmax-fmin);
            end
        end
    end
    
    
%%%计算拥挤度
%多个目标函数相邻解差值求和,计算拥挤度,并将最终拥挤度附在决策向量+目标向量+rank后
    for i=1:f_num
        nd(:,1)=nd(:,1)+y(:,f_num+x_num+1+i);
    end
    %2列保存拥挤度,其他的覆盖掉
    y(:,f_num+x_num+2)=nd;
    y=y(:,1:(f_num+x_num+2));
    temp_two(previous_index:current_index,:) = y; %将当前等级计算出的y储存到temp_two中
end
chromo=temp_two;
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

二进制锦标赛选择算子

function chromo_parent = tournament_selection( chromo )
%% 二进制竞标赛选择
[pop, index] = size(chromo);
touranment=2;  %(两两抉择)
a=round(pop/2);
%初始化
chromo_candidate=zeros(touranment,1);
chromo_rank=zeros(touranment,1);
chromo_distance=zeros(touranment,1);
chromo_parent=zeros(a,index);
% 获取等级的索引
rank = index - 1;
% 获得拥挤度的索引
distance = index;
for i=1:a
    for j=1:touranment
        chromo_candidate(j)=round(pop*rand(1));%随机产生候选者
        if(chromo_candidate(j)==0)%索引从1开始
            chromo_candidate(j)=1;
        end
        if(j>1)
            while (~isempty(find(chromo_candidate(1:j-1)==chromo_candidate(j))))
                chromo_candidate(j)=round(pop*rand(1));
                if(chromo_candidate(j)==0)%索引从1开始
                    chromo_candidate(j)=1;
                end
            end
        end
    end
    for j=1:touranment
        chromo_rank(j)=chromo(chromo_candidate(j),rank);
        chromo_distance(j)=chromo(chromo_candidate(j),distance);
    end
    %取出低等级的个体索引
    minchromo_candidate=find(chromo_rank==min(chromo_rank));
    %多个索引按拥挤度排序
    if (length(minchromo_candidate)~=1)
        maxchromo_candidate=find(chromo_distance(minchromo_candidate)==max(chromo_distance(minchromo_candidate)));
        if(length(maxchromo_candidate)~=1)
            maxchromo_candidate = maxchromo_candidate(1);
        end
        chromo_parent(i,:)=chromo(chromo_candidate(minchromo_candidate(maxchromo_candidate)),:);
    else
        chromo_parent(i,:)=chromo(chromo_candidate(minchromo_candidate(1)),:);
    end
end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

SBX&Poly mutation

function chromo_offspring = cross_mutation( chromo_parent,f_num,x_num,x_min,x_max,pc,pm,yita1,yita2,fun )
%模拟二进制交叉与多项式变异
[pop,~]=size(chromo_parent);
suoyin=1;
for i=1:pop
    %%%模拟二进制交叉
    %初始化子代种群
    %随机选取两个父代个体
    parent_1=round(pop*rand(1));
    if (parent_1<1)
        parent_1=1;
    end
    parent_2=round(pop*rand(1));
    if (parent_2<1)
        parent_2=1;
    end
    %确定两个父代个体不是同一个
    while isequal(chromo_parent(parent_1,:),chromo_parent(parent_2,:))
        parent_2=round(pop*rand(1));
        if(parent_2<1)
            parent_2=1;
        end
    end
    chromo_parent_1=chromo_parent(parent_1,:);
    chromo_parent_2=chromo_parent(parent_2,:);
    off_1=chromo_parent_1;%将子代初始化为chromo_parent1
    off_2=chromo_parent_1;
    if(rand(1)<pc)
        %进行模拟二进制交叉
        u1=zeros(1,x_num);
        gama=zeros(1,x_num);
        for j=1:x_num
            u1(j)=rand(1);
            if u1(j)<0.5
                gama(j)=(2*u1(j))^(1/(yita1+1));
            else
                gama(j)=(1/(2*(1-u1(j))))^(1/(yita1+1));
            end
            off_1(j)=0.5*((1+gama(j))*chromo_parent_1(j)+(1-gama(j))*chromo_parent_2(j));
            off_2(j)=0.5*((1-gama(j))*chromo_parent_1(j)+(1+gama(j))*chromo_parent_2(j));
            %使子代在定义域内
            if(off_1(j)>x_max(j))
                off_1(j)=x_max(j);
            elseif(off_1(j)<x_min(j))
                off_1(j)=x_min(j);
            end
            if(off_2(j)>x_max(j))
                off_2(j)=x_max(j);
            elseif(off_2(j)<x_min(j))
                off_2(j)=x_min(j);
            end
        end
        %计算子代个体的目标函数值
        off_1(1,(x_num+1):(x_num+f_num))=object_fun(off_1,f_num,x_num,fun);
        off_2(1,(x_num+1):(x_num+f_num))=object_fun(off_2,f_num,x_num,fun);
    end
    %%%多项式变异
    if(rand(1)<pm)
        u2=zeros(1,x_num);
        delta=zeros(1,x_num);
        for j=1:x_num
            u2(j)=rand(1);
            if(u2(j)<0.5)
                delta(j)=(2*u2(j))^(1/(yita2+1))-1;
            else
                delta(j)=1-(2*(1-u2(j)))^(1/(yita2+1));
            end
            off_1(j)=off_1(j)+delta(j);
            %使子代在定义域内
            if(off_1(j)>x_max(j))
                off_1(j)=x_max(j);
            elseif(off_1(j)<x_min(j))
                off_1(j)=x_min(j);
            end
        end
        %计算子代个体的目标函数值
        off_1(1,(x_num+1):(x_num+f_num))=object_fun(off_1,f_num,x_num,fun);
    end
    if(rand(1)<pm)
        u2=zeros(1,x_num);
        delta=zeros(1,x_num);
        for j=1:x_num
            u2(j)=rand(1);
            if(u2(j)<0.5)
                delta(j)=(2*u2(j))^(1/(yita2+1))-1;
            else
                delta(j)=1-(2*(1-u2(j)))^(1/(yita2+1));
            end
            off_2(j)=off_2(j)+delta(j);
            %使子代在定义域内
            if(off_2(j)>x_max(j))
                off_2(j)=x_max(j);
            elseif(off_2(j)<x_min(j))
                off_2(j)=x_min(j);
            end
        end
        %计算子代个体的目标函数值
        off_2(1,(x_num+1):(x_num+f_num))=object_fun(off_2,f_num,x_num,fun);
    end
    off(suoyin,:)=off_1;
    off(suoyin+1,:)=off_2;
    suoyin=suoyin+2;
end
chromo_offspring=off;
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105

精英策略选择

function chromo = elitism( pop,combine_chromo2,f_num,x_num )
%% 精英保留策略
%总体思路——依照文中定义的偏序关系:
%先按照Pareto等级选取子代,最后在同一等级中按照拥挤度选取子代
%% 根据pareto等级从高到低进行排序
[pop2,temp]=size(combine_chromo2);
chromo_rank=zeros(pop2,temp);
chromo=zeros(pop,(f_num+x_num+2)); %初始化存放排序后种群的矩阵
[~,index_rank]=sort(combine_chromo2(:,f_num+x_num+1));
for i=1:pop2
    chromo_rank(i,:)=combine_chromo2(index_rank(i),:);
end
%求出最高的pareto等级
max_rank=max(combine_chromo2(:,f_num+x_num+1));
%% 形成子代
%根据排序后的顺序,将等级相同的种群整个放入父代种群中,直到某一层不能全部放下为止
prev_index=0;
for i=1:max_rank
    %寻找当前等级i个体里的最大索引
    current_index=max(find(chromo_rank(:,(f_num+x_num+1))==i));
    %不能放下为止
    if(current_index>pop)
        %剩余群体数
        remain_pop=pop-prev_index;
        %等级为i的个体
        temp=chromo_rank(((prev_index+1):current_index),:);
        %根据拥挤度从大到小排序
        [~,index_crowd]=sort(temp(:,(f_num+x_num+2)),'descend');
        %填满父代
        for j=1:remain_pop
            chromo(prev_index+j,:)=temp(index_crowd(j),:);
        end
        return;
    elseif(current_index<pop)
        % 将所有等级为i的个体直接放入父代种群
        chromo(((prev_index+1):current_index),:)=chromo_rank(((prev_index+1):current_index),:);
    else
        % 将所有等级为i的个体直接放入父代种群
        chromo(((prev_index+1):current_index),:)=chromo_rank(((prev_index+1):current_index),:);
        return;
    end
    prev_index = current_index;
end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

目标函数

function f = object_fun( x,f_num,x_num,fun )
%   测试函数的设置
% --------------------ZDT1--------------------
if strcmp(fun,'ZDT1')
    f=[];
    f(1)=x(1);
    sum=0;
    for i=2:x_num
        sum = sum+x(i);
    end
    g=1+9*(sum/(x_num-1));
    f(2)=g*(1-(f(1)/g)^0.5);
end
% --------------------ZDT2--------------------
if strcmp(fun,'ZDT2')
    f=[];
    f(1)=x(1);
    sum=0;
    for i=2:x_num
        sum = sum+x(i);
    end
    g=1+9*(sum/(x_num-1));
    f(2)=g*(1-(f(1)/g)^2);
end
% --------------------ZDT3--------------------
if strcmp(fun,'ZDT3')
    f=[];
    f(1)=x(1);
    sum=0;
    for i=2:x_num
        sum = sum+x(i);
    end
    g=1+9*(sum/(x_num-1));
    f(2)=g*(1-(f(1)/g)^0.5-(f(1)/g)*sin(10*pi*f(1)));
end
% --------------------ZDT4--------------------
if strcmp(fun,'ZDT4')
    f=[];
    f(1)=x(1);
    sum=0;
    for i=2:x_num
        sum = sum+(x(i)^2-10*cos(4*pi*x(i)));
    end
    g=1+9*10+sum;
    f(2)=g*(1-(f(1)/g)^0.5);
end
% --------------------ZDT6--------------------
if strcmp(fun,'ZDT6')
    f=[];
    f(1)=1-(exp(-4*x(1)))*((sin(6*pi*x(1)))^6);
    sum=0;
    for i=2:x_num
        sum = sum+x(i);
    end
    g=1+9*((sum/(x_num-1))^0.25);
    f(2)=g*(1-(f(1)/g)^2);
end
% --------------------------------------------
% --------------------DTLZ1--------------------
if strcmp(fun,'DTLZ1')
    f=[];
    sum=0;
    for i=3:x_num
        sum = sum+((x(i)-0.5)^2-cos(20*pi*(x(i)-0.5)));
    end
    g=100*(x_num-2)+100*sum;
    f(1)=(1+g)*x(1)*x(2);
    f(2)=(1+g)*x(1)*(1-x(2));
    f(3)=(1+g)*(1-x(1));
end
% --------------------------------------------
% --------------------DTLZ2--------------------
if strcmp(fun,'DTLZ2')
    f=[];
    sum=0;
    for i=3:x_num
        sum = sum+(x(i))^2;
    end
    g=sum;
    f(1)=(1+g)*cos(x(1)*pi*0.5)*cos(x(2)*pi*0.5);
    f(2)=(1+g)*cos(x(1)*pi*0.5)*sin(x(2)*pi*0.5);
    f(3)=(1+g)*sin(x(1)*pi*0.5);
end
% --------------------------------------------
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

参考链接及更多代码

本文参考代码:

  • 相应博客:多目标优化算法(一)NSGA-Ⅱ(NSGA2);
  • 源代码下载链接:NSGA-II代码算法贴合原文,优化效果适中,运行时间有些长。改变迭代次数、分布参数等可能会获得更好的结果。可以完成对ZDT1~ZDT4、ZDT6、DTLZ1、DTLZ2六个函数的优化。源代码扩充了性能评价指标(收敛性)的计算及保存等操作。

更多优秀代码:

  • Matlab编写多目标优化算法NSGA-Ⅱ的详解以及论文详解_针对ZDT1:在保持与其他算法相同迭代次数的前提下,运行速度最快且优化结果最好。代码使用的是改进的deductive sort,随机选择和正态分布交叉NDX,与原文不一致。 结合本文参考代码改动后也可以完成对其他测试函数的优化,运行速度快且很好贴合PF。
  • NSGA2算法MATLAB实现(能够自定义优化函数)算法基本贴合原文个人感觉交叉变异应该是针对同一父代操作的,代码中交叉选择了两个父代进行,变异又选择了第三个父代。代码也是以ZDT1举例的,改动代码也可以适应其他函数,但是结果不太贴合PF
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/207789
推荐阅读
相关标签
  

闽ICP备14008679号