使用pymoo的IntegerRandomSampling时遇两问题求助
问题解答
1. 随机序列重复问题
你已明确原因是设置了固定seed=1,解决方法:
- 移除
minimize函数中的seed=1参数,每次运行会自动使用随机种子 - 或每次运行传入不同随机种子值,比如
seed=np.random.randint(0, 1000)
2. 整数解变为浮点数的问题
这是因为你使用的SBX交叉算子和PM变异算子是针对连续浮点变量设计的,运算逻辑会产生浮点数结果——即使初始采样是整数,经过交叉变异后也会被转换成浮点数。
pymoo针对整数离散问题提供了专门的算子,需替换为IntegerSBX和IntegerPM,这两个算子会确保运算结果始终是整数。
修改后的完整代码
import numpy as np from pymoo.core.problem import ElementwiseProblem from pymoo.algorithms.moo.nsga2 import NSGA2 # 替换为整数版本的交叉和变异算子 from pymoo.operators.crossover.int_sbx import IntegerSBX from pymoo.operators.mutation.int_pm import IntegerPM 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])) 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=IntegerSBX(prob=crossover_prob, eta=crossover_eta), mutation=IntegerPM(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)
关键修改点
- 导入
IntegerSBX和IntegerPM替换原有的SBX和PM - 在算法初始化中使用这两个整数算子
修改后,整个优化过程生成的解都会保持整数类型,不会出现浮点数转换问题。
内容的提问来源于stack exchange,提问作者RSer
相关产品推荐
相关产品推荐

