我想使用 pymoo 进行多目标优化并解决离散问题。为此,在 pymoo 的网页上可以看到 IntegerRandomSampling() 类: https://pymoo.org/customization/discrete.html
作为一个例子,我考虑一个测试应用程序来查找 2D 表面地图上 N 个个体的位置,其坐标由索引(整数)描述,并且我希望 pymoo 生成 N 个随机整数来表示每个“迭代”的位置。
我注意到两件事,我很乐意收到社区的意见:
有谁知道这是一个已识别的错误还是我没有正确做事?下面是一个小脚本,再现了我试图解释的内容。第 43 行左右的 print(x) 指令将显示 N 大小的随机整数数组,始终相同并变成浮点数。
非常感谢。
编辑:
import numpy as np
from pymoo.core.problem import ElementwiseProblem
from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.operators.crossover.sbx import SBX
from pymoo.operators.mutation.pm import PM
from pymoo.operators.sampling.rnd import FloatRandomSampling
from pymoo.operators.sampling.rnd import IntegerRandomSampling
class stru:
def __init__(self):
self.a = 0
class MaskProblem(ElementwiseProblem):
def __init__(self, data):
self.xg = data.xg
self.yg = data.yg
self.A = data.A
self.N = data.N
# design space
dsxl = np.zeros((self.N),dtype=int)
dsxu = np.zeros((self.N), dtype=int)
for j in range(self.N):
dsxu[j] = int(len(self.xg)*len(self.yg)-1)
super().__init__(n_var=self.N,
n_obj=self.N-1,
n_constr=0,
xl=dsxl,
xu=dsxu)
def _evaluate(self, x, out, *args, **kwargs):
#
print(x)
p = np.zeros((self.N,2),dtype=float)
for k in range(self.N):
j, i = np.unravel_index(np.abs(self.A - x[k]).argmin(), self.A.shape)
p[k,0] = self.xg[i]
p[k,1] = self.yg[j]
#
kmid = int(0.5*(self.N-1))
fobj = np.zeros((self.N-1),dtype=float)
for k in range(kmid):
fobj[k] = np.sqrt(np.square(p[k,0]-p[kmid,0])+np.square(p[k,1]-p[kmid,1]))
for k in range(kmid,self.N):
fobj[k-kmid] = np.sqrt(np.square(p[k, 0] - p[kmid, 0]) + np.square(p[k, 1] - p[kmid, 1]))
#print(f'x={x[0][0]}, i={i},j={j}, A(i,j)={data.A[j, i]}')
#
# objectives array
out["F"] = fobj
data = stru()
xmin = 0.0
xmax = 1.0
NX = 3
data.xg = np.linspace(xmin, xmax, NX)
ymin = 0.0
ymax = 1.0
NY = 5
data.yg = np.linspace(ymin, ymax, NY)
data.A = np.zeros((NY,NX),dtype=int)
for jx in range(NX):
for jy in range(NY):
data.A[jy,jx] = jy*NX + jx
print(data.A)
data.N = 3
n_population = 40
n_offsprings = 10
n_gen = 100
crossover_prob = 0.9
crossover_eta = 15
mutation = 20
problem = MaskProblem(data)
algorithm = NSGA2(
pop_size=n_population,
n_offsprings=n_offsprings,
sampling=IntegerRandomSampling(),
crossover=SBX(prob=crossover_prob, eta=crossover_eta),
mutation=PM(eta=mutation),
eliminate_duplicates=True
)
from pymoo.optimize import minimize
res = minimize(problem,algorithm,termination=('n_gen', n_gen),seed=1,save_history=True,verbose=False)
我认为问题来自于交叉或突变。我尝试了 SBX、TwoPointCrossover 和 UniformCrossover,但总是一样。但只有在第一代之后整数才变成浮点数。 对于我自己的问题,我将设计特定的交叉和变异类,但在 Pymoo 中实现可能很有趣,值得考虑。
为了将数据类型保持为整数,您可以通过
vtype
参数显式指定类型。
super().__init__(n_var=self.N,
n_obj=self.N-1,
n_constr=0,
xl=dsxl,
xu=dsxu,
vtype=int)