zoukankan      html  css  js  c++  java
  • 多目标优化算法(一)NSGA-Ⅱ(NSGA2)(转载)

    多目标优化算法(一)NSGA-Ⅱ(NSGA2)

    本文链接:https://blog.csdn.net/qq_40434430/article/details/82876572
    多目标优化算法(一)NSGA-Ⅱ(NSGA2)
    注:没有想到这篇博客竟然有很多人查看,这是我去年写的算法,里面难免会有一些错误,大家可以看看评论区,这里的matlab代码写的不太好,是以C语言思维写的,基本上没有并行,初学者建议可以看看platEMO上的源代码,提前培养好写代码的习惯!

    0. 前言
    这个算法是本人接触科研学习实现的第一个算法,因此想在这里和大家分享一下心得。

    1. 算法简介
    NSGA-Ⅱ算法,即带有精英保留策略的快速非支配多目标优化算法,是一种基于Pareto最优解的多目标优化算法。

    1.1 Pareto支配关系以及Pareto等级
    Pareto支配关系:对于最小化多目标优化问题,对于n个目标分量 fi(x),i=1...n f_i(x), i=1...nf
    i

    (x),i=1...n,任意给定两个决策变量Xa X_aX
    a

    ,Xb X_bX
    b

    ,如果有以下两个条件成立,则称Xa X_aX
    a

    支配Xb X_bX
    b


    1.对于∀i∈1,2,...,n forall i in {1,2,...,n}∀i∈1,2,...,n,都有fi(Xa)≤fi(Xb) f_i(X_a) leq f_i(X_b)f
    i

    (X
    a

    )≤f
    i

    (X
    b

    )成立。
    2.∃i∈1,2,...,n exists i in {1,2,...,n}∃i∈1,2,...,n,使得fi(Xa)<fi(Xb) f_i(X_a) <f_i(X_b)f
    i

    (X
    a

    )<f
    i

    (X
    b

    )成立。
    如果对于一个决策变量,不存在其他决策变量能够支配他,那么就称该决策变量为非支配解。
    Pareto等级:在一组解中,非支配解Pareto等级定义为1,将非支配解从解的集合中删除,剩下解的Pareto等级定义为2,依次类推,可以得到该解集合中所有解的Pareto等级。示意图如图1所示。


    1.2 快速非支配排序
    假设种群大小为P,该算法需要计算每个个体p的被支配个数np n_pn
    p

    和该个体支配的解的集合Sp S_pS
    p

    这两个参数。遍历整个种群,该参数的计算复杂度为O(mN2) O(mN^2)O(mN
    2
    )。该算法的伪代码如下:
    1.计算出种群中每个个体的两个参数np n_pn
    p

    和Sp S_pS
    p


    2.将种群中参数np=0 n_p=0n
    p

    =0的个体放入集合F1 F_1F
    1

    中。
    3.for 个体i∈F1 i in F_1i∈F
    1

    :
            for 个体l∈Si l in S_il∈S
    i


                   nl=nl−1 n_l=n_l-1n
    l

    =n
    l

    −1;(该步骤即消除Pareto等级1对其余个体的支配,相当于将Pareto等级1的个体从集合中删除)
                    if nl=0 n_l=0n
    l

    =0:
                           将个体l加入集合F2 F_2F
    2

    中。
                    end
            end
    end
    4.上面得到Pareto等级2的个体的集合F2 F_2F
    2

    ,对集合F2 F_2F
    2

    中的个体继续重复步骤3,依次类推直到种群等级被全部划分。
    matlab 代码如下:

    function [F,chromo] = non_domination_sort( pop,chromo,f_num,x_num )
    %non_domination_sort 初始种群的非支配排序和计算拥挤度
    %初始化pareto等级为1
    pareto_rank=1;
    F(pareto_rank).ss=[];%pareto等级为pareto_rank的集合
    p=[];%每个个体p的集合
    for i=1:pop
    %%%计算出种群中每个个体p的被支配个数n和该个体支配的解的集合s
    p(i).n=0;%被支配个体数目n
    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)%if(less==0 && greater~=0)
    p(i).n=p(i).n+1;%被支配个体数目n+1
    elseif(greater==0 && equal~=f_num)%elseif(greater==0 && less~=0)
    p(i).s=[p(i).s j];
    end
    end
    %%%将种群中参数为n的个体放入集合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
    %%%求pareto等级为pareto_rank+1的个体
    while ~isempty(F(pareto_rank).ss)
    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)
    p(p(F(pareto_rank).ss(i)).s(j)).n=p(p(F(pareto_rank).ss(i)).s(j)).n - 1;%nl=nl-1
    if p(p(F(pareto_rank).ss(i)).s(j)).n==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)];
    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
    1.3 拥挤度
    为了使得到的解在目标空间中更加均匀,这里引入了拥挤度nd n_dn
    d

    ,其算法如下:

    令参数nd=0,n∈1…N n_d=0,n∈1…Nn
    d

    =0,n∈1…N。
    for 每个目标函数fm f_mf
    m


            ① 根据该目标函数对该等级的个体进行排序,记fmaxm f_m^{max}f
    m
    max

    为个体目标函数值fm f_mf
    m

    的最大值,fminm f_m^{min}f
    m
    min

    为个体目标函数值fm f_mf
    m

    的最小值;
            ② 对于排序后两个边界的拥挤度1d 1_d1
    d

    和Nd N_dN
    d

    置为∞;
            ③ 计算nd=nd+(fm(i+1)−fm(i−1))/(fmaxm−fminm) n_d=n_d+(f_m (i+1)-f_m (i-1))/(f_m^{max}-f_m^{min})n
    d

    =n
    d

    +(f
    m

    (i+1)−f
    m

    (i−1))/(f
    m
    max

    −f
    m
    min

    ),其中fm(i+1) f_m (i+1)f
    m

    (i+1)是该个体排序后后一位的目标函数值。
        end

          从二目标优化问题来看,就像是该个体在目标空间所能生成的最大的矩形(该矩形不能触碰目标空间其他的点)的边长之和。拥挤度示意图如图2所示。

    matlab代码如下:

    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的循环时多了一次空,所以减掉
    %%拥挤度初始化为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
    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
    %多个目标函数拥挤度求和
    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;
    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
    1.4 精英保留策略
    1.首先将父代种群Ci C_iC
    i

    和子代种群Di D_iD
    i

    合成种群Ri R_iR
    i


    2.根据以下规则从种群Ri R_iR
    i

    生成新的父代种群Ci+1 C_{i+1}C
    i+1


          ①根据Pareto等级从低到高的顺序,将整层种群放入父代种群Ci+1 C_{i+1}C
    i+1

    ,直到某一层该层个体不能全部放入父代种群Ci+1 C_{i+1}C
    i+1


          ②将该层个体根据拥挤度从大到小排列,依次放入父代种群Ci+1 C_{i+1}C
    i+1

    中,直到父代种群Ci+1 C_{i+1}C
    i+1

    填满。
    matlab代码如下:

    function chromo = elitism( pop,combine_chromo2,f_num,x_num )
    %精英保留策略
    [pop2,temp]=size(combine_chromo2);
    chromo_rank=zeros(pop2,temp);
    chromo=zeros(pop,(f_num+x_num+2));
    %根据pareto等级从高到低进行排序
    [~,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
    1.5 实数编码的交叉操作(SBX)
    模拟二进制交叉:
    x1j(t)=0.5×[(1+γj)x1j(t)+(1−γj)x2j(t)] x _{1j}(t)=0.5×[(1+γ_j ) x_{1j}(t)+(1-γ_j ) x_{2j} (t)]
    x
    1j

    (t)=0.5×[(1+γ
    j

    )x
    1j

    (t)+(1−γ
    j

    )x
    2j

    (t)]

    x2j(t)=0.5×[(1−γj)x1j(t)+(1+γj)x2j(t)] x _{2j} (t)=0.5×[(1-γ_j ) x_{1j}(t)+(1+γ_j ) x_{2j}(t)]
    x
    2j

    (t)=0.5×[(1−γ
    j

    )x
    1j

    (t)+(1+γ
    j

    )x
    2j

    (t)]

    其中
    γj={(2uj)1/(η+1)uj<0.5(1/(2(1−uj))1/(η+1)else γ_j=left{egin{matrix}(2u_j)^{1/(η+1)};;;;;;;;;;;;u_j<0.5\ (1/(2(1-u_j))^{1/(η+1)};;;;elseend{matrix} ight.
    γ
    j

    ={
    (2u
    j

    )
    1/(η+1)
    u
    j

    <0.5
    (1/(2(1−u
    j

    ))
    1/(η+1)
    else

    1.6 多项式变异(polynomial mutation)
    多项式变异:
    x1j(t)=x1j(t)+Δj x _{1j} (t)=x_{1j} (t)+∆_j
    x
    1j

    (t)=x
    1j

    (t)+∆
    j

    其中
    Δj={(2uj)1/(η+1)−1uj<0.5(1−(2(1−uj))1/(η+1)else ∆_j=left{egin{matrix}(2u_j)^{1/(η+1)}-1;;;;;;;;;;;;u_j<0.5\ (1-(2(1-u_j))^{1/(η+1)};;;;elseend{matrix} ight.

    j

    ={
    (2u
    j

    )
    1/(η+1)
    −1u
    j

    <0.5
    (1−(2(1−u
    j

    ))
    1/(η+1)
    else

    并且0≤uj u_ju
    j

    ≤1。
    matlab代码如下:

    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;
    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
    1.7 竞标赛选择(tournament selection)
    锦标赛法是选择操作的一种常用方法,二进制竞标赛用的最多。
    假设种群规模为N,该法的步骤为:
    1.从这N个个体中随机选择k(k<n)个个体,k的取值小,效率就高(节省运行时间),但不宜太小,一般取为n/2(取整)。(二进制即取2)
    2.根据每个个体的适应度值,选择其中适应度值最好的个体进入下一代种群。
    3.重复1-2步,至得到新的N个个体。
    二进制选择的matlab代码如下:

    function chromo_parent = tournament_selection( chromo )
    %二进制竞标赛
    [pop, suoyin] = 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,suoyin);
    % 获取等级的索引
    rank = suoyin - 1;
    % 获得拥挤度的索引
    distance = suoyin;
    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
    2. 算法实现框图
    NSGA-Ⅱ算法的基本思想为:首先,随机产生规模为N的初始种群,非支配排序后通过遗传算法的选择、交叉、变异三个基本操作得到第一代子代种群;其次,从第二代开始,将父代种群与子代种群合并,进行快速非支配排序,同时对每个非支配层中的个体进行拥挤度计算,根据非支配关系以及个体的拥挤度选取合适的个体组成新的父代种群;最后,通过遗传算法的基本操作产生新的子代种群:依此类推,直到满足程序结束的条件。该算法的流程图如图3所示。

    初始化matlab代码如下:

    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
    主程序matlab代码如下:

    %---------------------------------------------------------------------
    %程序功能:实现nsga2算法,测试函数为ZDT1,ZDT2,ZDT3,ZDT4,ZDT6,DTLZ1,DTLZ2
    %说明:遗传算子为二进制竞赛选择,模拟二进制交叉和多项式变异
    % 需要设置的参数:pop,gen,pc,pm,yita1,yita2
    %作者:(晓风)
    %最初建立时间:2018.9.3
    %最近修改时间:2018.9.20
    %----------------------------------------------------------
    clear all
    clc
    tic;
    %参数设置
    fun='DTLZ1';
    funfun;%函数选择
    pop=300;%种群大小100
    gen=250;%250进化代数
    pc=1;%交叉概率
    pm=1/x_num;%变异概率
    % yita1=1;%模拟二进制交叉参数
    % yita2=10;%多项式变异参数
    yita1=2;%模拟二进制交叉参数10
    yita2=5;%多项式变异参数50

    %%初始化种群
    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
    %%二进制竞赛选择(k取了pop/2,所以选两次)
    chromo_parent_1 = tournament_selection(chromo);
    chromo_parent_2 = tournament_selection(chromo);
    chromo_parent=[chromo_parent_1;chromo_parent_2];
    %%模拟二进制交叉与多项式变异
    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! ',i);
    end
    end
    toc;
    aaa=toc;

    hold on
    if(f_num==2)
    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
    %%--------------------delta度量--------------------------------
    % [~,index_f1]=sort(chromo(:,x_num+1));
    % d=zeros(length(chromo)-1,1);
    % for i=1:(length(chromo)-1)
    % d(i)=((chromo(index_f1(i),x_num+1)-chromo(index_f1(i+1),x_num+1))^2+(chromo(index_f1(i),x_num+2)-chromo(index_f1(i+1),x_num+2))^2)^0.5;
    % end
    % d_mean1=mean(d);
    % d_mean=d_mean1*ones(length(chromo)-1,1);
    % d_sum=sum(abs(d-d_mean));
    % delta=(d(1)+d(length(chromo)-1)+d_sum)/(d(1)+d(length(chromo)-1)+(length(chromo)-1)*d_mean1);
    % disp(delta);
    %mean(a)
    %(std(a))^2
    %--------------------Coverage(C-metric)---------------------
    A=PP;B=chromo(:,(x_num+1):(x_num+f_num));%%%%%%%%%%%%%%%%%%%
    [temp_A,~]=size(A);
    [temp_B,~]=size(B);
    number=0;
    for i=1:temp_B
    nn=0;
    for j=1:temp_A
    less=0;%当前个体的目标函数值小于多少个体的数目
    equal=0;%当前个体的目标函数值等于多少个体的数目
    for k=1:f_num
    if(B(i,k)<A(j,k))
    less=less+1;
    elseif(B(i,k)==A(j,k))
    equal=equal+1;
    end
    end
    if(less==0 && equal~=f_num)
    nn=nn+1;%被支配个体数目n+1
    end
    end
    if(nn~=0)
    number=number+1;
    end
    end
    C_AB=number/temp_B;
    disp("C_AB:");
    disp(C_AB);
    %-----Distance from Representatives in the PF(D-metric)-----
    A=chromo(:,(x_num+1):(x_num+f_num));P=PP;%%%%%%与论文公式保持相同,注意A和上述不一样
    [temp_A,~]=size(A);
    [temp_P,~]=size(P);
    min_d=0;
    for v=1:temp_P
    d_va=(A-repmat(P(v,:),temp_A,1)).^2;
    min_d=min_d+min(sqrt(sum(d_va,2)));
    end
    D_AP=(min_d/temp_P);
    disp("D_AP:");
    disp(D_AP);
    filepath=pwd;
    cd('E:GAMOEA DMOEAD_王超 sga2对比算子修改DTLZ1');
    save C_AB4.txt C_AB -ASCII
    save D_AP4.txt D_AP -ASCII
    save solution4.txt chromo -ASCII
    save toc4.txt aaa -ASCII
    cd(filepath);
    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
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    3. 实验结果
    本文使用实数编码的模拟二进制交叉和多项式变异,交叉概率pc=0.9 p_c=0.9p
    c

    =0.9,变异概率pm=1/n p_m=1/np
    m

    =1/n,ηc=20 η_c=20η
    c

    =20,ηm=20 η_m=20η
    m

    =20。以下为选取的5个非凸非均匀的多目标函数的运行结果如图4到图8所示。
    函数范围的matlab代码如下:

    %测试函数
    %--------------------ZDT1--------------------
    if strcmp(fun,'ZDT1')
    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
    %--------------------------------------------
    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
    函数的matlab代码如下:

    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
    3.1 ZDT1
    f1=x1 f_1=x_1
    f
    1

    =x
    1

    g=1+9((∑ni=2xi)/(n−1)) g=1+9((∑_{i=2}^nx_i )/(n-1))
    g=1+9((
    i=2

    n

    x
    i

    )/(n−1))

    f2=g(1−(f1/g)0.5).n=30,xi∈[0,1] f_2=g(1-(f_1/g)^{0.5} ).n=30,x_i∈[0,1]
    f
    2

    =g(1−(f
    1

    /g)
    0.5
    ).n=30,x
    i

    ∈[0,1]

    选取种群大小为500,迭代次数500次,pc=0.9,pm=1/30,ηc=20,ηm=20,得到结果如图4(上)所示。
    选取种群大小为100,迭代次数2000次,pc=0.9,pm=1/30,ηc=20,ηm=20,得到结果如图4(下)所示。


    图4 ZDT1 pareto最优解对比图(绿色为理论值,红色为实验值)

    3.2 ZDT2
    f1=x1 f_1=x_1
    f
    1

    =x
    1

    g=1+9((∑ni=2xi)/(n−1)) g=1+9((∑_{i=2}^n x_i )/(n-1))
    g=1+9((
    i=2

    n

    x
    i

    )/(n−1))

    f2=g(1−(f1/g)2).n=30,xi∈[0,1] f_2=g(1-(f_1/g)^2 ).n=30,x_i∈[0,1]
    f
    2

    =g(1−(f
    1

    /g)
    2
    ).n=30,x
    i

    ∈[0,1]

    选取种群大小为500,迭代次数500次,pc=0.9,pm=1/30,ηc=20,ηm=20,得到结果如图5(上)所示。
    选取种群大小为100,迭代次数2000次,pc=0.9,pm=1/30,ηc=20,ηm=20,得到结果如图5(下)所示。


    图5 ZDT2 pareto最优解对比图(绿色为理论值,红色为实验值)

    3.3 ZDT3
    f1=x1 f_1=x_1
    f
    1

    =x
    1

    g=1+9((∑ni=2xi)/(n−1)) g=1+9((∑_{i=2}^nx_i )/(n-1))
    g=1+9((
    i=2

    n

    x
    i

    )/(n−1))

    f2=g(1−(f1/g)0.5−(f1/g)sin(10πf1)).n=30,xi∈[0,1] f_2=g(1-(f_1/g)^{0.5}-(f_1/g)sin⁡(10πf_1)).n=30,x_i∈[0,1]
    f
    2

    =g(1−(f
    1

    /g)
    0.5
    −(f
    1

    /g)sin⁡(10πf
    1

    )).n=30,x
    i

    ∈[0,1]

    选取种群大小为136,迭代次数500次,pc=0.9,pm=1/30,ηc=20,ηm=20,得到结果如图6示。
    选取种群大小为136,迭代次数2000次,pc=0.9,pm=1/30,ηc=20,ηm=20,得到结果如图6示。


    图6 ZDT3 pareto最优解对比图(绿色为理论值,红色为实验值)

    3.4 ZDT4
    f1=x1 f_1=x_1
    f
    1

    =x
    1

    g=1+9∗10+∑ni=2((xi)2−10cos(4πxi)) g=1+9*10+∑_{i=2}^n( (x_i )^2-10cos⁡(4πx_i))
    g=1+9∗10+
    i=2

    n

    ((x
    i

    )
    2
    −10cos⁡(4πx
    i

    ))

    f2=g(1−(f1/g)0.5).n=10,x1∈[0,1];x(2…6)∈[−5,5] f_2=g(1-(f_1/g)^{0.5} ).n=10,x_1∈[0,1];x_(2…6)∈[-5,5]
    f
    2

    =g(1−(f
    1

    /g)
    0.5
    ).n=10,x
    1

    ∈[0,1];x
    (

    2…6)∈[−5,5]

    选取种群大小为100,迭代次数500次,pc=0.9,pm=0.1,ηc=20,ηm=10,得到结果如图7(上)所示。
    选取种群大小为100,迭代次数2000次,pc=0.9,pm=0.1,ηc=20,ηm=10,得到结果如图7(下)所示。


    图7 ZDT4 pareto最优解对比图(绿色为理论值,红色为实验值)

    3.5 ZDT6
    f1=1−e−4x1sin6(6πx1) f_1=1-e^{-4x_1} sin^6 (6πx_1)
    f
    1

    =1−e
    −4x
    1


    sin
    6
    (6πx
    1

    )

    g=1+9((∑ni=2xi)/(n−1))0.25 g=1+9((∑_{i=2}^nx_i )/(n-1))^{0.25}
    g=1+9((
    i=2

    n

    x
    i

    )/(n−1))
    0.25

    f2=g(1−(f1/g)2).n=10,xi∈[0,1] f_2=g(1-(f_1/g)^2 ).n=10,x_i∈[0,1]
    f
    2

    =g(1−(f
    1

    /g)
    2
    ).n=10,x
    i

    ∈[0,1]

    选取种群大小为100,迭代次数500次,pc=0.9,pm=0.1,ηc=20,ηm=20,得到结果如图8(上)所示。
    选取种群大小为100,迭代次数2000次,pc=0.9,pm=0.1,ηc=20,ηm=20,得到结果如图8(下)所示。


    图8 ZDT6 pareto最优解对比图(绿色为理论值,红色为实验值)
    从结果中可以看出,除ZDT4以外,找到的解几乎全部是pareto前端上的点,并且解在目标空间上分布十分均匀,该算法对于非凸非均匀的多目标函数最优解的寻找还是十分有效的。由于ZDT4具有许多局部pareto最优前沿,为了摆脱这些局部前沿,需要对决策向量进行大的改变,因此选取ηm=10,但仍离真正的pareto前沿还有很大的差距。

    3.6 对比
    表1 γ的均值和方差(500代)

    项目 ZDT1 ZDT2 ZDT3 ZDT4 ZDT6
    均值 0.0532 0.0972 0.1712 20.2304 0.3284
    方差 0.0021 0.0051 0.0048 0.6310 0.0109
    表2 Δ的均值和方差(500代)

    项目 ZDT1 ZDT2 ZDT3 ZDT4 ZDT6
    均值 0.4575 0.4615 0.6640 0.5203 0.9538
    方差 0.0021 0.0015 0.0030 0.0013 0.0055
    表3 γ的均值和方差(2000代)

    项目 ZDT1 ZDT2 ZDT3 ZDT4 ZDT6
    均值 0.0011 0.0027 0.0225 12.0341 0.2092
    方差 0.0002 0.0002 0.0005 0.3320 0.0021
    表4 Δ的均值和方差(2000代)

    项目 ZDT1 ZDT2 ZDT3 ZDT4 ZDT6
    均值 0.4478 0.4337 0.6586 0.5168 0.4529
    方差 0.0001 0.0003 0.0006 0.0018 0.0001
    根据上述实验数据,进行五组实验,计算distance metric γ,diversity metric Δ的均值和方差,迭代500次后得到结果如表格1-2所示。迭代2000次后得到的结果如表格3-4所示。
          表1显示了NSGA-Ⅱ(实数编码500代)在5个问题上运行获得的distance metric γ的均值和方差,实验结果表明,除了ZDT4和ZDT6以外的问题均取得了良好的收敛效果,除ZDT4以外,其他问题5次运行结果的差异也都很小。
          表2显示了NSGA-Ⅱ(实数编码500代)在5个问题上运行获得的diversity metric Δ的均值和方差,实验结果表明,NSGA-Ⅱ在上述问题上均具有较强的传播多样性,并且5次运行结果的差异都很小。
          像500代的时候一样保留所有其他参数,但将代数增加至2000代,得到表3的distance metric γ的均值和方差以及表4的diversity metric Δ的均值和方差。将表3表4与表1表2对比可知,5个问题的distance metric γ随着代数的增加都有改善,其中ZDT3和ZDT4的改善尤为显著,除此之外,因为在500代时问题的结果已经有了良好的多样性分布了,所以代数的增加并没有对diversity metric Δ产生巨大的影响。
    [1]:Deb K, Pratap A, Agarwal S, et al. A fast and elitist multiobjective genetic algorithm: NSGA-II[J]. IEEE Transactions on Evolutionary Computation, 2002, 6(2):182-197.


    ————————————————
    版权声明:本文为CSDN博主「晓风wangchao」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_40434430/article/details/82876572

  • 相关阅读:
    COJ979 WZJ的数据结构(负二十一)
    COJ980 WZJ的数据结构(负二十)
    奇怪的错误
    COJ883 工艺品
    COJ885 LCS???
    COJ559 回文
    hdu1505(dp求最大子矩阵)
    hdu1506(dp求最大子矩阵)
    hdu2569(递推dp)
    hdu1081(最大子矩阵)
  • 原文地址:https://www.cnblogs.com/Vae1990Silence/p/11966540.html
Copyright © 2011-2022 走看看