使用Pygmo求解带约束多目标优化时遇线性约束误判报错
使用PyGMO求解带约束多目标优化问题时的线性约束报错问题
问题描述
使用pygmo==2.19.5求解带线性约束的多目标优化问题,想获取帕累托前沿,但程序抛出错误:
what: Non linear constraints detected in <class 'main.SimpleProblem'> instance. NSGA-II: cannot deal with them.
移除约束后程序可正常运行,已按照PyGMO文档中「Coding a User Defined Problem with constraints」示例编写fitness函数(返回目标函数值+约束值的向量),但文档无含额外约束的多目标示例,疑惑是否需要调整fitness函数的处理方式。
复现代码
import pygmo as pg class SimpleProblem: # objective functions and constraints def fitness(self, x): fitness_vector = [] # first objective fitness_vector.append(x[0]) constants = [1,0.5,0.5] # second objective fitness_vector.append(-sum([x[i] * constants[i] for i in range(3)])) # constraint fitness_vector.append(sum([x[i] for i in range(3)]) -2) return fitness_vector # number of objectives def get_nobj(self): return 2 # number of inequality constraints def get_nic(self): return 1 # real dimension of the problem def get_ncx(self): return 1 # integer dimension of the problem def get_nix(self): return 3 # bounds of the decision variables def get_bounds(self): return ([0] + [0] * 3, [1e6] + [1] * 3) if __name__ == "__main__": model = SimpleProblem() problem = pg.problem(model) algorithm = pg.algorithm(pg.nsga2(gen=1000)) population = pg.population(problem, size=100) population = algorithm.evolve(population)
问题原因与解决方案
核心原因
PyGMO的NSGA-II算法(pg.nsga2)仅支持无约束或仅含边界约束的多目标问题——不管你的约束是线性还是非线性,只要是额外的等式/不等式约束,它都会判定为“非线性约束”并拒绝处理,这是该算法实现的固有限制,和约束本身的线性无关。
解决方案
有两个可行方向:
换用支持约束的多目标优化算法
PyGMO中支持带约束多目标问题的算法包括:pg.moead(MOEA/D算法)pg.nsga3(NSGA-III算法)pg.sms_emoa(SMS-EMOA算法)
比如把算法替换为MOEA/D:
algorithm = pg.algorithm(pg.moead(gen=1000))将线性约束转化为决策变量边界(如果可行)
如果你的线性约束可以通过调整决策变量的上下界来等效实现,那可以直接修改get_bounds方法,去掉额外约束。但你的约束是x0+x1+x2 ≤2,且x0范围是[0,1e6],x1、x2是[0,1],这种情况无法完全通过边界等效,所以更适合换算法。
额外注意点
- 你的
fitness函数写法是正确的:返回向量前nobj个是目标函数值,后面nic个是不等式约束值(PyGMO默认要求约束值≤0时满足约束,你的约束sum(x)-2 ≤0符合要求)。 - 确认
get_ncx和get_nix的返回值:你的问题中决策变量是1个实数+3个整数,总维度是4,get_bounds返回的上下界长度是4,这部分是正确的。
内容的提问来源于stack exchange,提问作者wittn
相关产品推荐
相关产品推荐

