## NSGA-NET中的micro内部细节搜索

### 交叉和变异

def nsganet(
pop_size=100,
sampling=RandomSampling(var_type=np.int),
selection=TournamentSelection(func_comp=binary_tournament),
crossover=PointCrossover(n_points=2),  # 一种crossover的方式，双点crossover
mutation=PolynomialMutation(eta=3, var_type=np.int),  # 一种mutation的方式
eliminate_duplicates=True,
n_offsprings=None,
**kwargs):


#### 交叉

pointcrossover函数如下

class PointCrossover(Crossover):

def __init__(self, n_points):  # 作者在这里设置的是两点交叉
super().__init__(2, 2)
self.n_points = n_points

def _do(self, problem, pop, parents, **kwargs):

# get the X of parents and count the matings
X = pop.get("X")[parents.T]  # X为选取的两个parents
_, n_matings, n_var = X.shape  # n mating 为1，获取基因的长度

# start point of crossover
r = np.row_stack([random.perm(n_var-1) + 1 for _ in range(n_matings)])[:, :self.n_points]  # 选取index
r.sort(axis=1)
r = np.column_stack([r, np.full(n_matings, n_var)])

# the mask do to the crossover
M = np.full((n_matings, n_var), False)

# create for each individual the crossover range
for i in range(n_matings):

j = 0
while j < r.shape[1] - 1:
a, b = r[i, j], r[i, j + 1]
M[i, a:b] = True  # 选取一个片段，进行交换
j += 2

return pop.new("X", _X)


#### 变异

$v_k' = v_k +\delta\times(u_k-l_k)$

\delta=\left\{ \begin{aligned} &[2\times u+(1-2\times u)(1-\delta_1)^{\eta_m+1}]^{\frac{1}{\eta_m+1}}-1 && if \ u\leq0.5\\ &1-[2\times(1-u)+2\times(u-0.5)(1-\delta_2)^{\eta_m+1}]^{\frac{1}{\eta_m+1}} && if\ u>0.5 \end{aligned} \right.

    def _do(self, problem, pop, **kwargs):
pdb.set_trace()
X = pop.get("X").astype(np.double)  # 选取两个样本，而不是一个
Y = np.full(X.shape, np.inf)

if self.prob is None:
self.prob = 1.0 / problem.n_var  # 1/40.

do_mutation = random.random(X.shape) < self.prob  # 长度越大，做mutation的概率越小，平均是选取一位来做mutation

Y[:, :] = X
# 以下，根据选取的基因位，选择其上下boundary
xl = np.repeat(problem.xl[None, :], X.shape[0], axis=0)[do_mutation]
xu = np.repeat(problem.xu[None, :], X.shape[0], axis=0)[do_mutation]

if self.var_type == np.int:  # true
xl -= 0.5  # 下界由0减少0.5,
xu += (0.5 - 1e-16)  # 上界+0.5

X = X[do_mutation]  # 选取需要变异的基因位

delta1 = (X - xl) / (xu - xl)  # 计算delta1
delta2 = (xu - X) / (xu - xl)  # 计算delta2

mut_pow = 1.0 / (self.eta + 1.0)

rand = random.random(X.shape)
mask = rand <= 0.5

deltaq = np.zeros(X.shape)
# 计算如下的value，并且将结果赋给delta
xy = 1.0 - delta1
val = 2.0 * rand + (1.0 - 2.0 * rand) * (np.power(xy, (self.eta + 1.0)))
d = np.power(val, mut_pow) - 1.0

xy = 1.0 - delta2
val = 2.0 * (1.0 - rand) + 2.0 * (rand - 0.5) * (np.power(xy, (self.eta + 1.0)))
d = 1.0 - (np.power(val, mut_pow))

# mutated values
_Y = X + deltaq * (xu - xl)  # 得到的结果为浮点数

# back in bounds if necessary (floating point issues)
_Y[_Y < xl] = xl[_Y < xl]
_Y[_Y > xu] = xu[_Y > xu]

# set the values for output
Y[do_mutation] = _Y  # 将变异得到的结果赋给下一代

if self.var_type == np.int:
Y = np.rint(Y).astype(np.int)

off = OutOfBoundsRepair().do(problem, pop.new("X", Y))
return off


posted on 2021-05-26 14:12  YongjieShi  阅读(229)  评论(2编辑  收藏  举报