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

Scipy shgo优化器未遵守等式约束问题问询

SHGO优化返回结果违反等式约束的原因分析

问题重现

运行以下Scipy优化代码:

from scipy import optimize
from math import log

bounds = ((0, 1), (0, 1), (0, 1), (0, 1))

def finite_resources(x):
    return x[0] + x[2] - 1

# 注意:此处约束被定义为元组而非列表
cons = ({'type': 'eq', 'fun': finite_resources})

def global_satisfaction(x):
    return -(log(1+x[0])/(1+x[1]*10000) + log(1+x[2])/(1+x[3]*10000))

results = dict()
print(optimize.shgo(global_satisfaction, bounds, constraints=cons))

得到输出:

message: Optimization terminated successfully.
 success: True
     fun: -1.3862943611198906
    funl: [-1.386e+00]
       x: [ 1.000e+00  0.000e+00  1.000e+00  0.000e+00]
      xl: [[ 1.000e+00  0.000e+00  1.000e+00  0.000e+00]]
     nit: 1
    nfev: 18
   nlfev: 5
   nljev: 1
   nlhev: 0

返回的四元组x = [1.0, 0.0, 1.0, 0.0]明显违反等式约束x[0] + x[2] - 1 = 0。

原因分析

核心问题在于约束参数的格式错误:

  • Scipy优化函数(包括shgo)的constraints参数要求传入约束字典的序列(通常是列表),而你此处将单个约束字典用圆括号()包裹,创建了一个元组而非列表。
  • 虽然元组属于序列类型,但Scipy的shgo内部对约束的处理逻辑未正确识别元组形式的约束,导致约束完全未被应用——相当于在无约束条件下运行优化,此时目标函数的最大值自然出现在x[0]=1、x[2]=1(这两个变量的取值能最大化log(1+x)项),同时x[1]=0、x[3]=0消除分母的惩罚。

解决方案

将约束定义改为列表形式即可:

# 修正为列表格式的约束
cons = [{'type': 'eq', 'fun': finite_resources}]

修正后重新运行,优化结果会严格遵守等式约束,返回符合要求的最优解。

是否需要提交Issue?

不需要。这并非Scipy的bug,而是代码中约束参数的格式使用错误。只要按照官方文档要求传入列表形式的约束,问题即可解决。

内容的提问来源于stack exchange,提问作者user10165777

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:22:42