基于分解的MOEA:MOEA/D
简单描述
- 将一个多目标问题分解为多个标量子问题来同时进行求解。
在MOEAD之前解决MOP问题思想是给每一个目标分配一个权重表示其重要程度,通过这种加权使多目标问题转为一个单目标优化问题。这样导致每次运行都只能得到一个解,显然对于多目标优化问题不可能只存在一个解同时满足所有目标最优,因此利用一组不同权向量将该MOP分解为一组单目标优化问题来同时求解。这样每个单目标问题求得解分别对应PF上不同的点,也是该多目标优化问题的一组最优解。
为了种群更快的收敛,给每一个个体分配一个权向量。同时,使用一种邻近权向量的替换策略,即每个个体(权向量)和邻近的几个个体(权向量)才会比较进行优化。
进一步研究
- 权向量的生成
使用Das等人提出的systematic approach来产生一组均匀权向量{ λ1 ,λ2 … λn}。n为权向量数量 = 种群大小。 n = C H + m − 1 m − 1 n = C_{H+m-1}^{m-1} n=CH+m−1m−1 m目标个数,H多目标中每一维的坐标轴的间隔数量,且称 δ \delta δ=1/H 为均匀间隔值。
- m > 5时,且H>m,n会异常大,注意:如果H<m产生的点都在超平面的边界上,H = m时,只会在超平面的中心( 1 m {{1} \over{m}} m1, 1 m {{1} \over{m}} m1,… 1 m {{1} \over{m}} m1, 1 m {{1} \over{m}} m1) T ^T T有一点。
- m >5时,基本的systematic approach不能满足需求,文献【Ke Li, Kalyanmoy Deb, Qingfu Zhang, et al. An Evolutionary Many-Objective Optimization Algorithm Based on Dominance and Decomposition. IEEE Transactions on Evolutionary Computation, 2015, 19(5):694–716】提出一种two-layer生成策略。
具体来说,就是在两个m维超平面的边界产生权重向量,当然,这两个的H 是不一样的,然后将其中一个产生的向量映射到另一个超平面中。假设w = (w 1 _1 1,w 2 _2 2,…w m _m m) T ^T T是待映射的一个向量 w i = 1 − τ m + τ × w i w_i = {{1-\tau}\over{m}} + \tau \times w_i wi=m1−τ+τ×wi其中 i ∈ \in ∈{1,2…m} , τ \tau τ属于收缩因子,一般取0.5。最后将映射后的权重向量和没有映射的那些边界向量合并。
图2.7 Two-Layer,不需要映射的权重向量产生的H = 2,需要映射的那组权重向量的H = 1。
import numpy as np
class Mean_vector:
# 对m维空间,目标方向个数H
def __init__(self, H=5, m=3, path='out.csv'):
self.H = H
self.m = m
self.path = path
self.stepsize = 1 / H
def perm(self, sequence):
# !!! 序列全排列,且无重复
l = sequence
if (len(l) <= 1):
return [l]
r = []
for i in range(len(l)):
if i != 0 and sequence[i - 1] == sequence[i]:
continue
else:
s = l[:i] + l[i + 1:] # 剔除第 i 个元素
p = self.perm(s)
for x in p:
r.append(l[i:i + 1] + x)
# print(r)
return r
def get_mean_vectors(self):
H = self.H
m = self.m
sequence = []
for ii in range(H):
sequence.append(0)
for jj in range(m - 1):
sequence.append(1)
ws = []
# print(sequence) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]
pe_seq = self.perm(sequence)
for sq in pe_seq:
s = -1
weight = []
for i in range(len(sq)):
if sq[i] == 1:
w = i - s
w = (w - 1) / H
s = i
weight.append(w)
nw = H + m - 1 - s
nw = (nw - 1) / H
weight.append(nw)
if weight not in ws:
ws.append(weight)
return ws
def save_mv_to_file(self, mv):
f = np.array(mv, dtype=np.float64)
np.savetxt(fname=self.path, X=f)
def generate(self):
m_v = self.get_mean_vectors()
self.save_mv_to_file(m_v)
mv = Mean_vector(10, 2, 'ZDT1.csv')
mv.generate()
参考文章
【1】均匀权重向量集合的生成
【2】MOEAD算法中均匀权向量的实现—Python
【3】一种基于支配和分解的多目标优化进化算法学习笔记
- 聚合方法
- 生成下一代的解
- 评价指标
- 可视化