You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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)仅支持无约束或仅含边界约束的多目标问题——不管你的约束是线性还是非线性,只要是额外的等式/不等式约束,它都会判定为“非线性约束”并拒绝处理,这是该算法实现的固有限制,和约束本身的线性无关。

解决方案

有两个可行方向:

  1. 换用支持约束的多目标优化算法
    PyGMO中支持带约束多目标问题的算法包括:

    • pg.moead(MOEA/D算法)
    • pg.nsga3(NSGA-III算法)
    • pg.sms_emoa(SMS-EMOA算法)
      比如把算法替换为MOEA/D:
    algorithm = pg.algorithm(pg.moead(gen=1000))
    
  2. 将线性约束转化为决策变量边界(如果可行)
    如果你的线性约束可以通过调整决策变量的上下界来等效实现,那可以直接修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 09:25:23