热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

NSGAII算法详解

3NSGA-II3.1算法流程确定种群大小n,交叉概率t,迭代次数g随机产生n个个体,它们整体视为种群Pfori1togP∅for

3 NSGA-II


3.1 算法流程

确定种群大小 n,交叉概率 t,迭代次数 g
随机产生 n 个个体,它们整体视为种群 P
for i &#61; 1 to gP &#61;for j &#61; 1 to n产生一个 [0,1] 的随机数 aif (a<t)从 P 中随机选出两个个体作为父母&#xff0c;交叉产生一个新的个体并放入 P’ 中else从 P 中随机选出一个个体&#xff0c;变异产生一个新的个体并放入 P’ 中endend利用非支配排序和拥挤距离&#xff0c;从 P∪P’ 中选出 n 个个体&#xff0c; 代替 P # NSGA-II改进的部分
end
输出最终种群 P 中的非支配个体




3.2 NSGA-II 提出的 NSGA的缺点


  • O(MN3)O(MN^3)O(MN3)计算复杂度(其中M代表目标个数&#xff0c;N代表种群个数)

    NSGA算法每一代进化都要构造非支配集, 在种群规模大的时候会造成巨大的时间开销

  • 非精英机制方法

    NSGA算法没有采取保留优秀解的措施, 导致算法性能受损。

  • 需要指定共享参数

    指定共享参数是因为NSGA需要依靠共享参数来维持解群体的分布性, 也即实现解尽可能地均匀分布, 但共享参数的定义往往需要一定的经验, 这也导致共享参数的确定成为了老大难的问题。





3.3 NSGA-II 较于 NSGA的优点


3.3.1 快速非支配排序

​在NSGA-中&#xff0c;将进化群体按支配时关系分为若干层&#xff0c;第一层为进化群体的非支配个体集合&#xff0c;第二层为在进化群体中去掉第一层个体后所求得的非支配个体集合&#xff0c;第三层为在进化群体中去掉第一层和第二层个体后所求得的非支配个体集合&#xff0c;依此类推。选择操作首先考虑第一层非支配集&#xff0c;按照某种策略从第一层中选取个体;然后再考虑在第二层非支配个体集合中选择个体&#xff0c;依此类推,直至满足新进化群体的大小要求。


1) 论文算法

论文代码




2) 支配关系

在这里插入图片描述
对于二目标优化问题来讲, 支配的含义在于 解A的值在两个目标函数上都优与解B , 这样我们就称 解A支配解B (不理解可以参照 Pareto理论)
假如横纵坐标为两个不同的约束函数, 函数值越小越优秀的情况下。 那么 B 显然能够支配 C和D , 因为 B的两个函数值都小于 C与 D, 因此 Sp&#61;C,DS_p &#61; {C,D}Sp&#61;C,D 。 而 C 显然受到 A 和 B 的支配, 因此 np&#61;2np &#61; 2np&#61;2




3) 论文解释


  • 原文

    ​ First, for each solution we calculate two entities: 1) domination count npn_pnp, the number of solutions which dominate the solution p, and 2) SpS_pSp, a set of solutions that the solution dominates. This requires O(MN2)O(MN^2)O(MN2)comparisons.
    ​ All solutions in the first nondominated front will have their domination count as zero. Now, for each solution p with np&#61;0n_p &#61; 0np&#61;0, we visit each member (q ) of its sets SqS_qSq and reduce its domination count by one. In doing so, if for any member q the domination count becomes zero, we put it in a separate list Q. These members belong to the second nondominated front. Now, the above procedure is continued with each member of Q and the third front is identified. This process continues until all fronts are identified.


  • 译文

    ​ 首先&#xff0c;对每一个解我门计算两个实体:1&#xff09;支配计数npn_pnp ,即支配着解 p 的解的数量&#xff0c;还有 2&#xff09;SpS_pSp&#xff0c;解所支配的解的集合&#xff0c;这需要O(MN2)O(MN^2)O(MN2)次比较。
    ​ 所有第一非支配前沿面解的支配计数都为零。现在&#xff0c;对每一个解 p 都有np&#61;0n_p &#61; 0np&#61;0&#xff0c;我们访问每一成员(q&#xff09;和他的集合SqS_qSq并且减少逐一减少支配计数。通过这样&#xff0c;如果任何成员q的支配计数达到0&#xff0c;我们就把它放进一个单独集合 Q。这些成员属于第二非支配前沿面。现在&#xff0c;以上程序应用 Q中的每一成员继续执行直到第三前沿面被确定。这一过程持续到所有前沿面被确定。


  • 个人理解

    快速非支配排序算法的目的在于将 种群根据相应的支配关系划分为不同级别的Pareto解 , 根据约束函数划分为 Pareto1、Pareto2......ParetoNPareto_1、Pareto_2......Pareto_NPareto1Pareto2......ParetoN 等若干个等级。算法首先完成对所有种群最优解的划分, 也即 Pareto1Pareto_1Pareto1 级解(也即种群的最优解, 其余解按照1−N1 - N1N 优先级依次递减)。其次完成刨去 Pareto1Pareto_1Pareto1 级解之后解的划分, 根据支配次数的结果 nqn_qnq 的大小, 每执行依次递减, 当执行同一批次 nqn_qnq 为零时的解划分为同一等级 (Pareto front) , 直到集合为空, 完成种群 N 的划分。



4) 伪代码

# 以下是 NSGA-II 的伪代码
# 参数说明
# np表示被多少解支配&#xff0c;是一个数目
# Sp表示该解所支配的解的集合,是一个集合
# P表示整个种群
# 对于参数而言, 这里的参数都是一些假参数, 实际设计时, 解应该是一个具有属性地对象def fast_nondominated_sort(P):F &#61; [] # 初始化 F用来存放支配关系的排序结果(分层划分)for p in P: # 遍历整个种群Sp &#61; [] # 支配解集合初始化np &#61; 0 # 支配解个数初始化for q in P: # 遍历整个种群if p > q: # 如果p支配q,将q添加到 Sp 列表(p被p支配)Sp.append(q)elif q > p: # 如果q支配p,则 np &#43; 1np &#43;&#61; 1if np &#61;&#61; 0: # 如果p没有被其它解支配, 将它设为Pareto 1级, 也即非支配解p_rank &#61; 1 #p_rank 是解的一个属性, 代表了当前解的 Pareto等级F1.append(p) # 将非支配解加入p 集合中F.append(F1) # 将Pareto 1级解加入F群体中i &#61; 1# 下述算法复杂度为 O(MN^2)while F[i]: # 当F 非空Q &#61; [] # Q 存放后续的非支配解for p in F[i]: # 遍历Pareto 1级解集合for q in Sp: # 遍历Pareto 1级解的支配解 该集合 &#61; 全集 - Pareto1级解nq -&#61; 1 # 消除了 Pareto上层解 对它的支配if nq &#61;&#61; 0: # 如果该个体支配计数为0, 代表是非支配解q_rank &#61; i&#43;1 # 设置该解为与 i &#43; 1前沿面 i 初始为 1Q.append(q) # 将解存放到Q集合中F.append(Q) # 把Q得到的划分好的非支配解排序结果拼接到 F 结果集内部i &#43;&#61; 1 # 重复循环 知道F[i]为空, 也即遍历完所有的Pareto 1级解




3.3.2 拥挤度与拥挤度比较算子


1) 拥挤度计算公式

I[i&#43;1].m和I[i−1].m分别是解i后一个与前一个解在m函数上的的函数值I[i&#43;1].m和I[i-1].m分别是解i后一个与前一个解在m函数上的的函数值I[i&#43;1].mI[i1].mim

fmmax和fmmin分别是第m个函数的最大和最小值f_m^{max}和f_m^{min}分别是第m个函数的最大和最小值fmmaxfmminm
Idistance&#61;(I[i&#43;1].m−I[i−1].m)/(fmmax−fmmin)I_{distance} &#61; (I[i&#43;1].m - I[i-1].m) / (f_m^{max} - f_m^{min}) Idistance&#61;(I[i&#43;1].mI[i1].m)/(fmmaxfmmin)




2) 拥挤比较算子

经过前面的快速非支配排序和拥挤度计算之后&#xff0c;种群中的每个个体 iii 都拥有两个属性&#xff1a;非支配排序决定的非支配序 iranki_{rank}irank&#xff08;级数&#xff0c;即第几级&#xff09;和拥挤度 idi_did。依据这两个属性&#xff0c;可以定义拥挤度比较算子&#xff1a;个体i与另一个个体 j 进行比较&#xff0c;只要下面任意一个条件成立&#xff0c;则个体 iii 获胜。

① 如果个体 iii 所处非支配层优于个体 jjj 所处的非支配层&#xff0c;即 irankirank<jrank

​② 如果它们有相同的等级且个体 iii 比个体 jjj 有一个更大的拥挤距离&#xff0c;即 irank&#61;jranki_{rank} &#61; j_{rank}irank&#61;jrankid>jdi_d > j_did>jd

第一个条件确保被选择的个体属于较优的非劣等级。第二个条件根据它们的拥挤距离选择由于在同一非劣等级而不分胜负的两个个体中位于较不拥挤区域的个体(有较大的拥挤度 idi_did )。胜出的个体进入下一个操作。





3.3.3 精英策略


1) 概述

在这里插入图片描述
首先将第 t 代产生的新种群 QtQ_tQt 与父代 PtP_tPt 合并组成 RtR_tRt , 种群大小为 2N2N2N 。然后 RtR_tRt 进行非支配排序产生一系列非支配集 ZiZ_iZi 并计算拥挤度。由于子代和父代个体都包含在 RtR_tRt 中, 则经过非支配排序后的非支配集合 Z1Z_1Z1 是最优的, 所以首先将 Z1Z_1Z1 加入 Pt&#43;1P_{t&#43;1}Pt&#43;1 新父代种群中。 如果大小小于 N, 则继续向 Pt&#43;1P_{t&#43;1}Pt&#43;1 种群中添加 Z2Z_2Z2 。直到添加 Z3Z_3Z3 时, 种群大小超过了 N , 这时就根据拥挤度比较算子进行选择添加, 使得 Pt&#43;1P_{t&#43;1}Pt&#43;1 个体数量达到 NNN。然后通过遗传算子(选择、交叉、变异)产生新的子代种群 Qt&#43;1Q_{t&#43;1}Qt&#43;1




2)主体循环

主体循环
以上代码的逻辑跟精英策略的逻辑一致。





3.4 选择算法


3.4.1 锦标赛选择算法

锦标赛选择算法

​遗传算法中的锦标赛选择策略每次从种群中取出一定数量个体&#xff08;放回抽样&#xff09;&#xff0c;然后选择其中最好的一个进入子代种群。重复该操作&#xff0c;直到新的种群规模达到原来的种群规模。几元锦标赛就是一次性在总体中取出几个个体&#xff0c;然后在这些个体中取出最优的个体放入保留到下一代种群的集合中。具体的操作步骤如下&#xff1a;

​① 确定每次选择的个体数量N。&#xff08;二元锦标赛选择即选择2个个体&#xff09;
​② 从种群中随机选择N个个体(每个个体被选择的概率相同) &#xff0c;根据每个个体的适应度值&#xff0c;选择其中适应度值最好的个体进入下一代种群。
​③ 重复步骤②多次&#xff08;重复次数为种群的大小&#xff09;&#xff0c;直到新的种群规模达到原来的种群规模。


推荐阅读
  • 本文详细介绍如何在 Apache 中设置虚拟主机,包括基本配置和高级设置,帮助用户更好地理解和使用虚拟主机功能。 ... [详细]
  • 函子(Functor)是函数式编程中的一个重要概念,它不仅是一个特殊的容器,还提供了一种优雅的方式来处理值和函数。本文将详细介绍函子的基本概念及其在函数式编程中的应用,包括如何通过函子控制副作用、处理异常以及进行异步操作。 ... [详细]
  • 本文详细介绍了如何在Spring框架中设置事件发布器、定义事件监听器及响应事件的具体步骤。通过实现ApplicationEventPublisherAware接口来创建事件发布器,利用ApplicationEvent类定义自定义事件,并通过ApplicationListener接口来处理这些事件。 ... [详细]
  • 对于初学者而言,搭建一个高效稳定的 Python 开发环境是入门的关键一步。本文将详细介绍如何利用 Anaconda 和 Jupyter Notebook 来构建一个既易于管理又功能强大的开发环境。 ... [详细]
  • 长期从事ABAP开发工作的专业人士,在面对行业新趋势时,往往需要重新审视自己的发展方向。本文探讨了几位资深专家对ABAP未来走向的看法,以及开发者应如何调整技能以适应新的技术环境。 ... [详细]
  • 使用TabActivity实现Android顶部选项卡功能
    本文介绍如何通过继承TabActivity来创建Android应用中的顶部选项卡。通过简单的步骤,您可以轻松地添加多个选项卡,并实现基本的界面切换功能。 ... [详细]
  • 本文详细介绍了JQuery Mobile框架中特有的事件和方法,帮助开发者更好地理解和应用这些特性,提升移动Web开发的效率。 ... [详细]
  • 本文详细介绍了在 Ubuntu 16.04 系统上安装和配置 PostgreSQL 数据库的方法,包括如何设置监听地址、启用密码加密、更改默认用户密码以及调整客户端访问控制。 ... [详细]
  • linux网络子系统分析(二)—— 协议栈分层框架的建立
    目录一、综述二、INET的初始化2.1INET接口注册2.2抽象实体的建立2.3代码细节分析2.3.1socket参数三、其他协议3.1PF_PACKET3.2P ... [详细]
  • Logging all MySQL queries into the Slow Log
    MySQLoptionallylogsslowqueriesintotheSlowQueryLog–orjustSlowLog,asfriendscallit.However,Thereareseveralreasonstologallqueries.Thislistisnotexhaustive:Belowyoucanfindthevariablestochange,astheyshouldbewritteninth ... [详细]
  • 本文详细解析了MySQL中常见的几种错误,并提供了具体的解决方法,帮助开发者快速定位和解决问题。 ... [详细]
  • 本文探讨了Python类型注解使用率低下的原因,主要归结于历史背景和投资回报率(ROI)的考量。文章不仅分析了类型注解的实际效用,还回顾了Python类型注解的发展历程。 ... [详细]
  • 问题场景用Java进行web开发过程当中,当遇到很多很多个字段的实体时,最苦恼的莫过于编辑字段的查看和修改界面,发现2个页面存在很多重复信息,能不能写一遍?有没有轮子用都不如自己造。解决方式笔者根据自 ... [详细]
  • 本文详细介绍了如何搭建一个高可用的MongoDB集群,包括环境准备、用户配置、目录创建、MongoDB安装、配置文件设置、集群组件部署等步骤。特别关注分片、读写分离及负载均衡的实现。 ... [详细]
  • 小编给大家分享一下Vue3中如何提高开发效率,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获, ... [详细]
author-avatar
坚韧稻草
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有