精华内容
下载资源
问答
  • 多目标遗传算法定义
    千次阅读
    2019-02-17 10:27:49
                   

    第四章 多目标遗传算法研究

    §4.1 多目标优化算法简介

            实际的工程优化问题大多数是多目标优化问题,目标之间一般都是互相冲突的。多目标优化很早就得到了人们的重视,到目前已经发展了较多的求解多目标优化的方法。下面先介绍多目标优化最重要的关于非劣解以及非劣解集的定义。

    定义1 为多目标优化的可行域),不存在另一个可行点 ,使得 成立( 为目标数),且其中至少有一个严格不等式成立,则称 是多目标优化的一个非劣解(Noninferior Solution)。所有非劣解构成的集叫非劣解集(Noninferior Set)。

            一个多目标优化如果存在非劣解,往往存在无穷多个,形成非劣解集。在求解实际问题时,过多的非劣解是无法直接应用的。决策者只能选择令其最满意的一个非劣解作为最终解。求最终解主要有三类方法,一类是求非劣解的生成法,即先求出大量的非劣解,构成非劣解的一个子集,然后按照决策者的意图找出最终解,另一类为交互法,不先求出很多的非劣解,而是通过分析者与决策者对话的方式,逐步求出最终解。最后一类是事先要求决策者提供目标之间的相对重要程度,算法以此为依据,将多目标问题转化为单目标问题进行求解,该类方法也可以被认为是第一类方法的一个子方法,该类方法的难点在于,如何得到决策者真实的权重信息,本章将提出一种基于模糊逻辑的,能比较好反映决策者权重的多目标遗传算法。

            生成法主要有加权法﹑约束法﹑加权法和约束法结合的混合法以及多目标遗传算法。而交互法主要有用于求解线性约束多目标优化的Geoffrion法﹑求解线性多目标优化的逐步法(STEM)和Zionts-Wallenius方法以及代替价值交换法。

    作者认为相对而言生成法对决策者更有吸引力,首先目前没有比较好的多目标非线性优化的交互法,其次在只给决策者有限信息的前提下,往往要求决策者回答一些似是而非的问题,决策者在交互过程中将会很被动,也就是说交互法在某种程度上将问题的矛盾转嫁给了决策者。如果我们能求得非劣解的一个较好的近似解集,决策者就有了一个对问题比较全面的认识,从而能更好地进行决策和折衷。

    生成法中,常用的加权法有其固有的缺点,对于非劣解集的某些区域不可能求出。如图4.1就是一个两个目标的例子,箭头所指非劣解曲线凹的部分无法用加权法求出,出现该现象的原因是,加权法实际上是优化各个目标函数正线性组合而成的单个目标。即采用正加权系数计算的单目标最优必然是非劣解,而某些非劣解可能找不到一组正加权系数来进行求解。采用约束法可以避免该现象,但是计算代价过大,且过程很繁杂,应用前景也不乐观。利用多目标遗传算法求解非劣解集是最近几年新出现的一种求解思路,目前还处在研究

     

     

     

     

     

     

     

     

     


    4.1 加权法无法求出全部非劣解的例子

    的初始阶段,但是初步的计算结果非常令人振奋,故本章另一个研究重点就放在了多目标非劣解集算法的研究上。

    §4.2基于模糊逻辑的多目标遗传算法

    §4.2.1 模糊逻辑简介

            模糊逻辑(Fuzzy Logic)是一种新型的分类方法(分类是集合论的基本概念之一)。模糊逻辑模仿人类的智慧,引入隶属度的概念,描述介于“真”与“假”中间的过渡过程。在模糊逻辑中,事件不以集合的极限值分类,而是给每一个元素赋予一个介于01之间的实数,描述其属于一个集合的强度。具体的介绍可以参考文献【116】。

    §4.2.2 基于模糊逻辑的多目标遗传算法的思路和具体实现

            通过前面的介绍,我们知道采用模糊逻辑是一种很好的反应决策者主观意愿的工具。可以用模糊逻辑的方法反应决策者对于各个目标之间重要性的“权衡”信息。众所周知,遗传算法是依据个体的适应度进行,可以认为适应度就是决策者对于个体的综合评价,因而可以依据模糊逻辑的方法,直接构造决策者对于遗传个体的适应度的取值,即决策者对个体的综合评价。并以此作为遗传进化的依据和动力。下面是初步的算法步骤:

    1)分别求出各单目标的最优解;

    2)以(1)中的单目标的最优解和决策者协商,给出各个目标满意度的隶属函数;

    3)通过模糊逻辑表达决策者的想法,将各目标的满意度和个体的适应度联系起来;

    4)以(3)定义的适应度为基础采用遗传算法进行求解;

            之所以首先求解各个单目标的最优解,是希望能给决策者一个比较清晰的概念,即如果单独优化某个目标,可能的最优解是多少。有了这个信息,决策者才能给出令人置信的关于不同目标的满意度的隶属曲线。如果求解单目标优化的难度很大,也可以给出对单目标最优的一个估计值。

            具体的计算方法和模糊控制的计算方法基本相同,也分为模糊化(Fuzzification)﹑模糊推理(Fuzzy-Inference)和去模糊化(Defuzzification)三部分组成。在作者算法中,模糊推理采用的是最大最小法,而去模糊化采用的是面积重心法。详见参考文献【116】。

            下面以十杆桁架双目标优化为例详细叙述算法过程。

             参考图3.4,位移目标是指节点123﹑4的最大 向位移最小。这里最大 向位移指的是绝对值最大。

            这样我们就有了两个目标,即同时极小化位移和重量,可以建立比较简单的模糊逻辑如下:

    1)如果重量轻并且位移小那么设计的适应度高;

            显然上式同时对两个目标都提出了要求。而如果我们只关心重量则可以建立如下的模糊逻辑:

    2)如果重量轻不管位移大或小设计的适应度都应高;

            我们可以将模糊逻辑表示得更加精细,更符合决策者实际的想法:

    3-1)如果重量轻而且位移小那么设计的适应度很高;

    3-2)如果重量轻而且位移中等那么设计的适应度高;

    3-3)如果重量轻而且位移大那么设计的适应度一般;

    3-4)如果重量中等而且位移小那么设计的适应度高;

    3-5)如果重量中等而且位移中等那么设计的适应度中等;

    3-6)如果重量中等而且位移大那么设计的适应度低;

    3-7)如果重量大而且位移小那么设计的适应度中等;

    3-8)如果重量大而且位移中等那么设计的适应度低;

    3-9)如果重量大而且位移大那么设计的适应度很低;

            我们可以建立相应的表格表示以上逻辑:

    重量

    位移

    设计适应度

    Good

    Good

    Very High

    Good

    Normal

    High

    Good

    Bad

    Normal

    Normal

    Good

    High

    Normal

    Normal

    Normal

    Normal

    Bad

    Low

    Bad

    Good

    Normal

    Bad

    Normal

    Low

    Bad

    Bad

    Very Low

    4.1 模糊逻辑表

            采用模糊逻辑的方法实际上将目标函数映射到决策者的效用函数上,一般来说决策者的效用函数的精确描述是很困难的,目前多目标优化研究的一个重要领域就是如何合理构造决策者的效用函数。但是要决策者用带有模糊性的语言对自己的偏好加以描述却比较容易的。采用模糊逻辑的另外一个优点就是,决策者可以直观地观察到自己如果改变了模糊逻辑后,决策的变化。即求出的解始终是与决策者的真实想法接近的。在非劣解集范围较大的情况下,采用模糊逻辑可能是唯一实际可行的办法。

    §4.2.3 算例

            在上一章已经求得十杆问题的最轻重量为1598.93lb,相应的最大位移为7.171639 ,我们也可以求得最小位移为0.977492 ,相应的最大重量为15349.4496 。下面是是位移最小和重量最轻的设计点的比较。

     

    位移最小设计(

    最轻设计(

    1

    40.0000

    7.9396

    2

    40.0000

    0.1

    3

    40.0000

    8.0956

    4

    40.0000

    3.9613

    5

    0.1

    0.1

    6

    40.0000

    0.1

    7

    40.0000

    5.7554

    8

    40.0000

    5.5994

    9

    40.0000

    5.5994

    10

    40.0000

    0.1

    重量(

    15349.4496

    1598.93

    位移(

    0.977492

    7.171639

    4.2

            从上表可以很明显地看出,位移和重量是两个互相冲突的目标。

            在已知单目标极值的情况下我们采取一简单的模糊逻辑来确定个体的适应度,如果重量轻并且位移小那么适应度高。

            为简单起见,假定重量轻的隶属函数为线性的,如图4.2所示。

    1

    1598.93

    15349.4496

    重量

     

     

     

     

     

     

     

     

     


    4.2 重量轻的隶属函数

            假定位移小的隶属函数也为线性,如图4.4所示。

            个体适应度的取值范围定义为[0,1],适应度高的隶属函数也假定为线性,如图4.3所示。

            群体规模取100,代数为500代,复制概率为0.2,变异概率为0.01,随机运行十次得到如下结果:

    随机运行十次得结果如下:

    重量(

    位移(

    4567.742671

    2.288459

    4645.949119

    2.349095

    4688.605046

    2.378970

    4714.601695

    2.381532

    4887.722703

    2.460164

    更多相关内容
  • 遗传算法是用于无约束优化问题的单目标优化技术。 GA 有多种实现方式,其中一种采用 SBX 交叉和多项式变异。 该代码源自 Arvind Sheshadari [1] 对 NSGA-II 的多目标实现。 笔记: (i)与其他计算智能技术不同,...
  • 基于这样一种应用需求,单目标遗传算法很明显已经不能满足工程实践的要求了,所以需要开拓多目标的优化算法,多目标遗传算法就是在这样的背景下,好吧,是我自己需要进行多目标的优化,跟大背景没有太大的关联。...

    目录

    前言

    多目标遗传算法

    多目标的优化结果

    Pareto曲线及分层处理

    拥挤距离

    代码实现

    优化结果

    最后的话


    前言

    在很多的工程实践问题中,往往是多输入多输出的。而且最有意思的事情在于:多个输出指标总是互相矛盾的。把其中一个提高了,另外一个就会受到影响,顾此失彼。基于这样一种应用需求,单目标的遗传算法很明显已经不能满足工程实践的要求了,所以需要开拓多目标的优化算法,多目标的遗传算法就是在这样的背景下,好吧,是我自己需要进行多目标的优化,跟大背景没有太大的关联。本篇以基础知识为主,最后会加入入门级别的代码展示,只不过这个代码是我最近刚学多目标的时候编写的,写得很繁琐冗余,只能说是把多目标优化的功能实现了,代码质量很低,之后我会对代码进行优化,便于大家学习讨论。阅读这篇文章的时候认为大家已经掌握的遗传算法的基本知识了,如果单目标算法还不清楚的,建议阅读我之前的博客。

    Python—标准遗传算法求函数最大值代码实现

    多目标遗传算法

    先来推荐一篇博客,讲得还是比较清楚了:

    基于DEAP库的python进化算法-7.多目标遗传算法NSGA-II

    我参考着这篇博客的讲解思路,把我对多目标的理解记录一下,大家如果要看关于概念准确的定义,还是建议移步推荐的这篇博客。

    多目标的优化结果

    首先,需要讨论的是结果的展示问题。在单目标中,由于只有一个目标,所以我们在展示结果的时候,往往是给出的目标值的收敛曲线(有些时候也展示适应度曲线,看个人偏好了)。但是多目标优化过程不是这样的,咱以两个目标为例,分别以两个目标的结果作为坐标,得到的优化结果是什么?是一个点对吧,这一个点对于我们来说很重要,但是,由于是多目标的问题,我们很多时候就会好奇,如果我将其中一个目标做一点让步,就是它不要这么好,那另一个目标会不会变得更好呢?我们想知道它们的变化关系,所以,其实在关心这么一个点的同时,我们还想了解一条线,两个目标都还不错,但又不是最好的那条线。借一张推荐的博客里面的图说明一下这个问题。

    这个图展示的就是两个优化目标f1,f2的结果,如果我们想目标值越小越好,那就是坐标上的散点越靠近左下角越好,其实在优化的过程中就会发现,我们能去评判红色圈圈中的四个点到底谁好吗?得结合实际情况去取舍对吧?那算法它没人那么聪明,它只能进行筛选,如果在编写算法的时候,没有这种保留一条最优曲线的思路,那四个点,算法就只给你留一个,最终结果展示的时候,就会遗漏很多的信息了。这个也是为什么多目标优化和单目标优化结果有本质不同的原因。

    Pareto曲线及分层处理

    理解了结果的形式,这条曲线就顺理成章的产生了,简单地说,这条曲线就是最优解的散点连成的线,有些朋友喜欢叫最优解前沿,其实是一个意思。这里要引入分层这个概念。举个例子,比如规定的种群数量NP为50,上面那条最优解曲线上一共是7个点,那对应的7个个体认为是基因表现比较好的7个,但是迭代需要选择50个呀,7个是不够的,我们就把这7个划分为第一层,接着,把这7个剔除了,再去寻找靠近坐标左下角的散点连成第二条曲线,划分为第二层,进行迭代直到所有的散点都分层完毕了,这个过程也就结束了。之后进行选择判断的时候,就从第一层开始挑个体,一直补充到NP数量。

    拥挤距离

    这个概念其实是为曲线服务的,其实理解的最好方式是去跑一遍代码,以有没有拥挤距离这个条件为变量,就知道这家伙是干啥用的了。我先用语言跟大家解释一下。比如第一条Pareto曲线上有十个点,大家先想想我们是希望这十个点靠的近好呢,还是希望它们散开好呢?想想我们画曲线的目的,不就是为了看变化情况嘛,那你这十个点一集中,我还看啥变化情况,不如画一个点得了。就是出于这样朴实无华的目的,我们引入了拥挤距离这个概念。

    一句话概括:拥挤距离越大越好。值越大说明这条曲线散得越开,就很符合我们的要求。具体是这样用的,咱还是以NP为50举例,比如优化已经到了后期了,你的第一层上的点有70个,但是你只要取50个呀,多了好苦恼呀,这个时候我们就要加入拥挤距离作为筛选条件,取前五十个拥挤距离大的点,至于后面20个,虽然也是在第一层的,但由于它们离得近,就不要它们了,就这么任性。

    拥挤距离的具体定义和求解大家看这篇文章,人家说得比较详细,我就不再赘述了。

    多目标优化拥挤距离计算

    代码实现

    代码稍微补充一下呀,其实Python现在已经用多目标优化的库DEAP了,不想自己动手的同学可以学学怎么调用,这里以学习多目标遗传算法为主,就自己编写的。大家根据自己情况灵活选择就ok。

    求解的问题是这样的,同时优化以下两个函数的最小值:

    y=(x-1)^2

    y=cos(x)

    x取值范围是0到pi/2.

    直接上代码了:

    import numpy as np
    import matplotlib.pyplot as plt
    import math as mt
    #import seaborn as sns
    #sns.set_style('darkgrid')
    
    def funclsin(x):
        y=(x-1)**2
        return y
    
    def funclcos(x):
        y=mt.cos(x)
        return y
    #%%
    pi=mt.pi
    NP=70   #初始化种群数
    L=10    #二进制位串长度
    Pc=0.8  #交叉率
    Pm=0.2  #变异率
    G=20   #最大遗传代数
    Xs=pi/2   #上限
    Xx=0    #下限
    f=np.random.randint(0,high=2,size=(NP,L))   #生成随机初始种群
    x=np.zeros((1,140))[0].tolist()
    tempx=np.zeros((1,140))[0].tolist()
    f1trace=[]         #记录第一个目标函数
    f2trace=[]         #记录第二个目标函数
    
    #%%遗传算法循环
    for i in range(G):
        print(i)
        f1=[]
        f2=[]
        nf=f                   #出新的种群,在其基础上进行交叉、变异
        for M in range(0,NP,2):
            p=np.random.rand()     #交叉
            if p<Pc:
                q=np.random.randint(0,high=2,size=(1,L))[0].tolist()
                for j in range(L):
                    if q[j]==1:
                        temp=nf[M+1][j]
                        nf[M+1][j]=nf[M][j]
                        nf[M][j]=temp
        j=1
        while j<=(NP*Pm):
            h=np.random.randint(1,high=NP)  #变异
            for k in range(round(L*Pm)):
                g=np.random.randint(1,high=L)
                nf[h][g]=(not nf[h][g])+0         #取反操作,python和matlab不一样
            j+=1
        #交叉变异结束之后,新一代nf加上前代f共2*NP个个体进行筛选
        newf=np.vstack((f,nf))         #垂直方向累加两个f
        for j in range(newf.shape[0]):
            U=newf[j]
            m=0
            for k in range(L):
                m=U[k]*(2**(k-1))+m    #将二进制解码为定义域范围内十进制
            x[j]=Xx+m*(Xs-Xx)/(2**(L-1))
            f1.append(funclsin(x[j]))
            f2.append(funclcos(x[j]))
        fs=[]
    #    plt.scatter(f1,f2)
    #    plt.savefig(r'C:\Users\王耀\Desktop\Genetic Algorithm\pic\exx'+str(i),bbox_inches = 'tight',pad_inches = 0,dpi =100)
    #    plt.close()
        for j in range(len(f1)):
            fs.append(f1[j])
            fs.append(f2[j])
        fs=np.array(fs)
        fs=fs.reshape(len(f1),2)                #把求解得到的适应度函数转换为多目标散点的形式
        fs=fs.tolist()
        ps=np.zeros((len(f1),len(f1)))                    #i,j=1,i支配j,我们希望点的值越小越好
        for k in range(0,len(f1)):
            for j in range(0,len(f1)):
                if fs[k][0]<fs[j][0] and fs[k][1]<fs[j][1]:
                    ps[k][j]=1                  #这一步是这样的,ps是一个比较矩阵,如果100个点互相比(包括自己)
                                                #如果被置1了,就说明被支配了,全部比完之后,纵向全为0,则说明没有点支配自己
        jishu=[]
        for k in range(len(ps)):
            aa=0
            for j in range(len(ps)):
                if ps[j][k]==1:
                    aa+=1
            jishu.append(aa)
            
        sortjishu=np.sort(jishu)                #升序排序    
        index= np.argsort(jishu)                #升序对应索引
        aaa=list(set(sortjishu))
        front=[[] for k in range(len(set(sortjishu)))]
        for k in range(len(set(sortjishu))):
            for j in range(len(index)):
                if sortjishu[j]==aaa[k]:
                    front[k].append(index[j])    #记录对应的索引位置
                    
    #只是依靠分层的话,很可能最后会优化到一个点上
    #所以需要加入拥挤距离来刻画点的分布情况
        f=[]
        for j in range(len(front)):
            if len(f)==NP:
    #            print(2)
                break
            tempf=[]
            for k in range(len(front[j])):
                tempf.append(newf[front[j][k]])  #把第J层的染色体添加进入tempf中
            tempf1=[]
            tempf2=[]      
            for M in range(len(tempf)):          #计算第j层染色体的函数值,存在temf1.2中
                U=tempf[M]
                m=0
                for k in range(L):
                    m=U[k]*(2**(k-1))+m    #将二进制解码为定义域范围内十进制
                tempx[M]=Xx+m*(Xs-Xx)/(2**(L-1))
                tempf1.append(funclsin(tempx[M]))
                tempf2.append(funclcos(tempx[M]))
                
            #对f1计算其拥挤距离,此时与f2无关。
            tempf1index=np.argsort(tempf1)   #tempf1升序排序
            distance=np.zeros(len(tempf1))
            #将两端位置值置为正负无穷
            for k in range(len(tempf1)):
                if tempf1[k]==max(tempf1):
                    distance[k]=float('inf')
                elif tempf1[k]==min(tempf1):
                    distance[k]=float('inf')
            #计算每个点在f1下的拥挤距离
            for k in range(len(tempf1index)):
                if abs(distance[tempf1index[k]])<10:      #把极值点排除在外
                    distance[tempf1index[k]]=(tempf1[tempf1index[k+1]]-tempf1[tempf1index[k-1]])/(max(tempf1)-min(tempf1))
                else:
                    continue
                
            #对f2计算拥挤距离,与f1无关
            tempf1index1=np.argsort(tempf2)   #tempf2升序排序
            distance1=np.zeros(len(tempf1))
            #将两端位置值置为正负无穷
            for k in range(len(tempf2)):
                if tempf2[k]==max(tempf2):
                    distance1[k]=float('inf')
                elif tempf2[k]==min(tempf2):
                    distance1[k]=float('inf')
                    #计算每个点在f2下的拥挤距离
            for k in range(len(tempf1index1)):
                if abs(distance1[tempf1index1[k]])<10:      #把极值点排除在外
                    distance1[tempf1index1[k]]=(tempf2[tempf1index1[k+1]]-tempf2[tempf1index1[k-1]])/(max(tempf2)-min(tempf2))
                else:
                    continue
                
            sumdis=[]                          #当收敛到一个点时,拥挤距离就失去意义了
            
            for k in range(len(distance)):
                sundistance=distance[k]+distance1[k]
                sumdis.append(sundistance)
            disindex=np.argsort(sumdis)[::-1]  #sumdis降序排序(拥挤距离越大越好)
            for k in range(len(sumdis)):
                f.append(tempf[disindex[k]])
                if len(f)==NP:
                    break
                else:
                    continue
            f1=[]
            f2=[]      
            for j in range(len(f)):
                U=f[j]
                m=0
                for k in range(L):
                    m=U[k]*(2**(k-1))+m    #将二进制解码为定义域范围内十进制
                x[j]=Xx+m*(Xs-Xx)/(2**(L-1))
                f1.append(funclsin(x[j]))
                f2.append(funclcos(x[j]))       
        plt.scatter(f1,f2)
        plt.savefig(r'C:\Users\王耀\Desktop\Genetic Algorithm\pic\exx1'+str(i),bbox_inches = 'tight',pad_inches = 0,dpi =100)
        plt.close()

     简单说一下需要注意的地方:

     for j in range(len(f1)):
            fs.append(f1[j])
            fs.append(f2[j])
        fs=np.array(fs)
        fs=fs.reshape(len(f1),2)                #把求解得到的适应度函数转换为多目标散点的形式
        fs=fs.tolist()
        ps=np.zeros((len(f1),len(f1)))                    #i,j=1,i支配j,我们希望点的值越小越好
        for k in range(0,len(f1)):
            for j in range(0,len(f1)):
                if fs[k][0]<fs[j][0] and fs[k][1]<fs[j][1]:
                    ps[k][j]=1                  #这一步是这样的,ps是一个比较矩阵,如果100个点互相比(包括自己)
                                                #如果被置1了,就说明被支配了,全部比完之后,纵向全为0,则说明没有点支配自己

    这里的ps是一个比较矩阵(用二维列表写的),它的作用是对每个点进行比较,如果是在比较之后,处于被支配的点(比如在右上角的)我们就把它置1,这样在获得ps之后,统计每个个体1的数目,1越少,个体就越优秀。

     f=[]
        for j in range(len(front)):
            if len(f)==NP:
    #            print(2)
                break
            tempf=[]
            for k in range(len(front[j])):
                tempf.append(newf[front[j][k]])  #把第J层的染色体添加进入tempf中
            tempf1=[]
            tempf2=[]      
            for M in range(len(tempf)):          #计算第j层染色体的函数值,存在temf1.2中
                U=tempf[M]
                m=0
                for k in range(L):
                    m=U[k]*(2**(k-1))+m    #将二进制解码为定义域范围内十进制
                tempx[M]=Xx+m*(Xs-Xx)/(2**(L-1))
                tempf1.append(funclsin(tempx[M]))
                tempf2.append(funclcos(tempx[M]))
                
            #对f1计算其拥挤距离,此时与f2无关。
            tempf1index=np.argsort(tempf1)   #tempf1升序排序
            distance=np.zeros(len(tempf1))
            #将两端位置值置为正负无穷
            for k in range(len(tempf1)):
                if tempf1[k]==max(tempf1):
                    distance[k]=float('inf')
                elif tempf1[k]==min(tempf1):
                    distance[k]=float('inf')
            #计算每个点在f1下的拥挤距离
            for k in range(len(tempf1index)):
                if abs(distance[tempf1index[k]])<10:      #把极值点排除在外
                    distance[tempf1index[k]]=(tempf1[tempf1index[k+1]]-tempf1[tempf1index[k-1]])/(max(tempf1)-min(tempf1))
                else:
                    continue
                
            #对f2计算拥挤距离,与f1无关
            tempf1index1=np.argsort(tempf2)   #tempf2升序排序
            distance1=np.zeros(len(tempf1))
            #将两端位置值置为正负无穷
            for k in range(len(tempf2)):
                if tempf2[k]==max(tempf2):
                    distance1[k]=float('inf')
                elif tempf2[k]==min(tempf2):
                    distance1[k]=float('inf')
                    #计算每个点在f2下的拥挤距离
            for k in range(len(tempf1index1)):
                if abs(distance1[tempf1index1[k]])<10:      #把极值点排除在外
                    distance1[tempf1index1[k]]=(tempf2[tempf1index1[k+1]]-tempf2[tempf1index1[k-1]])/(max(tempf2)-min(tempf2))
                else:
                    continue
                
            sumdis=[]                          #当收敛到一个点时,拥挤距离就失去意义了

    这一段代码是计算拥挤距离用的,拥挤距离是针对两个目标函数分别计算,最后再把距离相加进行比较。

    优化结果

    结果比较简单,因为咱这选的函数比较简单,主要是学习为主嘛。

    下面是第一代的种群两个目标函数值的关系图:(迭代一次了)

     之后是迭代15次的结果:

     收敛速度和计算速度都是相当快的,大家可以更换测试函数再进行测验。

    最后的话

    在代码调试的过程中,有时会出现收敛到单点的情况(迭代次数大了之后),我不知道这个是不是跟Python的初始种群随机生成的机制有关系,了解的朋友可以私信我讨论一下。谢谢大家。

    展开全文
  • 多目标遗传算法及MATLAB代码

    万次阅读 多人点赞 2020-01-03 23:12:49
    需要求一个比较复杂的矩阵,一般方法解不出来,故尝试用多目标遗传算法(Multiobjective Genetic Algorithm)求解。不是专门做研究遗传算法的,根据自己需求进行了简单学习,并做如下笔记。 i 遗传算法理解 遗传...

    需要求一个比较复杂的矩阵,一般方法解不出来,故尝试用多目标遗传算法(Multiobjective Genetic Algorithm)求解。不是专门做研究遗传算法的,根据自己需求进行了简单学习,并做如下笔记。

    i 遗传算法理解

    遗传算法属于一种搜索算法,通过不断试错,当结果满足提前设置精度时,停下来。理论上而言,只要计算时间足够长,计算能力足够大,穷举法就可以实现这一目标,并不需要这些听上去高大上的算法。关键问题是,如何快速收敛。遗传算法(Genetic algorithm)是一种从生物学获得灵感(往往运用最广的算法,核心都很简单,毕竟简单才方便推广),通过选择(selection)、交叉(crossover)和变异(Mutation)等操作让收敛速度加快,具体理论和操作前辈们早已论证,详见参考文献。类似算法还有模拟退火算法(Simulated Annealing)、粒子群算法(Paricle Swarm)等。

     

    ii 基本概念解释

    1. 概念

    染色体(chromosome):可能的解,编码化的解称为基因型(genetic type)解;实际的解称为表现型(pheno type)解

    种群数(population size):随机生成的初始解的个数;

    适值函数(fitness function): 评价染色体优劣性的函数,可以简单理解为与目标值的差异

    目标函数(objective function):限定函数,用于限制求解变量的函数

    决策变量(decision variables):所需要求解的变量,也就是求解问题的维数

    遗传操作(genetic_operator)包括:

    交叉(corssover):两个染色体之间部分基因互换;交叉率(crossover probability)交叉操作的概率。

    变异(mutation):单个染色体中部分基因变化,保持多样性;变异率(mutaiton probability)变异操作的概率。

    选择(selection):选择出适应性高的染色体,进行下一代操作。

    最大代数(maximum generaiton):进化循环次数,最大迭代次数。

     

    2. Pareto解或非支配解(non-dominated solution)

    最大值问题,对于解X,

    若不存在X1,使得F(X1)>F(X),则X为弱Pareto最优解,此时F(X1)可以等于F(X)

    若不存在X1,使得F(X1)>=F(X),则X为Pareto最优解,也称非劣解

     

    3. 多目标遗传算法种类

    本文讨论非支配排序遗传算法(Non-dominated Sorting Genetic Algorithm II),NSGA-II(参考文献【2】和《网络模型与多多目标遗传算法》P165)

     

    iii NSGA-II求解步骤和MATLAB代码 

    首先,根据自己的问题定义目标函数(objective_description_function)和评价函数(evaluate_objective),然后运行主函数即可。主函数由如下几个函数组成。

    主函数  nsga_2 (i.e. 非支配排序遗传算法的求解步骤)

    • STEP 1: initialize_variables,随机生成染色体种群,随机解
    • STEP 2: non_domination_sort_mod,解的非支配排序
    • STEP 3: tournament_selection,精英策略的竞赛选择
    • STEP 4: genetic_operator,基因操作
    • STEP 5: replace_chromosome,替换第一代染色体,进入下一次迭代

     

    MATLAB代码

    参考Aravind Seshadri 发布的代码

    Aravind Seshadri (2020). NSGA - II: A multi-objective optimization algorithm, MATLAB Central File Exchange. Retrieved January 6, 2020.

    CSDN joekepler 有将上述部分代码做中文注释

    NSGA2 算法MATLAB完整代码 中文注释详解

    大家可以中英文对照参考着看,很好理解的。Aravind Seshadri写的相当详细,自惭形秽,我就不写了。

     

    【参考文献】

    1. (入门了解)  超详细的遗传算法(Genetic Algorithm)解析  
    2. Kalyanmoy Deb, et al., A fast and Elitist multiobjective genetic algorithm: NSGA-II 
    3. 雷英杰 等,MATLAB遗传算法工具箱及应用,西安电子科技大学出版社【其中很多函数已经被包装进GA,不能用了】
    4. [日] 玄光男,等,网络模型与多目标遗传算法,清华大学出版社
    5. [日] 玄光男,等,遗传算法与工程优化,清华大学出版社
    6. MATLAB Global Optimizaiton Toolbox 
    7. NSGA2 算法MATLAB完整代码 中文注释详解 
    8. Aravind Seshadri (2020). NSGA - II: A multi-objective optimization algorithm, MATLAB Central File Exchange. Retrieved January 6, 2020.
    展开全文
  • 多目标优化问题可以描述如下: 其中,f(x) 为待优化的目标函数;x 为 待优化的变量;lb 和 ub 分别为变量 x 的下限和上限约束;Aeq * x = beq 为变量 x 的线性等式约束;A * x <= b 为变量 x 的线性不等式约束。...

    一、理论基础

    多目标优化问题可以描述如下:

            其中,f(x) 为待优化的目标函数;x 为 待优化的变量;lb 和 ub 分别为变量 x 的下限和上限约束;Aeq * x = beq 为变量 x 的线性等式约束;A * x <= b 为变量 x 的线性不等式约束


            在上图所示的优化问题中,目标函数 f1 和 f2 是相互矛盾的。因为 A1 < B1 且 A2 > B2,也就是说,某一个目标函数的提高需要以另一个目标函数的降低作为代价,称这样的解 A 和解 B 是非劣解,或者说是 Pareto 最优解。多目标优化算法的目的就是要寻找这些 Pareto 最优解。

            目前的多目标优化算法有很多,Kalyanmoy Deb 的带精英策略的快速非支配排序遗传算法(nondominated sorting genetic algorithm II,NSGA- II)无疑是其中应用最为广泛也是最为成功的一种。MATLAB R2009a 版本提供的函数 gamultiobj 所采用的算法就是基于 NSGA - II 改进的一种多目标优化算法(a variant of NSGA - II)。本案例将以函数 gamultiobj 为基础,对基于遗传算法的多目标优化算法进行详细分析,并介绍函数gamultiobj的使用。
            1、支配(dominnate)与非劣(non - inferior)
            在多目标优化问题中,如果个体 p 至少有一个目标比个体 q 的好,而且个体 p 的所有目标都不比个体 q 的差,那么称个体 p 支配个体 q(p dominates q),或者称个体 q 受个体 p 支配(qis dominated by p),也可以说,个体 p 非劣于个体 q(p is non - inferior to q)。
            2、序值(rank)和前端(front)
            如果 p 支配 q,那么 p 的序值比 q 的低。如果 p 和 q 互不支配,或者说, p 和 q 相互非劣,那么 p 和 q 有相同的序值。序值为 1 的个体属于第一前端,序值为 2 的个体属于第二前端,依次类推。显然,在当前种群中,第一前端是完全不受支配的,第二前端受第一前端中个体的支配。这样,通过排序,可以将种群中的个体分到不同的前端。
            3、拥挤距离(crowding distance)
            拥挤距离用来计算某前端中的某个体与该前端中其他个体之间的距离,用以表征个体间的拥挤程度。显然,拥挤距离的值越大,个体间就越不拥挤,种群的多样性就越好。需要指出的是,只有处于同一前端的个体间才需要计算拥挤距离,不同前端之间的个体计算拥挤距离是没有意义的。
            4、最优前端个体系数(ParetoFraction)
            最优前端个体系数定义为最优前端中的个体在种群中所占的比例,即最优前端个体数 = min { ParetoFraction * 种群大小,前端中现存的个体数目 },其取值范围为 0~1。需要指出的是,ParetoFraction 的概念是函数 gamultiobj 所特有的,在 NSGA - II 中是没有的,这也是为什么称函数 gamultiobj 是一种多目标优化算法的原因。

    二、案例简述

    1、问题描述

            待优化的多目标问题表述如下:

     2、解题思路及步骤

            这里将使用函数 gamultiobj 求解以上多目标优化问题。同函数 ga 的调用一样,函数 gamultiobj 的调用方式也有两种:GUI 方式和命令行方式

            通过 GUI 方式调用 gamultiobj

            通过以下两种方式可以调出函数 gamultiobj 的 GUI 界面:
            (1)在 MATLAB主界面上依次单击 APPS→Optimization,在弹出的 Optimization Tool 对话框的 Solver 中选择 “gamultiobj - Multiobjective optimization using Genetic Algorithm” 。
            (2)在 Command Window 中输入:optimtool('gamultiobj') 命令
            可以看到,函数 gamultiobj 的 GUI 界面与函数 ga 的 GUI 界面大致相同,仅在以下几个方面存在区别
            (1)前者比后者多了 Distance measure function 和 Pareto front population fraction 两个参数。
            (2)前者比后者少了参数 Elite count,这是因为函数 gamultiobj 的精英是自动保留的;前者比后者少了 Scaling function,这是因为函数 gamultiobj 的选择是基于序值和拥挤距离的,故不再需要 Scaling 的处理;函数 gamultiobj 没有非线性约束。
            (3)绘图函数不同及下列设置的默认值不同;种群大小(Population size)、选择函数(Selection function)、交叉函数(Crossover function)最大进化代数(Generations)停止代数(Stall generations)适应度函数值偏差(Function tolerance)。

            通过命令行方式调用函数 gamultiobj

            gamultiobj 的命令行调用格式为:

    [x, fval] = gamultiobj(fitnessfcn, nvars, A, b, Aeq, beq, lb, ub, options)

             其中,x 为函数 gamultiobj 得到的 Pareto 解集fval 为 x 对应的目标函数值fitnessfcn 为目标函数句柄,同函数 ga 一样,需要编写一个描述目标函数的 M 文件;nvars 为变量数目;A、b、Aeq、beq 为线性约束,可以表示为 A * x <= B,Aeq * x = beq;lb,ub为上、下限约束,可以表述为 lb <= x <= ub,当没有约束时,用 “ [ ] ” 表示即可;options 中需要对多目标优化算法进行一些设置,即

    options = gaoptimset('Param1', value1, 'Param2', value2, ... );

            其中,Param1,Param2 等是需要设定的参数,如最优前端个体系数、拥挤距离计算函数、约束条件、终止条件等;valuel,value2 等是 Param 的具体值。Param 有专门的表述方式,如最优前端个体系数对应于 ParetoFraction,拥挤距离计算函数对应于 DistanceMeasureFcn 等。

    三、MATLAB 程序实现

    1、使用函数 gamultiobj 求解多目标优化问题

            (1)使用函数 gamultiobj 求解多目标优化问题的第一步是编写目标函数的M文件。对于以上问题,函数名为my_first_multi,目标函数代码如下:

    function f = my_first_multi(x)
     
    f(1) = x(1)^4 - 10*x(1)^2+x(1)*x(2) + x(2)^4 - (x(1)^2)*(x(2)^2);
    f(2) = x(2)^4 - (x(1)^2)*(x(2)^2) + x(1)^4 + x(1)*x(2);

            (2)使用命令行方式调用 gamultiobj 函数,代码如下:

    clear
    clc
     
    
    fitnessfcn = @my_first_multi;   % Function handle to the fitness function
    nvars = 2;                      % Number of decision variables
    lb = [-5,-5];                   % Lower bound
    ub = [5,5];                     % Upper bound
    A = []; b = [];                 % No linear inequality constraints
    Aeq = []; beq = [];             % No linear equality constraints
    options = gaoptimset('ParetoFraction',0.3,'PopulationSize',100,'Generations',200,'StallGenLimit',200,'TolFun',1e-100,'PlotFcns',@gaplotpareto);
    
    [x,fval] = gamultiobj(fitnessfcn,nvars, A,b,Aeq,beq,lb,ub,options);

            其中,fitnessfcn 即(1)中定义的目标函数 M 文件,设置的最优前端个体系数 ParetoFrac -tion 为 0.3,种群大小 PopulationSize 为 100,最大进化代数 Generations 为 200,停止代数StallGenLimit 也为 200,适应度函数值偏差 TolFun 为 le - 100,绘制 Pareto 前端。当然,也可以通过 GUI 方式调用函数 gamultiobj,其方法与函数 ga 的调用相同。

    2、结果分析

            可以看到,在基于遗传算法的多目标优化算法的运行过程中,自动绘制了第一前端中个体的分布情况,且分布随着算法进化一代而更新一次。当迭代停止后,得到如下图所示的第一前端个体分布图

             同时, Worksapce 中返回了函数 gamultiobj 得到的 Pareto 解集 x 及与 x 对应的目标函数值。需要说明的是,由于算法的初始种群是随机产生的,因此每次运行的结果不一样。
            从上图可以看到,第一前端的 Pareto 最优解分布均匀。返回的 Pareto 最优解个数为 30 个,而种群大小为 100,可见,ParetoFraction 为 0.3 的设置发挥了作用。另外,个体被限制在了 [ -5,5 ] 的上下限范围内。

    展开全文
  • 多目标遗传算法NSGA

    万次阅读 多人点赞 2017-05-01 22:19:47
    多目标遗传算法NSGA因所读的一篇论文中,为了解决目标的最优解问题,作者使用了一种称为NSGA-II(Improved Non-dominated Sorting Genetic Algorithm)的遗传算法,花了两天时间了解下,此为何物。其中NSGA以及NSGA-...
  • 对任意目标函数的优化问题转化成两个目标函数的优化问题,并对转化后的优化问题设计了遗传算法,同时把均匀性分布指标函数引入算法的变异操作中,用于自适应地调节搜索向Pareto最优解集移动和更好地获得解的均匀...
  • 【MATLAB】matlab多目标遗传算法的用法

    千次阅读 多人点赞 2020-07-20 23:45:13
    用于求解多目标优化问题 object1 和object 2有一定的竞争关系 得到的解是一组解,称为帕累托前沿 pareto front options = optimoptions('gamultiobj','PlotFcn',... {@gaplotpareto},'UseParallel',true); func=@...
  • 第九章 基于遗传算法多目标最优化算法基础理论pareto最优解多目标优化NSGA一II算法的基本思想(1) 基本原理(2) 算法流程(3) 算法缺陷2. 带精英策略的非支配排序的遗传算法(NSGA-II) 基础理论 pareto最优解 带精英...
  • 多目标优化问题概述(遗传算法

    千次阅读 2020-05-09 14:06:58
    遗传算法(进化算法)的主要原理和应用
  • 问题描述 前置背景 ...问题二是无人机航线规划多目标问题,总共有九架无人机,所以相当于有9个子问题 如图从上到下依次是九架无人机在各自所能支持的通信方式和飞行海拔下的通信范围网,其中青色代表D1通
  • 本文讲述了笔者关于NSGA-II和一些多目标优化概念的理解,包括多目标优化问题,支配,Pareto最优,以及非支配排序和拥挤距离,最后简单阐述NSGA-II的整体流程,并概括了关于NSGA-II的一些优点和缺点。......
  • 多目标优化求解思路二.NSGA-II算法解析1.快速非支配排序(Fast non-dominated sort)2.拥挤距离计算(Crowding distance assignment)3.精英保存策略(Elitism)三.NSGA-II算法实现1.测试函数 一.多目标优化简介 1.多目标...
  • 多目标遗传算法优化

    万次阅读 热门讨论 2017-03-31 20:29:37
    %% 遗传算法求解多目标优化案例 %% 将原多目标函数改写为f1=(x^2+y^2)/4;f2=x(1-y)+10; % 运用线性叠加法,F=a*f1(x)+b*f2(x) ,a+b=1 % 总目标函数改写为 f=0.6*(x^2+y^2)/4+0.4*(x*(1-y)+10); popse=100; % ...
  • python--多目标规划问题
  • 遗传算法 建立GeneticAlgorithm.py import numpy as np from GAIndividual import GAIndividual import random import copy import matplotlib.pyplot as plt class GeneticAlgorithm: ''' The class for....
  • 多目标优化系列: MOP_1. 多目标优化的相关基本概念 MOP_2. 非支配排序遗传算法 —(NSGA、...1995年,Srinivas和Deb提出了非支配排序遗传算法(Non-dominatedSorting Genetic Algorithms,NSGA)。这是一种基于P...
  • 在前面几篇文章中,我们已经介绍了高性能Python遗传和进化算法框架——Geatpy的使用及一些案例。...
  • JSSP 是使用遗传算法实现的作业车间调度问题解决器。给定一组有限的作业,每个作业由一系列操作组成,每个操作由给定的机器在设定的时间内执行。还必须考虑到每个操作可以有其他操作作为依赖项,并且某些操作可以...
  • 多目标规划问题定义 在实际问题中大都具有目标且需要同时满足,即在同一问题模型中同时存在几个非线性目标,而这些目标函数需要同时进行优化处理,并且这些目标又往往是互相冲突的,称这类问题称为多目标规划...
  • 目标遗传算法 精英保留策略

    千次阅读 2020-10-19 08:48:18
    遗传算法(Genetic Algorithm)中的基因,并不一定真实地反映了待求解问题的本质,因此各个基因之间未必就相互独立,如果只是简单地进行杂交,很可能把较好的组合给破坏了,这样就没有达到累积较好基因的目的,
  • %% 遗传算法求解多目标优化案例 %% 将原多目标函数改写为f1=(x^2+y^2)/4;f2=x(1-y)+10; % 运用线性叠加法,F=a*f1(x)+b*f2(x) ,a+b=1 % 总目标函数改写为 f=0.6*(x^2+y^2)/4+0.4*(x*(1-y)+10); popse=100...
  • 遗传算法 我们的人口由不同的个体组成,分别对应于不同的回路。 这些电路是根据定义的适用性进行评估的。 在此问题的范围内,个人的适应度越高,将产生的解决方案越好。 为此,我们将考虑输出(电路是否产生正确的...
  • (背包问题):背包只能容得下一定重量b的物品,物品有m种,每种物品有自己的重量w(i)和价值v(i),从这些物品中选择装入背包,是背包不超过重量b,但价值又要最大。... 遗传算法作经典的人工智能算法,可以很
  • 序 在(一)中我介绍了GA、NSGA以及NSGA-II算法以及他们之间的关系,据完成(一)已经差不多10个月了,当初的愿望实现了吗,事到...废话不说,有关NSGA-II算法的请参考第一篇文章:多目标非支配排序遗传算法-NSGA-I
  • 遗传算法关于多目标优化python(详解)

    万次阅读 多人点赞 2018-06-13 15:20:52
    之前学习了遗传算法对单目标函数的最优值求解,对于多目标问题。或者说是变量参数的求解问题,我想再研究一下。正好,我也想改进一下之前的代码架构。不得不说,之前的代码是面向过程的架构,完全没有体现出python...
  • 遗传算法概述

    千次阅读 2022-03-03 10:02:12
    对于实际问题中的目标函数和约束条件种类繁多中的最优化问题,有的是线性的,有的是非线性的;有的是连续的,有的是离散的;有的是单峰值的,有的是峰值的。随着研究的深入,人们逐渐认识到在很复杂情况下要想完全...
  • 多目标优化算法,非支配的精英策略遗传算法:NSGA-II 1.算法简介 NSGA-II算法特点:快速非支配排序算法、精英保留策略、拥挤度分配策略。 相比于NSGA的优势: 排序算法的时间复杂度 O(MN2)O(MN^2)O(MN2) ...
  • 遗传算法讲解与实现(python)

    千次阅读 2021-10-27 16:49:51
    遗传算法在我看来是一种调参的时候可以考虑的算法,是一种可以找到全局最优参数的一种方法,当需要调参的数据范围很大的时候,穷举法显然不是一个很好的选择!这里通过一个简单的例子将遗传算法进行实现,以小见大。...
  • @多目标优化问题和遗传算法学习笔记 多目标优化问题和遗传算法学习笔记 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,780
精华内容 3,912
热门标签
关键字:

多目标遗传算法定义