NSGA-II:一种快速精英多目标遗传算法


在这里插入图片描述

PS:本文非常经典的NSGA-II:A fast and elitist multiobjective genetic algorithm: NSGA-II来自《IEEE Transactions on Evolutionary Computation》,目前Google学术引用5w+~

1.摘要

使用非支配排序和共享的多目标进化算法(EAs)受到的主要批评有:1)计算复杂度 O ( M N 3 ) O(MN^3) O(MN3)(其中 M M M为目标数量, N N N为种群规模);2)非精英主义方法;3)需要指定共享参数。在本文中,我们提出了一种基于非支配排序的多目标进化算法(MOEA),称为非支配排序遗传算法 II(NSGA-II),该算法缓解了上述三种困难。NSGA-II提出了一种计算复杂度为 O ( M N 2 ) O(MN^2) O(MN2)的快速非支配排序方法,还提出了一种选择算子,通过结合父代和子代种群来创建配对池,并选择最优(在适应度和分布方面)解决方案。

2.NSGA-Ⅱ

2.1 非支配排序方法

非支配排序方法通过比较种群中个体之间的支配关系,将个体分为不同的前沿层次。
a.初始化,对每个个体初始化支配集合和被支配计数;
b.计算支配关系,通过双重循环比较每对个体,更新其支配关系。如果一个个体支配另一个个体,就将其添加到支配集合中,并增加被支配计数;
c.构建第一层前沿,识遍历种群,找出被支配计数为0的个体(即不被其他任何个体支配的个体),将这些个体加入第一层前沿;
d.迭代构建后续前沿,初始化一个空的集合 Q 用于存储下一个层次的个体。对当前前沿层中的每个个体,更新其支配的个体的被支配计数。如果某个被支配个体的被支配计数减为0,则将其加入集合 Q 并赋予新的层次排名。重复此过程,直到没有更多个体可以加入新的层次;
e.终止条件,当没有新的个体可以被加入到下一个层次时,算法结束。

% 非支配排序方法
function [pop, F] = NonDominatedSorting(pop)

    % 获取种群的大小
    nPop = numel(pop);

    % 初始化每个个体的支配集合和被支配计数
    for i = 1:nPop
        pop(i).DominationSet = [];  % 支配集合初始化为空
        pop(i).DominatedCount = 0;   % 被支配计数初始化为0
    end
    
    F{1} = [];  % 初始化第一层前沿

    % 计算每个个体之间的支配关系
    for i = 1:nPop
        for j = i + 1:nPop
            p = pop(i);  % 当前个体p
            q = pop(j);  % 另一个体q
            
            if Dominates(p, q)  % 如果p支配q
                p.DominationSet = [p.DominationSet j];  % 将j加入p的支配集合
                q.DominatedCount = q.DominatedCount + 1;  % q的被支配计数加1
            end
            
            if Dominates(q.Cost, p.Cost)  % 如果q支配p
                q.DominationSet = [q.DominationSet i];  % 将i加入q的支配集合
                p.DominatedCount = p.DominatedCount + 1;  % p的被支配计数加1
            end
            
            pop(i) = p;  % 更新个体p
            pop(j) = q;  % 更新个体q
        end
        
        % 将不被支配的个体加入第一层前沿
        if pop(i).DominatedCount == 0
            F{1} = [F{1} i];  % 将i加入第一层前沿
            pop(i).Rank = 1;  % 赋予个体rank为1
        end
    end
    
    k = 1;  % 初始化前沿层次

    while true
        
        Q = [];  % 初始化下一个层次的集合
        
        % 遍历当前层次的个体
        for i = F{k}
            p = pop(i);  % 当前个体p
            
            % 更新其支配的个体
            for j = p.DominationSet
                q = pop(j);  % 被支配的个体q
                
                q.DominatedCount = q.DominatedCount - 1;  % 被支配计数减1
                
                % 如果q现在不被任何个体支配,加入下一个层次
                if q.DominatedCount == 0
                    Q = [Q j]; %#ok
                    q.Rank = k + 1;  % 赋予个体rank为k+1
                end
                
                pop(j) = q;  % 更新个体q
            end
        end
        
        % 如果没有更多个体加入下一个层次,结束循环
        if isempty(Q)
            break;
        end
        
        F{k + 1} = Q; %#ok  % 将下一个层次的个体加入前沿
        k = k + 1;  % 层次加1
        
    end
end

2.2 计算拥挤度

拥挤度是用于评估个体在目标空间中的“拥挤程度”,其目的是在选择过程中保持种群的多样性。在多目标优化中,拥挤度越高的个体被认为在目标空间中更具代表性,因为它们在目标值上分布得更广泛。通过计算个体在目标空间中的距离,可以有效避免选择相似的个体,从而增强解的多样性。

% 计算拥挤度
function pop = CalcCrowdingDistance(pop, F)

    % 获取前沿层的数量
    nF = numel(F);
    
    % 遍历每一层前沿
    for k = 1:nF
        
        % 获取当前前沿中个体的成本值
        Costs = [pop(F{k}).Cost];
        
        % 获取目标数量
        nObj = size(Costs, 1);
        
        % 获取当前前沿个体数量
        n = numel(F{k});
        
        % 初始化距离矩阵
        d = zeros(n, nObj);
        
        % 计算每个目标的拥挤距离
        for j = 1:nObj
            
            % 对成本值进行排序
            [cj, so] = sort(Costs(j, :));
            
            % 设定最小和最大个体的拥挤距离为无穷大
            d(so(1), j) = inf;  
            
            % 计算中间个体的拥挤距离
            for i = 2:n-1
                
                d(so(i), j) = abs(cj(i + 1) - cj(i - 1)) / abs(cj(1) - cj(end));
                
            end
            
            % 设定最后一个个体的拥挤距离为无穷大
            d(so(end), j) = inf;
            
        end
        
        % 将计算的拥挤距离存储回个体中
        for i = 1:n
            
            pop(F{k}(i)).CrowdingDistance = sum(d(i, :));  % 汇总所有目标的拥挤距离
           
        end     
    end
end

2.3 种群排序

NSGA-II首先将种群按拥挤距离降序排列,以保持种群的多样性;然后再按非支配排名排序,确保优先选择非支配个体。

function [pop, F] = SortPopulation(pop)
    % 按照拥挤距离降序排序种群
    [~, CDSO] = sort([pop.CrowdingDistance], 'descend'); 
    pop = pop(CDSO); 

    % 按照排名(非支配等级)对种群进行排序
    [~, RSO] = sort([pop.Rank]); 
    pop = pop(RSO); 
    
    % 更新前沿
    Ranks = [pop.Rank]; 
    MaxRank = max(Ranks); 
    F = cell(MaxRank, 1); 
    for r = 1:MaxRank
        F{r} = find(Ranks == r); % 找到当前排名中个体的索引
    end
end

3.结果展示

在这里插入图片描述

在这里插入图片描述

4.参考文献

[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.

5.代码获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小O的算法实验室

谢谢大佬的肯定!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值