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

SciPy Optimize使用NonlinearConstraint时Hessian报缺少参数v问题咨询

报错原因分析

直接报错的核心原因是混淆了目标函数的Hessian和非线性约束的Hessian的定义与传入位置:

  • 你定义的cons_H是给非线性约束使用的Hessian,要求接收拉格朗日乘子参数v,这部分你已经正确传给了NonlinearConstraint的hess参数,逻辑无误。
  • 但你错误将cons_H同时传给了optimize.minimize的hess参数,该位置要求传入的是目标函数自身的Hessian函数,仅需接收输入变量x作为唯一参数,调用时不会传入v,因此触发参数缺失的报错。

除此之外代码还存在3个配套错误,不修正依然无法正常运行:

  • 维度不匹配:你定义的变量上下界bounds是3个变量的约束,但初始值x0只有2个元素,和变量维度不匹配。
  • 目标函数梯度传入错误:你把约束的雅可比cons_J传给了minimize的jac参数,目标函数的梯度和约束的雅可比是完全独立的计算逻辑,不可混用。
  • 约束Hessian返回格式错误:你定义的cons_H返回的是一维数组,而Hessian要求返回n×n的二维矩阵(n为变量维度)。
解决方法

按以下步骤修改代码即可正常运行:

  1. 单独定义目标函数的梯度(jac)和Hessian,不要和约束的对应计算函数混用
  2. 修正约束的Hessian返回符合要求的二维矩阵
  3. 调整初始值x0为3维,和变量维度匹配
  4. 调用minimize时,传入目标函数专属的梯度和Hessian

修改后的可运行代码如下:

import numpy as np
from scipy import optimize
from scipy.optimize import NonlinearConstraint

# 目标函数定义
def fun(x):
    return x[0]**2 + x[1]**2 - 8*x[1] + 16

# 目标函数梯度
def fun_jac(x):
    return np.array([2*x[0], 2*x[1] - 8, 0.0])

# 目标函数Hessian
def fun_hess(x):
    return np.array([
        [2.0, 0.0, 0.0],
        [0.0, 2.0, 0.0],
        [0.0, 0.0, 0.0]
    ])

bounds = optimize.Bounds([0,0,0],[np.inf,np.inf,np.inf])

# 约束相关定义
def cons_f(x):
    return x[0]**2 + x[1]**2 + x[2]
def cons_J(x):
    return [2*x[0], 2*x[1], 1]
def cons_H(x,v):
    # 返回3x3的约束Hessian矩阵
    return v[0] * np.array([
        [2.0, 0.0, 0.0],
        [0.0, 2.0, 0.0],
        [0.0, 0.0, 0.0]
    ])
nonlinear_constraint = optimize.NonlinearConstraint(cons_f, -np.inf, 6, jac=cons_J, hess=cons_H)

# 修正初始值为3维
x0 = [1, 1, 1]
res = optimize.minimize(fun, x0, method='trust-constr', jac=fun_jac, hess=fun_hess,
               constraints=[nonlinear_constraint],
               options={'verbose': 1}, bounds=bounds)
print("最优解:", res.x)

运行后可以得到符合约束的最优解,无报错。

内容的提问来源于stack exchange,提问作者Félix Fombellida

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:57:03