遗传算法解决带约束的多目标优化问题

对于下述知识可先学习:Geatpy库学习流程_要努力呦的博客-CSDN博客

        

        有了以上的经验后,对于如何使用 Geatpy 面向对象进化算法框架求解新的问题就 会得心应手。下面看一个带约束的多目标优化问题: 

 编写问题类如下:

# -*- coding: utf-8 -*-
"""MyProblem.py"""
import numpy as np
import geatpy as ea
class MyProblem(ea.Problem): # 继承Problem父类
    def __init__(self):
        name = 'BNH' # 初始化name(函数名称,可以随意设置)
        M = 2 # 初始化M(目标维数)
        maxormins = [1] * M # 初始化maxormins
        Dim = 2 # 初始化Dim(决策变量维数)
        varTypes = [0] * Dim #
#         初始化varTypes(决策变量的类型,0:实数;1:整数)
        lb = [0] * Dim # 决策变量下界
        ub = [5, 3] # 决策变量上界
        lbin = [1] * Dim # 决策变量下边界
        ubin = [1] * Dim # 决策变量上边界
        # 调用父类构造方法完成实例化
        ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb,
        ub, lbin, ubin)
    def aimFunc(self, pop): # 目标函数
        Vars = pop.Phen # 得到决策变量矩阵
        x1 = Vars[:, [0]] # 注意这样得到的x1是一个列向量,表示所有个体的x1
        x2 = Vars[:, [1]]
        f1 = 4*x1**2 + 4*x2**2
        f2 = (x1 - 5)**2 + (x2 - 5)**2
        # 采用可行性法则处理约束
        pop.CV = np.hstack([(x1 - 5)**2 + x2**2 - 25,
        -(x1 - 8)**2 - (x2 - 3)**2 + 7.7])
        # 把求得的目标函数值赋值给种群pop的ObjV
        pop.ObjV = np.hstack([f1, f2])
    def calReferObjV(self): # 计算全局最优解
        N = 10000 # 欲得到10000个真实前沿点
        x1 = np.linspace(0, 5, N)
        x2 = x1.copy()
        x2[x1 >= 3] = 3
        return np.vstack((4 * x1**2 + 4 * x2**2,
        (x1 - 5)**2 + (x2 - 5)**2)).T

        Geatpy 的问题类有三大函数:构造函数(又称“构造方法”)__init()__()、目标 函数 aimFunc() 以及计算理论参考解的目标函数参考值(常常是理论最优解)的函数 calReferObjV()。如果实际问题并不知道模型的理论最优解的目标函数参考值,那么 calReferObjV() 函数的定义可以被省略。在多目标优化中,“真实帕累托前沿”可在 calReferObjV() 中进行计算或读取文件得到。

完成了问题类的定义后,对“2.2.1”中的执行脚本“main.py”略加修改便可以用于当前问题的求解:

# -*- coding: utf-8 -*-
"""main.py"""
import geatpy as ea # import geatpy
from MyProblem import MyProblem # 导入自定义问题接口
"""=========================实例化问题对象==========================="""
problem = MyProblem() # 实例化问题对象
"""===========================种群设置=============================="""
Encoding = 'RI' # 编码方式
NIND = 100 # 种群规模
Field = ea.crtfld(Encoding, problem.varTypes, problem.ranges,
problem.borders) # 创建区域描述器
population = ea.Population(Encoding, Field, NIND) #
# 实例化种群对象(此时种群还没被真正初始化,仅仅是生成一个种群对象)
"""=========================算法参数设置============================"""
myAlgorithm = ea.moea_NSGA2_templet(problem, population) #
实例化一个算法模板对象
myAlgorithm.MAXGEN = 200 # 最大遗传代数
myAlgorithm.drawing = 1 # 设置绘图方式
"""===================调用算法模板进行种群进化=======================
调用run执行算法模板,得到帕累托最优解集NDSet。
NDSet是一个种群类Population的对象。
NDSet.ObjV为最优解个体的目标函数值;NDSet.Phen为对应的决策变量值。
详见Population.py中关于种群类的定义。
"""
NDSet = myAlgorithm.run() # 执行算法模板,得到非支配种群
NDSet.save() # 把结果保存到文件中
# 输出
print('用时:%f 秒'%(myAlgorithm.passTime))
print('评价次数:%d 次'%(myAlgorithm.evalsNum))
print('非支配个体数:%d 个'%(NDSet.sizes))
print('单位时间找到帕累托前沿点个数:%d 个'%(int(NDSet.sizes //
    myAlgorithm.passTime)))
# 计算指标
PF = problem.getReferObjV() # 获取真实前沿
if PF is not None and NDSet.sizes != 0:
    GD = ea.indicator.GD(NDSet.ObjV, PF) # 计算GD指标
    IGD = ea.indicator.IGD(NDSet.ObjV, PF) # 计算IGD指标
    HV = ea.indicator.HV(NDSet.ObjV, PF) # 计算HV指标
    Spacing = ea.indicator.Spacing(NDSet.ObjV) # 计算Spacing指标
    print('GD: %f'%GD)
    print('IGD: %f'%IGD)
    print('HV: %f'%HV)
    print('Spacing: %f'%Spacing)
"""=====================进化过程指标追踪分析========================"""
if PF is not None:
    metricName = [['IGD'], ['HV']]
    [NDSet_trace, Metrics] =ea.indicator.moea_tracking(myAlgorithm.pop_trace, PF,
        metricName, problem.maxormins)
    # 绘制指标追踪分析图
    ea.trcplot(Metrics, labels = metricName, titles = metricName)

        上述执行脚本调用了多目标优化的“moea_NSGA2_templet”算法模板,它实现的是多目标优化 NSGA-II 算法,详见“moea_NSGA2_templet.py”源码。

        在调用完算法模板后,通过 problem 对象的“getReferObjV()”方法获取真实前沿。这 里也许会产生疑问:前面“MyProblem.py”中不是定义了“calReferObjV()”方法来计算 问题的真实前沿吗?并没有定义“getReferObjV()”函数。实际上,“getReferObjV()”函数 是自定义的“MyProblem”类的父类:“Problem”中定义的一个函数(详见“Problem.py”), 它将先尝试读取本地的特定格式的全局最优解参考值的记录文件,如果没有找到,它将 调用自定义的“calReferObjV()”函数来计算全局最优解的参考值(这里即真实前沿), 计算完成后,它把结果按照特定格式保存到“Real_Best”文件夹下面的.csv 文件中。

        上述执行脚本还展示了如何使用 Geatpy 提供的多目标优化进化过程指标追踪分析功能。调用工具箱的“indicator.moea_tracking()”函数即可完成指标追踪分析,为此需 要一个保存着历代种群对象的列表“pop_trace”,该列表在进化算法模板的父类中有定 义(详见“Algorithm.py”中的“MoeaAlgorithm 类”——多目标进化优化算法模板父类, Geatpy 中所有的多目标进化优化算法模板都继承了这个父类)。

  • 4
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
遗传算法是一种常用于解决优化问题算法,而约束条件的优化问题是指在优化过程中需满足一些约束条件。MATLAB中的遗传算法工具箱提供了一套完整的工具用于解决约束条件的优化问题。 在MATLAB中使用遗传算法解决约束条件的优化问题的步骤如下: 1. 定义适应度函数:根据具体问题定义一个适应度函数。适应度函数的设计需考虑到目标函数以及约束条件,以衡量每个个体的优劣程度。 2. 设置遗传算法参数:包括种群大小、遗传操作的概率(交叉与变异的概率)、遗传算法迭代次数、终止条件等。 3. 设计变量的表示方式:根据具体问题,将变量进行二进制编码或者编码为实数。 4. 设计遗传算法的编码和解码方法:对变量进行编码和解码,以便在遗传算法中进行操作。 5. 定义遗传算法的遗传操作:包括选择、交叉、变异等操作。选择操作根据个体的适应度值选取优秀的个体用于下一代,交叉操作用于产生新的个体,变异操作用于引入新的基因。 6. 设计约束条件的处理方法:针对约束条件,可以采用罚函数法或者修正算子法等方法,将违反约束条件的个体进行惩罚或修正。 7. 执行遗传算法:通过设置的参数和操作,执行遗传算法迭代优化,直到满足设定的终止条件。 8. 执行结果分析:得到最优解后,进行结果的分析和后处理,可以通过绘图等方式展示结果。 MATLAB的遗传算法工具箱提供了全面的遗传算法函数和操作,使得解决约束条件的优化问题更加简便和高效。通过良好的适应度函数设计和合理的参数设置,可以得到较好的优化结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值