基于DEAP库的Python进化算法从入门到入土--(六)多目标遗传算法 NSGA-II

Python019

基于DEAP库的Python进化算法从入门到入土--(六)多目标遗传算法 NSGA-II,第1张

在很多实际工程问题中,我们的优化目标不止一个,而是对多个目标函数求一个综合最优解。例如在物流配送问题中,不仅要求配送路径最短,还可能需要参与运输车辆最少等。

多目标优化问题的数学模型可以表达为:

多目标优化问题通常具有如下特点:

对于多目标优化问题,传统方法是将原问题通过加权方式变换为单目标优化问题,进而求得最优解。该方法具有两大问题:

遗传算法具有多点多方向搜索的特征,在一次搜索中可以得到多个Pareto最优解,因此更适合求解多目标优化问题。

而当前用于求解多目标优化问题的遗传算法一般有两种思路:

NSGA-II(nondominated sorting genetic algorithm II)是2002年Deb教授提出的NSGA的改进型,这个算法主要解决了第一版NSGA的三个痛点:

针对这三个问题,在NSGA-II中,Deb提出了快速非支配排序算子,引入了保存精英策略,并用“拥挤距离”(crowding distance)替代了共享(sharing)。

在介绍NSGA-II的整体流程之前,我们需要先了解快速非支配排序和拥挤距离的定义。

解的支配关系与Pareto最优解

下图表示了解之间的支配和强支配关系:

下图表示了一个最小化问题解集中的Pareto最优解和Pareto弱最优解:

快速非支配排序步骤

快速非支配排序就是将解集分解为不同次序的Pareto前沿的过程。

它可以描述为:

DEAP实现

DEAP内置了实现快速非支配排序操作的函数 tools.emo.sortNondominated

tools.emo.sortNondominated(individuals, k, first_front_only=False)

参数:

返回:

拥挤距离的定义

在NSGA II中,为了衡量在同一个前沿中各个解质量的优劣,作者为每个解分配了一个拥挤距离。其背后的思想是 让求得的Pareto最优解在objective space中尽量分散 。也就有更大可能让解在Pareto最优前沿上均匀分布。

DEAP实现

DEAP中内置了计算拥挤距离的函数 tools.emo.assignCrowdingDist

tools.emo.assignCrowdingDist(individuals)

参数:

返回:

比较操作

根据快速非支配排序和拥挤距离计算的结果,对族群中的个体进行排序:

对两个解 ,

在每个迭代步的最后,将父代与子代合为一个族群,依照比较操作对合并后族群中的个体进行排序,然后从中选取数量等同于父代规模的优秀子代,这就是NSGA-II算法中的精英保存策略。

DEAP实现

DEAP内置了实现NSGA-II中的基于拥挤度的选择函数 tools.selNSGA2 用来实现精英保存策略:

tools.selNSGA2(individuals, k, nd='standard')

参数:

返回:

这里选用ZDT3函数作为测试函数,函数可表达为:

其Pareto最优解集为

这里为了方便可视化取 。

下图给出了该函数在Decision Space和Objective Space中的对应:

其pareto最优解在Objective Space中如下图红点所示:

将结果可视化:

得到:

可以看到NSGA-II算法得到的Pareto最优前沿质量很高:最优解均匀分布在不连续前沿的各个线段上;同时在最优前沿以外没有个体存在。

python2和python3的区别

如果你是一个初学者,或者你以前接触过其他的编程语言,你可能不知道,在开始学习python的时候都会遇到一个比较让人很头疼的问题:版本问题!!是学习python2 还是学习 python3 ?这是非常让人纠结的!

搜索一下便会发现python3 和 python2 是不兼容的,而且差异比较大,到底学习哪个版本呢?下面就来为大家分析一下:

其实python是linux上最常用的软件之一,但是linux目前的版本大部分还是使用python2的,而且,在linux上依赖python2的程序更多一些,所以 Python3 要代替 python2 成为主流还需要几年的时间。

当初设计 Python3 的目的是没有代码兼容的包袱的情况下改进 Python,但个人认为改进得还不够大刀阔斧,没有彻底改进一些bug,还有不少的 wart 错过了改进机会,因此造成的语法不兼容的地方也没最初设想的多。

人们几年摸索慢慢下来,大部分的情况下可以直接写 2/3 兼容的代码,也有 six 这类的兼容层可用。

所以先学 Python2 还是 Python3 都不是问题,或者说都是问题。

目前现状是实际应用中大部分暂不考虑 Python3,有的时候注意写兼容 2/3 的代码。用 Python2 为主的写新代码时要考虑以后迁移到 Python3 的可能性。

论学 Python2 还是 Python3,都需要注意另外一边的不同点:所幸就是这些不同点很容易掌握,只有一个 unicode encoding

对较多人造成困扰(同时也是很多 web 相关库移植的主要障碍,3.3 重新支持 u'',情况大大改善了)学习python2 还是

python3 、使用python2 还是 python3 需要看具体情况而定.

所以我建议:

1. 如果是你在企业中,需要用到python而学习python的话,那就要看企业的应用python的版本进行学习;

2. 如果想要更多的成熟解决方案,最少的bug,最稳定的应用那就用python2 ;

3. 如果你是在读大学的学生,那我建议你学习python3,等到毕业的时候或许python已经成为了主流。