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

SciPy optimize.shgo函数多参数传参触发TypeError问题求解

SciPy SHGO算法多参数目标函数传参报错解决

问题描述

调用SciPy实现的SHGO全局优化算法时,需要给目标函数传入除优化变量x之外的固定参数,运行时触发TypeError,无法定位传参逻辑错误。
对应优化问题的数学形式如下:
优化问题数学公式
可复现问题代码:

import numpy as np
import scipy.optimize as opt


def fobj(x, y, z):
    return (x+y+z).sum()

x0 = np.array([0.5, 0.5, 0.5, 0.5])
y = np.array([1, 3, 5, 7])
z = np.array([10, 20, 30, 40])
bnds = list(zip([0, 1, 2, 3], [2, 3, 4, 5]))
cons = {'type': 'eq', 'fun': lambda x: x.sum() - 14}
min_kwargs = {'method': 'SLSQP', 'options': {'maxiter': 100, 'disp': True}}
ret = opt.shgo(func=fobj, bounds=bnds, args=(y, z), constraints=cons, minimizer_kwargs=min_kwargs, options={'disp': True})

运行后抛出的核心报错:

TypeError: fobj() takes 3 positional arguments but 5 were given

完整报错追踪栈:

Splitting first generation
Traceback (most recent call last):
  File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 630, in __getitem__
    return self.cache[x]
KeyError: (0, 0, 0, 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 420, in shgo
    shc.construct_complex()
  File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 733, in construct_complex
    self.iterate()
  File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 876, in iterate
    self.iterate_complex()
  File "C:\path\lib\site-packages\scipy\optimize\_shgo.py", line 895, in iterate_hypercube
    self.HC = Complex(self.dim, self.func, self.args,
  File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 25, in __init__
    self.n_cube(dim, symmetry=symmetry)
  File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 76, in n_cube
    self.C0.add_vertex(self.V[origintuple])
  File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 634, in __getitem__
    xval = Vertex(x, bounds=self.bounds,
  File "C:\path\lib\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 557, in __init__
    self.f = func(x_a, *func_args)
  File "C:\path\lib\site-packages\scipy\optimize\_optimize.py", line 466, in function_wrapper
    fx = function(np.copy(x), *(wrapper_args + args))
TypeError: fobj() takes 3 positional arguments but 5 were given

疑惑点:代码仅通过args=(y,z)传入2个额外参数,加上优化变量x总共应该是3个参数,不清楚5个参数的来源。尝试在minimizer_kwargs中添加args=(x0)后报错无变化。
运行环境:

  • Python 3.10.5
  • Numpy 1.22.4
  • SciPy 1.8.1

错误根本原因

SHGO执行分为两个独立阶段,两个阶段都会单独调用目标函数:

  1. 全局采样构造复形阶段:SHGO内部会自动读取shgo顶层传入的args绑定到目标函数,这一步传参逻辑正常,只会传入x、y、z三个参数。
  2. 局部优化求精阶段:SHGO调用指定的SLSQP局部优化器时,SciPy 1.8.x版本不会自动把顶层的args透传给局部优化器,反而会在内部函数包装逻辑中重复拼接参数,最终传给目标函数的参数为:x(1个)+ 顶层传入的y、z(2个)+ 局部阶段错误重复传入的y、z(2个),合计5个参数,和报错信息完全吻合。

之前尝试在minimizer_kwargs中传args=(x0)完全错误:x0是优化初始点,不是目标函数的固定参数,且(x0)写法不是单元素元组(实际是numpy数组类型,单元素元组需要写为(x0,)),自然无法解决问题。

修复方法

只需要在minimizer_kwargs配置字典中,和顶层shgo调用保持一致,同步传入相同的args参数即可,修正后的可运行代码:

import numpy as np
import scipy.optimize as opt


def fobj(x, y, z):
    return (x+y+z).sum()

x0 = np.array([0.5, 0.5, 0.5, 0.5])
y = np.array([1, 3, 5, 7])
z = np.array([10, 20, 30, 40])
bnds = list(zip([0, 1, 2, 3], [2, 3, 4, 5]))
cons = {'type': 'eq', 'fun': lambda x: x.sum() - 14}
# 关键修复:局部优化器参数中同步传入目标函数额外参数
min_kwargs = {
    'method': 'SLSQP',
    'args': (y, z),
    'options': {'maxiter': 100, 'disp': True}
}
ret = opt.shgo(
    func=fobj,
    bounds=bnds,
    args=(y, z),
    constraints=cons,
    minimizer_kwargs=min_kwargs,
    options={'disp': True}
)

print(ret.x) # 输出最优解 [2. 3. 4. 5.],对应最优目标值132

补充说明:该参数透传问题是SciPy 1.8~1.9版本SHGO模块的已知实现缺陷,高版本SciPy已经修复了顶层args自动透传的逻辑,但为了兼容不同版本,无论使用哪个SciPy版本,都建议在minimizer_kwargs中同步传入args参数,避免触发同类报错。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:51:28