最近主要的重点是去学习遗传算法,我之前学习了遗传算法的基本概念,但是那只是针对于一维的问题,也就是只是针对于某一个方面进行优化的遗传算法。
但是在实际场景中,肯定不会是只需要一个优化一个方面的算法。肯定是需要给出一个满足多个方面需求的最优解,所以就需要使用多维遗传算法。
关于多目标优化中比较重要的一个概念就是Pareto 前沿
在多目标优化问题中,通常存在多个决策变量和多个目标函数。决策变量是我们可以控制的变量,而目标函数是我们要最小化或最大化的量。然而,不同的目标函数之间往往存在冲突,即优化其中一个目标函数的同时会降低另一个目标函数的值。所以我们需要找到一组解决方案,使得每个目标函数都得到最优解的同时不影响其他目标函数。
而Pareto 前沿就是所有非劣解的集合,Pareto 前沿上的任何一个解都无法通过改进一个目标函数的值而不降低另一个目标函数的值。也就是一种相对最优。
在多目标中,我们的目的就是得到 Pareto 前沿上的解集合,这些解可以提供最优的选择方案
用来找到Pareto 前沿的方法:
非支配排序结合拥挤度排序
非支配排序的排序方式:
先比较支配关系
对于每对不同的个体i和j,判断它们之间的支配关系。如果个体i在所有目标函数上都不劣于个体j,那么称个体i支配个体j,同时将个体j添加到个体i的支配集合中,将个体j的支配个数加1。反之,如果个体j支配个体i,则将个体i添加到个体j的支配集合中,将个体i的支配个数加1。
排序
将种群中的个体按照支配个数进行排序,支配个数越小的个体排名越高
再按照拥挤度排序,拥挤度越大的个体排名越高。
拥挤度
对于每个解,通过计算其在目标空间中相邻解之间的距离,来衡量解的拥挤程度。
目的是在于通过对解的拥挤程度进行度量和维护,保证种群中的解分布在整个Pareto前沿上。
如何实现
对于每个支配层内的解,计算其在目标空间中相邻解之间的距离。这里可以采用不同的距离度量方式,其中一种是欧几里得距离。
进行更新,根据拥挤度对种群进行排序。对于同一支配层内的解,拥挤度越大的解排名越靠后。
这样的话,就可以避免在进行选择的时候,选择大部分的是同一区域的解,保持种群的多样性,
使得算法能够探索到更多的解空间。
具体使用:
首先需要编写3个基本类。
员工类,员工偏好类,员工排班类。
员工偏好类:员工的偏好类型和偏好值之类的基本信息。
员工类:基本信息以及偏好列表;
排班类:用于存储结果,和基因型。
重点的两个类:
适应度函数:
在这个函数中,基因型的类型是IntegerGene.某个基因代表员工在每个班次的工作状态。值为0或者1.。
先将基因型转换出排班矩阵,然后根据排班矩阵和员工偏好值计算适应度,适应度值越小代表方案越优秀。底层计算逻辑,就是计算方案与偏好值的方差。然后方差越大适应度越高,把多个偏好值适应度进行计算后相加,就是总适应度。
基因型工厂
用来生成基因型
使用随机数生成器来生成一个整数型数组,设置好整数的范围,一般是员工的最大工作时间。
然后调用接口将整数值转换基因型,最后在转换为一个基因型对象。
第三步建立 遗传算法引擎
分别指定适应度函数,编解码对象,种群大小,选择,交叉,变异算子, 迭代次数 :。
然后设置收集最优的基因型对象,然后就这个基因型进行一个转换变成对象然后输出,就可以得到
结果。现在只是写出了一个简单的demo,参数设置还不够优秀,
而且还有拥挤度计算函数还没有编写,还有很多需要完善的地方,主要是资料太少,导致在api接口的使用方面有很大的问题。官方文档也是全部中文,直接翻译有不少歧义。