之前学习了遗传算法对单目标函数的最优值求解,对于多目标问题。或者说是多目标函数的求解问题,我想再研究一下。正好,我也想改进一下之前的代码架构。不得不说,之前的代码是面向过程的架构,完全没有体现出python面向对象的特点。于是在上篇里更新了面向对象的程序。

一.举个多目标函数的简单例子

这里我们举个二元函数的最大值优化例子:

根据之前所学,

第一步,编码。这里我们采用二进制对个体基因型编码,将个体表现型编码为十进制。如,基因型x=100001对应的表现型是{4,1}。

第二步,初始生成种群。本例中,随机生成4个个体组成一个种群。如下,{011101}{101011}{011100}{111001},其表现型为{3,5}{5,3}{3,4}{7,1}。

第三步,计算适应度。本例,直接用目标函数作为适应度函数。得到如下表格:

第四步,选择。适应度越高的个体,遗传到下一代的数量越多,这里采用轮盘赌方式。轮盘赌是典型的几何概率模型,其特点在于其选择概率与适应度大小成正比。在第三步中,计算了4个个体的适应度以及他所占总适应度值的比值将其组成一个概率区域,如下:

接下来,我们随机生成4个[0,1]之间的随机数,{0.15,0.35,0.89,0.75}。根据随机数的大小,来选择个体存活的数量。这里,有两个随机数落在了4#区间,分别有1个随机数落在了1#和2#区间。这样,我们就选出了下一代的个体。

第五步,交配。在这步中会个体间的基因互换,这里采取的是单点互换。首先,选择对群体进行随机配对,然后随机设置交换点的位置,最后互换基因。这里,我们将1-2,3-4,配对并且互换基因,如下:

第六步,变异。在这步中,我们随机选择一个个体,并且随机选择一个位置进行变异。将0变为1,或者将1变为0。

编号                                    基因型                            变异点                           变异结果

经过以上过程,我们得到了第二代,对其适应度计算如下:

此时,我们已经发现其解的适应度都得到了提升。实际上本轮已经得到了最佳的解{7,7}。

二. 复杂的多目标函数求解

以上我们的目标函数是不存在冲突的,但是有这样一种冲突的情况,两个目标函数一个要求最大,一个要求最小。某个目标函数的提高需要另一个函数降低作为代价,这样就出现了帕雷托解(pareto)。

我们使用遗传算法解决pareto解有以下几种方法:

1.权重系数转换法

对每个目标函数f(xi)(i=1,2,3,4...)赋予权重wi(i=1,2,3.....),wi为目标函数重要程度。则得到如下线性组合:

这里我们就将多目标转化为单目标函数,将u作为评价函数。

2.并列选择法

主要步骤:(1)将种群按照目标函数个数等分为子种群,为每个子种群分配一个目标函数。(2)将子种群中的个体按照各自的目标函数选择出适应度高的个体,然后将其组成一个子种群。(3)再将子种群进行交配,变异,生成下一代父亲种群。然后,再重复第一步。

并列选择法的缺点在于易于生成单个目标函数的极端最优解,而较难生成一种多个目标在某种程度上都比较满意的折衷解。

3.排序选择法

排序选择法的基本思想是:基于“pareto最优个体”的概念对群体中的个体进行排序,然后根据这个次序进行种群选择。这样的话就能够让pareto最优个体有更多的机会遗传到下一代。这种方法的缺点是仅仅度量了各个个体之间的优越次序,而并未度量各个个体的分散程度,所以容易生成相似的解,而不是分布较广的多个最优解。

4.共享函数法

针对排序选择方法的缺点,即所求的几个最优解通常是集中于最优解集合的某一个小区域内,而不是分散在整个pareto最优解集合。由此,引出了基于共享函数的小生境技术。该算法对相同个体或类似个体是数目加以限制,以便能够产生出种类较多的不同的最优解。这就引出一个问题,怎么衡量两个个体之间的相似度?这就是小生境数。顾名思义,小生境就是在一个小环境中相似的个体种群。最常见的公式为:

s(d)为共享函数,是表示群体中两个个体之间密切关系程度的一个函数。d(X,Y)为个体X,Y之间的hanmin距离,也是用于衡量个体间相似度的一个函数。在计算出小生境数后,可以是小生境数较小的个体能够有更多的机会被选中,遗传到下一代群体中,即相似程度较小的个体能够有更多的机会被遗传到下一代群体中。

其缺点是:每次选择操作时都需要进行大量的个体之间的优越关系的评价和比价较运算,是算法搜索效率较低。

5.Horn和Nafploitis印的基于小生境pareto多目标遗传算法(NPGA)

类似于上面的并列选择法将每一代个体划分为若干类,每个类别选出若干适应度较大的个体作为一个类的优秀代表组成一个种群,然后交配变异产生新一代种群。基于这种小生境的遗传算法(Niched Genetic Algorithms,NGA),可以更好的保持解的多样性,同时具有很高的全局寻优能力和收敛速度,特别适合于复杂多峰函数的优化问题。

6.Srinvivas和Deb的非支配排序遗传算法NSGA

1980年提出的,在遗传算法的基础上对选择再生方法进行改进:将每个个体按照他们的支配与非支配关系进行再分层,再做选择操作,从而达到目的。这里有几个概念要介绍一下:

pareto支配关系

分层

我理解的分层意思就是取出种群中的非支配个体组成一个小种群(第一个非支配最优层),并赋予其中所有个体一个共享的虚拟适应度值。然后在取出个体后的种群中继续取出非支配个体,再将它们组成一个小种群(第二个非支配最优层),并赋予所有个体一个共享的虚拟适应度值。重复以上步骤,直到原始种群分配完毕,这就叫分层,也叫非支配型排序。伪代码如下:

上面说到,我们要指定共享适应度,算法根据适应度共享对虚拟适应度要重新指定。因而需要引出个体共享后的适应度值,以及共享函数和共享半径。具体的公式这里就不展开了,具体想了解可阅读参考文献3的25页。

因此可以发现,非支配型排序遗传算法有如下问题:

1.计算复杂度较高,O(MN**3)M为目标函数个数,N为种群大小。

2.没有精英策略。精英策略可以一定程度上加速算法执行程度,而且在一定程度上保证已经找到的满意解不会丢失。

3.需要指定共享半径。

针对以上问题有学者(k.Deb 2002)提出了用精英策略快速非支配的遗传算法来解决。

7.带精英策略的非支配排序遗传算法一NSGAII

1).采用快速非支配型排序,降低了算法复杂度。其复杂度降为了O(MN**2)。

2).提出了拥挤度和拥挤度比较算子,代替需要指定共享半径的适应度共享策略。并在快速排序后的同级比较中作为胜出标准。使准pareto解中的个体能扩展到整个pareto域中,并均匀分布,保持了种群的多样性。

3).引入精英策略,扩大采样空间。将父代种群和子代种群合并,保证优良个体能够留存下来。

其算法步骤如下:1.首先随机产生数量为n的初始种群,然后对其进行非支配型排序。接下来,就是常规的选择,交叉,变异操作产生第一代子代种群。2.然后,从第二代开始,将父代和子代合并。然后对其进行快速非支配型排序,同时计算每个非支配层的个体进行拥挤度的计算。然后根据非支配关系和拥挤度来选择合适的个体组成新的父代种群。最后通过再通过选择,交叉,变异产生子代。3.接下来,重复第二步。

这里有几个主要的关键技术需要解释一下:

1).快速非支配型排序

2).拥挤度

在原来的NSGA中,我们采用共享函数来确保多样性,但需要共享半径。为了解决这个问题,我们提出了拥挤度的概念:在种群种群中的给定点的周围个体密度,用id表示。它指出了在个体i周围包含个体i本身但不包含其他个体的最小的长方形。

拥挤度计算伪代码:

3).拥挤比较算子

经过快速非支配排序和拥挤度计算,种群中的每一个个体都得到了两个属性:非支配序rankn和拥挤度。利用这两个属性,我们可以区分种群中间任意两个个体间的支配和非支配关系。定义拥挤度比较算子,当且仅当irank>jrank或irank=jrank且id>jd,有个体i优于个体j。

4).精英选择策略

将父代优秀的个体与子代合并。

三.NSGAII的实现

算法流程

代码实现

#Importing required modules
import math
import random
import matplotlib.pyplot as plt#定义函数1
def function1(x):value = -x**2return value#定义函数2
def function2(x):value = -(x-2)**2return value#Function to find index of list
#查找列表指定元素的索引
def index_of(a,list):for i in range(0,len(list)):if list[i] == a:return ireturn -1#Function to sort by values
# 函数根据指定的值列表排序
'''list1=[1,2,3,4,5,6,7,8,9]value=[1,5,6,7]sort_list=[1,5,6,7]
'''
def sort_by_values(list1, values):sorted_list = []while(len(sorted_list)!=len(list1)):# 当结果长度不等于初始长度时,继续循环if index_of(min(values),values) in list1:# 标定值中最小值在目标列表中时sorted_list.append(index_of(min(values),values))#     将标定值的最小值的索引追加到结果列表后面values[index_of(min(values),values)] = math.inf#      将标定值的最小值置为无穷小,即删除原来的最小值,移向下一个#     infinitedreturn sorted_list#Function to carry out NSGA-II's fast non dominated sort
#函数执行NSGA-II的快速非支配排序,将所有的个体都分层
'''
郭军p21
1.np=0 sp=infinite
2.对所有个体进行非支配判断,若p支配q,则将q加入到sp中,并将q的层级提升一级。若q支配p,将p加入sq中,并将p的层级提升一级。
3.对种群当前分层序号k进行初始化,令k=1
4.找出种群中np=0的个体,将其从种群中移除,将其加入到分层集合fk中,该集合就是层级为0个体的集合。
5.判断fk是否为空,若不为空,将fk中所有的个体sp中对应的个体层级减去1,且k=k+1,跳到2;若为空,则表明得到了所有非支配集合,程序结束
'''
"""基于序列和拥挤距离,这里找到任意两个个体p,q"""
def fast_non_dominated_sort(values1, values2):S=[[] for i in range(0,len(values1))]# 种群中所有个体的sp进行初始化 这里的len(value1)=pop_sizefront = [[]]# 分层集合,二维列表中包含第n个层中,有那些个体n=[0 for i in range(0,len(values1))]rank = [0 for i in range(0, len(values1))]# 评级for p in range(0,len(values1)):S[p]=[]n[p]=0# 寻找第p个个体和其他个体的支配关系# 将第p个个体的sp和np初始化for q in range(0, len(values1)):#step2:p > q 即如果p支配q,则if (values1[p] > values1[q] and values2[p] > values2[q]) or (values1[p] >= values1[q] and values2[p] > values2[q]) or (values1[p] > values1[q] and values2[p] >= values2[q]):#支配判定条件:当且仅当,对于任取i属于{1,2},都有fi(p)>fi(q),符合支配.或者当且仅当对于任意i属于{1,2},有fi(p)>=fi(q),且至少存在一个j使得fj(p)>f(q)  符合弱支配if q not in S[p]:# 同时如果q不属于sp将其添加到sp中S[p].append(q)# 如果q支配pelif (values1[q] > values1[p] and values2[q] > values2[p]) or (values1[q] >= values1[p] and values2[q] > values2[p]) or (values1[q] > values1[p] and values2[q] >= values2[p]):# 则将np+1n[p] = n[p] + 1if n[p]==0:# 找出种群中np=0的个体rank[p] = 0# 将其从pt中移去if p not in front[0]:# 如果p不在第0层中# 将其追加到第0层中front[0].append(p)i = 0while(front[i] != []):# 如果分层集合为不为空,Q=[]for p in front[i]:for q in S[p]:n[q] =n[q] - 1# 则将fk中所有给对应的个体np-1if( n[q]==0):# 如果nq==0rank[q]=i+1if q not in Q:Q.append(q)i = i+1# 并且k+1front.append(Q)del front[len(front)-1]return front# 返回将所有个体分层后的结果#Function to calculate crowding distance
#计算拥挤距离的函数
'''
高媛p29
1.I[1]=I[l]=inf,I[i]=0 将边界的两个个体拥挤度设为无穷。
2.I=sort(I,m),基于目标函数m对种群排序
3.I[i]=I[i]+(Im[i+1]-Im[i-1])/(fmax-fmin)
'''
def crowding_distance(values1, values2, front):distance = [0 for i in range(0,len(front))]# 初始化个体间的拥挤距离sorted1 = sort_by_values(front, values1[:])sorted2 = sort_by_values(front, values2[:])# 基于目标函数1和目标函数2对已经划分好层级的种群排序distance[0] = 4444444444444444distance[len(front) - 1] = 4444444444444444for k in range(1,len(front)-1):distance[k] = distance[k]+ (values1[sorted1[k+1]] - values2[sorted1[k-1]])/(max(values1)-min(values1))for k in range(1,len(front)-1):distance[k] = distance[k]+ (values1[sorted2[k+1]] - values2[sorted2[k-1]])/(max(values2)-min(values2))return distance
#     返回拥挤距离#函数进行交叉
def crossover(a,b):r=random.random()if r>0.5:return mutation((a+b)/2)else:return mutation((a-b)/2)#函数进行变异操作
def mutation(solution):mutation_prob = random.random()if mutation_prob <1:solution = min_x+(max_x-min_x)*random.random()return solutionpop_size = 20
max_gen = 100
# 迭代次数
#Initialization
min_x=-55
max_x=55
solution=[min_x+(max_x-min_x)*random.random() for i in range(0,pop_size)]
# 随机生成变量
gen_no=0
while(gen_no<max_gen):function1_values = [function1(solution[i])for i in range(0,pop_size)]function2_values = [function2(solution[i])for i in range(0,pop_size)]# 生成两个函数值列表,构成一个种群non_dominated_sorted_solution = fast_non_dominated_sort(function1_values[:],function2_values[:])# 种群之间进行快速非支配性排序,得到非支配性排序集合print("The best front for Generation number ",gen_no, " is")for valuez in non_dominated_sorted_solution[0]:print(round(solution[valuez],3),end=" ")print("\n")crowding_distance_values=[]# 计算非支配集合中每个个体的拥挤度for i in range(0,len(non_dominated_sorted_solution)):crowding_distance_values.append(crowding_distance(function1_values[:],function2_values[:],non_dominated_sorted_solution[i][:]))solution2 = solution[:]#生成了子代while(len(solution2)!=2*pop_size):a1 = random.randint(0,pop_size-1)b1 = random.randint(0,pop_size-1)# 选择solution2.append(crossover(solution[a1],solution[b1]))#随机选择,将种群中的个体进行交配,得到子代种群2*pop_sizefunction1_values2 = [function1(solution2[i])for i in range(0,2*pop_size)]function2_values2 = [function2(solution2[i])for i in range(0,2*pop_size)]non_dominated_sorted_solution2 = fast_non_dominated_sort(function1_values2[:],function2_values2[:])# 将两个目标函数得到的两个种群值value,再进行排序 得到2*pop_size解crowding_distance_values2=[]for i in range(0,len(non_dominated_sorted_solution2)):crowding_distance_values2.append(crowding_distance(function1_values2[:],function2_values2[:],non_dominated_sorted_solution2[i][:]))# 计算子代的个体间的距离值new_solution= []for i in range(0,len(non_dominated_sorted_solution2)):non_dominated_sorted_solution2_1 = [index_of(non_dominated_sorted_solution2[i][j],non_dominated_sorted_solution2[i] ) for j in range(0,len(non_dominated_sorted_solution2[i]))]#排序front22 = sort_by_values(non_dominated_sorted_solution2_1[:], crowding_distance_values2[i][:])front = [non_dominated_sorted_solution2[i][front22[j]] for j in range(0,len(non_dominated_sorted_solution2[i]))]front.reverse()for value in front:new_solution.append(value)if(len(new_solution)==pop_size):breakif (len(new_solution) == pop_size):breaksolution = [solution2[i] for i in new_solution]gen_no = gen_no + 1#Lets plot the final front now
function1 = [i * -1 for i in function1_values]
function2 = [j * -1 for j in function2_values]
plt.xlabel('Function 1', fontsize=15)
plt.ylabel('Function 2', fontsize=15)
plt.scatter(function1, function2)
plt.show()

四.总结

相对于单目标函数求解,多目标函数求解明显难度提升了好几个数量级,其核心问题在于出现了pareto解。我们需要权衡各个目标函数之间的利弊,选择合适算法来求解。本篇通过引出一个简单的多目标函数例子,介绍了7种算法着重介绍了其中的NSGAII算法,其核心策略在于对快速非支配算法的设计,拥挤度的计算,拥挤度算子的设计,精英策略的设计。由于篇幅较长,里面几个的概念不容易理解,程序中也有一些技巧不易察觉。但是静下心来慢慢琢磨,还是挺有收获的。本人才疏学浅,如有纰漏,望诸位读者不吝赐教。祝好!

五.参考文献:

  1. 九二. 遗传算法学习--多目标优化中的遗传算法[DB/OL]. https://www.cnblogs.com/lomper/p/3831428.html
  2. variousme. 小生境遗传算法[EB/OL]. http://blog.sina.com.cn/s/blog_714e46f80100o1pp.html.
  3. 卢小亭. 多目标优化遗传算法选择方法的研究与改进[D]. 合肥:安徽理工大学, 2008. 20-25
  4. 高媛. 非支配排序遗传算法NSGA的研究与应用_[D]. 杭州:浙江大学, 2006. 20-24
  5. devilmaycry812839668. 带精英策略的快速非支配排序遗传算法 NSGA-II 算法[EB/OL]. https://www.cnblogs.com/devilmaycry812839668/p/6268408.html.
  6. 郭军. 带精英策略的非支配排序遗传算法优化研究[D]. 沈阳:辽宁大学, 2017. 21-25
  7. A, Konak, DW, Coit. Multi-objective optimization using genetic algorithms: A tutorial[J]. Reliability Engineering and System Safety, 2006, 91(9): 992-1007
  8. Duyuankai1992. 使用python做遗传算法与基于遗传算法的多目标算法[EB/OL]. https://blog.csdn.net/qq_37879432/article/details/80457054.
  9. Alex.遗传算法-python实现[EB/OL]. http://www.cnblogs.com/biaoyu/p/4865368.html

希望有志同道合的小伙伴关注我的公众平台,欢迎您的批评指正,共同交流进步。

遗传算法关于多目标优化python(详解)相关推荐

  1. 模拟退火算法与遗传算法求解多目标优化问题的算法实现(数学建模)

    一.模拟退火算法 模拟退火算法是一种全局优化算法,解决的问题通常是找到一个最小化(或最大化)某个函数的全局最优解.它通过模拟物理退火的过程来搜索解空间,在开始时以一定的温度随机生成初始解,然后一步步降 ...

  2. 【GAN优化】详解GAN中的一致优化问题

    GAN的训练是一个很难解决的问题,上期其实只介绍了一些基本的动力学概念以及与GAN的结合,并没有进行过多的深入.动力学是一门比较成熟的学科,有很多非常有用的结论,我们将尝试将其用在GAN上,来得到一些 ...

  3. html的细节优化,网站页面优化细节详解

    原标题:网站页面优化细节详解 SEO页面优化是继SEO结构优化之后,另一个重要优化地方; 页面标题 在每个页面中的关键位置,出现目标关键词,这是我们做页面优化的基础思路,关键词位置,都有哪些呢? 第一 ...

  4. 基于遗传算法的多目标优化算法(附代码案例)

    一.理论基础 多目标优化问题可以描述如下: 其中,f(x) 为待优化的目标函数:x 为 待优化的变量:lb 和 ub 分别为变量 x 的下限和上限约束:Aeq * x = beq 为变量 x 的线性等 ...

  5. 基于YOLOv5的目标检测系统详解(附MATLAB GUI版代码)

    摘要:本文重点介绍了基于YOLOv5目标检测系统的MATLAB实现,用于智能检测物体种类并记录和保存结果,对各种物体检测结果可视化,提高目标识别的便捷性和准确性.本文详细阐述了目标检测系统的原理,并给 ...

  6. 《MATLAB智能算法30个案例》:第9章 基于遗传算法的多目标优化算法

    <MATLAB智能算法30个案例>:第9章 基于遗传算法的多目标优化算法 1. 前言 2. MATLAB 仿真示例 3. 小结 1. 前言 <MATLAB智能算法30个案例分析> ...

  7. python input与返回值-Python 详解基本语法_函数_返回值

    Python 详解基本语法 概要: 函数的返回值是函数重要的组成部分.函数的根本在于实现程序的部分功能,所以很多时候我们需要将函数执行后的结果返回给程序再由程序作出进一步的操作.可以说是函数的返回值令 ...

  8. 【GAN优化】详解SNGAN(频谱归一化GAN)

    今天将和大家一起学习具有很高知名度的SNGAN.之前提出的WGAN虽然性能优越,但是留下一个难以解决的1-Lipschitz问题,SNGAN便是解决该问题的一个优秀方案.我们将先花大量精力介绍矩阵的最 ...

  9. 【百度飞浆】YOLO系列目标检测算法详解

    YOLO系列目标检测算法详解 1 YOLO发展史 2 YOLO v3目标检测原理 3 PaddleDetection中YOLO v3模型介绍 4 YOLO v3配置演练 1 YOLO发展史 2 YOL ...

最新文章

  1. [Swust OJ 404]--最小代价树(动态规划)
  2. ubuntu 16.04 分辨率只有800×600问题解决
  3. initial model for Agile Development Organization: Relationship Graph
  4. node+mongodb+win7
  5. bs cs架构区别_软件架构设计分层模型和构图思考
  6. 宁德时代预计一季度净利润超9.9亿元 同比增长超140%
  7. 海报PSD分层促销模板|深层剖析设计套路
  8. web前端入门指南:来看看这位大佬的学习之路吧!
  9. swift基础之_swift调用OC/OC调用swift
  10. dadayi大一c语言累加编程题,c++习题答案中国电力出版社
  11. shell基本理论知识
  12. Mybtis进行mysql数据库的修改表名操作
  13. oracle客户端 PLSQL安装配置教程
  14. python翻译-50 行代码,实现中英文翻译
  15. 抖音视频怎么上热门 视频去水印
  16. 信息安全工程师自学笔记(1)
  17. 《大话数据结构》参考
  18. Spring Cloud-Alibaba
  19. android 浏览器应用商店,百度易揭秘:自带应用商店和浏览器 兼容安卓
  20. 意大利作曲家维瓦尔第

热门文章

  1. 局域网中的每台计算机主机扩展槽,计算机导论选择题
  2. iOS开发技巧-国际化(Localization),只看一篇就够了
  3. punycode编码
  4. 如何动态使用烘焙出来的ReflectionProbe-0.exr信息
  5. jsp学生体育成绩管理系统
  6. layui表头宽度和表格一致_layui表格如何把表头固定
  7. 电感线圈绕制常用的漆包线
  8. 一只小蜜蜂 C语言 函数 递归
  9. JAVA:不使用第三个变量,交换两个变量的值
  10. [iPhone]解决:手指按住不动时,屏幕也会上下抖动