MOEA/D 算法

基于分解的多目标进化算法(MOEA/D)2007年提出[1]。MOEA/D算法是一种基于分解的多目标优化算法,它将一个多目标优化问题分解成若干个标量优化子问题,并同时对其进行优化。于分解操作的存在,该方法在保持解的分布性方面有着很大优势,而通过分析相邻问题的信息来优化,能避免陷入局部最优。

[1]这篇论文把分解的思想用到了进化计算中,之前这些方法大都用在传统解决优化问题的方法上

将PF的近似问题转化为标量优化问题的方法

  • 权重和方法
  • 切比雪夫方法
  • 边界交叉法

辅助理解这个算法的

  • https://www.docin.com/p-1627227465.html [感觉翻译了论文的绝大部分]
  • https://blog.csdn.net/sinat_33231573/article/details/80271801
  • https://blog.csdn.net/qq_35414569/article/details/79655400 [对这三种方法的解释比较好]

MOEA/D算法流程

输入:

  • 多目标优化的目标函数
  • 算法终止条件(迭代次数)
  • N定义的种群大小
  • 均匀分布的N个权重向量
  • T:每个临域中权重向量的个数

算法流程

  1. 初始化
    1.1 N个均匀分布的权重向量: λ1,…λN,i=1,…,N\lambda_1,\dots \lambda_N, i=1,\dots,Nλ1​,…λN​,i=1,…,N,并计算每个权重向量最近的T个权重向量B(i)
    1.2. 在可行空间中均匀采样初始化的种群
    1.3. 初始化z(每个目标函数的最优值,根据需要最大化还是最小化进行初始化)
    1.4. 设置外部种群EP为空
  2. 当小于迭代次数的时候
    2.1. 从B(i)中随机选取两个序号k,l,由xk和xlx^k 和x^lxk和xl产生一个新的解y
    2.2 对产生的解进行修复改正
    2.3 更新z:若zj&lt;fj(y)z_j&lt;f_j(y)zj​<fj​(y),则zj=fj(y),j=1,…,nObjz_j=f_j(y), j=1,\dots,nObjzj​=fj​(y),j=1,…,nObj
    2.4 更新邻域解:若gts(y∣λj,z)≤gts(xj∣λj,z),j∈B(i)g^ts(y|\lambda^j,z)\leq g^ts(x^j|\lambda^j,z),j\in B(i)gts(y∣λj,z)≤gts(xj∣λj,z),j∈B(i),更新xj=yFVj=F(y)x^j=y FV^j=F(y)xj=yFVj=F(y)
    2.5 更新EP:移除所有被F(y)支配的向量,若F(y)不被EP里面的支配,把y加入EP
  3. 若满足终止条件,输出EP,否则转2

在论文里面和源代码中应该是实现了前两种方式,用的是DE(差分进化算法)。我这里只实现了切比雪夫方法,以及遗传算法。代码主要参考了论文给出的源代码,yarpiz以及博客

在实现的过程中也确实如博客一样遇到了如下的问题:

  1. 如何产生均匀的权重向量
  2. 如何产生下一代y

试了一下生成均匀分布向量确实是均匀的但当维度变大之后速度真的超级慢,而且种群的数目不能按照自己的意愿调整。MOEA/D论文所给的代码,二维的权重向量是均匀的,但三维的肯定不是在空间中均匀分布的啊!按照[2]的说法标准Tchebycheff Approach得到的解不均匀,就提出了一种自适应权重调整的方法。在[3]这篇综述里提到可以均匀随机抽样产生初始化的权重向量。
在ZDT1,ZDT2,ZDT3上面确实没有太大分别,我就随机了。


速度比MOPSO要快,但效果感觉没有MOPSO好(种群大小为100,迭代200代,外部存档200)

iteration=200 #迭代次数
population=100
archive=200 #存档数目
nObj=2
theta=0.1 #变异的概率
nVar=30 #决策变量个数
varMax=np.ones(nVar)
varMin=np.zeros(nVar)
yita1=2 #交叉参数
yita2=5 #变异参数
'''下面不是参数!'''
Lambda=[] #权重向量
pops=[]
EPs=[]
class pop():def __init__(self,var,cost):self.var=varself.cost=costself.dominate=False
def isDominates(x,y):#x是否支配yreturn (x<=y).all() and (x<y).any()
def determinDomination(p):for i in range(len(p)):p[i].dominate=Falsefor i in range(0,len(pops)-1):for j in range(i+1,len(p)):if isDominates(p[i].cost,p[j].cost):p[j].dominate=True#j被i支配if isDominates(p[j].cost,p[i].cost):p[i].dominate=True

产生权重向量和邻居

T=max(math.ceil(0.15*population),2)
T=min(T,15)#邻居的数目
def genVector2(nObj,npop,T):Lambda=[]dist=np.zeros((npop,npop))for i in range(npop):w=np.random.rand(nObj)w=w/np.linalg.norm(w)
#         w=w/sum(w)Lambda.append(w)for i in range(npop-1):for j in range(i+1,npop):dist[i][j]=dist[j][i]=np.linalg.norm(Lambda[i] - Lambda[j])sp_neighbors=np.argsort(dist,axis=1)sp_neighbors=sp_neighbors[:,:T]return Lambda, sp_neighbors
Lambda,sp_neighbors=genVector2(nObj,population,T)

初始化种群,全局最优z和外部存档

def initPop(npop,nVar,varMin,varMax,fitness):global popspops=[]for i in range(npop):var=varMin+np.random.random(nVar)*(varMax-varMin)cost=fitness(var)pops.append(pop(var,cost))
initPop(population,nVar,varMin,varMax,ZDT2)z=pops[0].cost
for p in range(population):for j in range(nObj):z[j]=min(pops[p].cost[j],z[j])
z=np.array(z)
determinDomination(pops)
EPs=copy.deepcopy([x for x in pops if x.dominate!=True])

产生下一代,采用模拟二进制交叉和多项式变异,参考了https://blog.csdn.net/qq_40434430/article/details/82876572

def cross_mutation2(p1,p2):gamma=0.1 #这个方式的效果很差alpha=-gamma+np.random.random(nVar)*(1+2*gamma)y=alpha*p1+(1-alpha)*p2 return y
def cross_mutation(p1,p2):#交叉变异,不拷贝的话原始数据也变了y1=np.copy(p1)y2=np.copy(p2)y1,y2=crossover(y1,y2)if np.random.rand()<theta:mutate(y1)if np.random.rand()<theta:mutate(y2)return y1,y2
def crossover(p1,p2):nVar=len(p1)gamma= 0for i in range(nVar):uj = np.random.rand()if uj <= 0.5:gamma = (2 * uj) ** (1 / (yita1+1))else:gamma = (1 / (2 * (1 - uj))) ** (1 / (yita1+1))p1[i]=0.5*((1+gamma)*p1[i]+(1-gamma)*p2[i])p2[i]=0.5*((1-gamma)*p1[i]+(1+gamma)*p2[i])p1[i]=min(p1[i],varMax[i])p1[i]=max(p1[i],varMin[i])p2[i]=min(p2[i],varMax[i])p2[i]=max(p2[i],varMin[i])return p1,p2def mutate(p):#用的是多项式变异,对每个决策变量进行变异dj = 0for i in range(len(p)):uj = np.random.rand()if uj < 0.5:dj = (2 * uj) ** (1 / (yita2+1)) - 1else:dj = 1 - (2 * (1 - uj)) ** (1 /(yita2+1))p[i] = p[i] + djp[i]=min(p[i],varMax[i])p[i]=max(p[i],varMin[i])
def generate_next(idx,xk,xl,fitness):y0,y1=cross_mutation(xk,xl)
#     y0=cross_mutation2(xk,xl)#对y进行修复根据约束for i in range(nVar):y0[i]=max(varMin[i],y0[i])y0[i]=min(varMax[i],y0[i])
#     return y0y1[i]=max(varMin[i],y1[i])y1[i]=min(varMax[i],y1[i])fx1=np.array(fitness(y0))fx2=np.array(fitness(y1))if isDominates(fx1,fx2):return y0elif isDominates(fx2,fx1):return y1else:if np.random.rand()<0.5:return y0else:return y1

更新邻域解

def update_neighbor(idx,y):#若gy<gx更新,用的权重是邻居的权重Bi=sp_neighbors[idx] fy=y.costfor j in range(len(Bi)):w=Lambda[Bi[j]]maxn_y=max(w*abs(fy-z))maxn_x=max(w*abs(pops[Bi[j]].cost-z))if maxn_x>=maxn_y:pops[Bi[j]]=y

主循环

start=time.time()
for j in range(iteration):if j%10==0:print("="*10,j,"="*10)print(z,len(EPs))for i in range(population):Bi=sp_neighbors[i] choice=np.random.choice(T,2,replace=False) #选出来的邻居应该不重复k=Bi[choice[0]]l=Bi[choice[1]]xk=pops[k]xl=pops[l]#产生新的解,并对解进行修复y=generate_next(i,xk.var,xl.var,ZDT3)fv_y=np.array(ZDT3(y))y=pop(y,fv_y)#更新z,t=z>fv_yz[t]=fv_y[t]#更新邻域解update_neighbor(i,y)ep=Falsedelete=[]for k in range(len(EPs)):if (fv_y==EPs[k].cost).all():#如果有一样的就不用算了啊ep=Truebreakif isDominates(fv_y,EPs[k].cost):delete.append(EPs[k])elif ep==False and isDominates(EPs[k].cost,fv_y):ep=Truebreak #后面就不用看了,最好也是互不支配if len(delete)!=0:for k in range(len(delete)):EPs.remove(delete[k])if ep==False:EPs.append(y)while len(EPs)>archive:select=np.random.randint(0,len(EPs))del EPs[select]
#         if len(EPs)>archive:
#             delete=np.random.choice(EPs,len(EPs)-archive)
#             for k in range(len(delete)):
#                 EPs.remove(delete[k])
end=time.time()
print("循环时间:%2f秒"%(end-start))

参考文献
[1] Zhang Q , Li H . MOEA/D: A Multiobjective Evolutionary Algorithm Based on Decomposition[J]. IEEE Transactions on Evolutionary Computation, 2008, 11(6):712-731.
[2] Qi Y , Ma X , Liu F , et al. MOEA/D with Adaptive Weight Adjustment[J]. Evolutionary Computation, 2014, 22(2):231-264.
[3] Trivedi A, Srinivasan D, Sanyal K, et al. A Survey of Multiobjective Evolutionary Algorithms Based on Decomposition[J]. IEEE Transactions on Evolutionary Computation, 2017, 21(3):440-462.

枯了,我真的是代码能力太差了。之前不想用class就一直全是问题,更新numpy中一行更新不动,各种引用的问题
过了这个月好好改下代码,别的测试函数也试一下。最近事情有点多

MOEA/D原理及pyton实现相关推荐

  1. python解释器的工作原理_Python GIL全局解释器锁详解(深度剖析)

    通过前面的学习,我们了解了 Pyton 并发编程的特性以及什么是多线程编程.其实除此之外,Python 多线程还有一个很重要的知识点,就是本节要讲的 GIL. GIL,中文译为全局解释器锁.在讲解 G ...

  2. Python 玩转数据 5 - 图解 Python 赋值,浅拷贝 copy.copy() 和 深拷贝 copy.deepcopy() 原理

    引言 上面文章有介绍 Python 动态类型 共享引用等相关知识,有这个基础,我们来深入研究一下 Python 赋值,拷贝的原理,有涉及到可变类型和不可变类型的不同处理.更多 Pyton 进阶系列文章 ...

  3. UUID的使用及其原理

    今天敲项目要用UUID,想起之前老师告诉UUID的使用,但没说具体的生成逻辑,于是我进行了百度 首先,UUID的使用: //生成随机的UUID String uuid = UUID.randomUUI ...

  4. etcd 笔记(01)— etcd 简介、特点、应用场景、常用术语、分布式 CAP 理论、分布式原理

    1. etcd 简介 etcd 官网定义: A highly-available key value store for shared configuration and service discov ...

  5. git原理及常见使用方法

    Git 原理入门-来自阮一峰 Git 是最流行的版本管理工具,也是程序员的必备技能之一. 即使天天使用它,很多人也未必了解它的原理.Git 为什么可以管理版本?git add.git commit这些 ...

  6. 微机原理—定时计数控制接口

    别看题目很高深,其实就是很简单的定时器和计数器而已. 通常用手机定个闹钟,就是定时器的使用. 工厂里通过传送带上安装传感器,传感器传输给计算机的信号用来计数. 这是一些很简单的应用,通过很小的一个芯片 ...

  7. 三层交换机原理:01路由器如何隔离广播域?

    前言: 当网络规模较大的时候,需要设备来隔离广播域,防止网络中因产生广播风暴而导致网络效率降低,而二层交换机不能隔离广播域,所以需要三层路由器设备来隔离广播域! 但三层路由器为什么能够隔离广播域,是如 ...

  8. CRF(条件随机场)与Viterbi(维特比)算法原理详解

    摘自:https://mp.weixin.qq.com/s/GXbFxlExDtjtQe-OPwfokA https://www.cnblogs.com/zhibei/p/9391014.html C ...

  9. BiLSTM-CRF学习笔记(原理和理解) 维特比

    https://www.zhihu.com/question/20136144 维特比详解 BiLSTM-CRF 被提出用于NER或者词性标注,效果比单纯的CRF或者lstm或者bilstm效果都要好 ...

  10. 【Learning Notes】线性链条件随机场(CRF)原理及实现

    1. 概述 条件随机场(Conditional Random Field, CRF)是概率图模型(Probabilistic Graphical Model)与区分性分类( Discriminativ ...

最新文章

  1. Facebook收购GrokStyle:布局AI零售
  2. uhttpd 架构调用细节之lua
  3. K - FatMouse and Cheese
  4. CSS垂直翻转/水平翻转提高web页面资源重用性
  5. 打包跳过编译_Apache Flink v1.9-SNAPSHOT 源码编译
  6. 【Discuz!】去掉版面的右侧的“收藏本版”和“订阅”
  7. Vim 安装 YouCompleteMe
  8. pytorch:一维线性回归(一)
  9. 计算机主板各模块复位,电脑主板复位电路工作原理分析
  10. 付完版面费就该吃土了
  11. phpcmsV9 的 PHPSSO 配置
  12. 音频放大电路_集成电路技术汇总:检测技巧
  13. Linux svn服务器搭建
  14. mysql 速度评测_[评测]低配环境下,PostgresQL和Mysql读写性能简单对比(欢迎大家提出Mysql优化意见)...
  15. 阿里全国脱贫攻坚先进-万祥军:谋定中国农民丰收节交易会
  16. ChemDraw19激活中文版下载化学绘图软件教程
  17. 秦储承办 | 西部数博会暨第三届西安区块链产业发展论坛成功召开!
  18. 激活windows系列地址
  19. 华为智慧屏 SE55
  20. 异常检测方法-MAD

热门文章

  1. PHP运行的环境安装
  2. SREng扫描报告分析
  3. centos7服务器如何通过trunk模式接入交换机
  4. windows64位PowerDesigner下载
  5. java生成word文档 图片_java根据模板生成word文档,兼容富文本、图片
  6. 诺基亚安卓手机_宁可不做手机?也不用安卓系统!诺基亚:真香啊
  7. php根据两点经纬度计算距离
  8. 定点运算之补码一位乘法(Booth算法)
  9. flv文件修复工具——FLVMDI的使用方法
  10. UE4 讯飞语音识别插件