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

Scipy trust-constr求解约束优化报布尔索引维度不匹配错误

scipy.optimize.trust-constr 索引报错排查

问题复现代码

当前编写的约束优化求解代码如下:

from scipy import optimize as opt
import numpy as np


def f(x):
    return (x[0]-5)**2 + (x[1]-6)**2

# 边界与线性约束
bounds = opt.Bounds([0,0],[np.inf, np.inf])
lin_const = opt.LinearConstraint([[1,2],[0,0]], [-np.inf, 0], [4,0])

# 非线性约束、对应雅可比与海塞矩阵
def cons_f(x):
    return [x[0]**2 - 4, np.exp(-x[0]) - 1]

def cons_J(x):
    return [[2*x[0], 0], [-np.exp(-x[0])]]

def cons_H(x, v):
    return v[0]*np.array([[2,0], [0,0]]) + v[1]*np.array([[np.exp(-x[0]), 0], [0,0]])

nonlin_const = opt.NonlinearConstraint(cons_f, -np.inf, 1, jac=cons_J, hess=cons_H)

# 求解
x0 = np.array([0.50, 0.75])
res = opt.minimize(f, x0, method='trust-constr',jac="2-point", hess=opt.SR1(), bounds=bounds, constraints=[lin_const, nonlin_const], options={'verbose': 1})
print(res.x)

运行后触发numpy索引报错:
boolean index did not match indexed array along dimension 0; dimension is 1 but corresponding boolean dimension is 2
完整报错栈如下:

IndexError                                Traceback (most recent call last)
Input In [32], in <cell line: 2>()
      1 x0 = np.array([0.50, 0.75])
----> 2 res = opt.minimize(f, x0, method='trust-constr',jac=cons_J, hess=opt.SR1(), bounds=bounds, constraints=[lin_const, nonlin_const], options={'verbose': 1})
      3 print(res.x)

File ~\anaconda3\envs\choquetclassifier\lib\site-packages\scipy\optimize\_minimize.py:634, in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    631     return _minimize_slsqp(fun, x0, args, jac, bounds,
    632                            constraints, callback=callback, **options)
    633 elif meth == 'trust-constr':
---> 634     return _minimize_trustregion_constr(fun, x0, args, jac, hess, hessp,
    635                                         bounds, constraints,
    636                                         callback=callback, **options)
    637 elif meth == 'dogleg':
    638     return _minimize_dogleg(fun, x0, args, jac, hess,
    639                             callback=callback, **options)

File ~\anaconda3\envs\choquetclassifier\lib\site-packages\scipy\optimize\_trustregion_constr\minimize_trustregion_constr.py:361, in _minimize_trustregion_constr(fun, x0, args, grad, hess, hessp, bounds, constraints, xtol, gtol, barrier_tol, sparse_jacobian, callback, maxiter, verbose, finite_diff_rel_step, initial_constr_penalty, initial_tr_radius, initial_barrier_parameter, initial_barrier_tolerance, factorization_method, disp)
    357     prepared_constraints.append(PreparedConstraint(bounds, x0,
    358                                                    sparse_jacobian))
    360 # 拼接初始约束为标准形式
---> 361 c_eq0, c_ineq0, J_eq0, J_ineq0 = initial_constraints_as_canonical(
    362     n_vars, prepared_constraints, sparse_jacobian)
    364 # 准备所有标准约束并拼接
    365 canonical_all = [CanonicalConstraint.from_PreparedConstraint(c)
    366                  for c in prepared_constraints]

File ~\anaconda3\envs\choquetclassifier\lib\site-packages\scipy\optimize\_trustregion_constr\canonical_constraint.py:352, in initial_constraints_as_canonical(n, prepared_constraints, sparse_jacobian)
    350     finite_ub = ub < np.inf
    351     c_ineq.append(f[finite_ub] - ub[finite_ub])
---> 352     J_ineq.append(J[finite_ub])
    353 elif np.all(ub == np.inf):
    354     finite_lb = lb > -np.inf

IndexError: boolean index did not match indexed array along dimension 0; dimension is 1 but corresponding boolean dimension is 2

报错根因

核心问题是非线性约束的雅可比矩阵返回维度不符合要求:

  • 代码定义了2个优化变量、2个非线性约束,雅可比矩阵必须为(2,2)形状的二维数组,每一行对应一个约束对两个变量的偏导
  • 编写的cons_J第二行仅返回了[-np.exp(-x[0])](长度为1),遗漏了第二个约束np.exp(-x[0]) -1对x[1]的偏导值0,导致雅可比矩阵维度不匹配,触发后续布尔索引错误
  • 额外冗余问题:线性约束中[0,0]对应的约束0*x0 +0*x1 =0是恒成立的无效约束,不会触发报错但会增加计算开销

修正后代码

from scipy import optimize as opt
import numpy as np


def f(x):
    return (x[0]-5)**2 + (x[1]-6)**2

# 边界与线性约束,移除冗余的全零约束
bounds = opt.Bounds([0,0],[np.inf, np.inf])
lin_const = opt.LinearConstraint([[1,2]], [-np.inf], [4])

# 非线性约束、对应雅可比与海塞矩阵
def cons_f(x):
    return [x[0]**2 - 4, np.exp(-x[0]) - 1]

def cons_J(x):
    # 补全第二行对x[1]的偏导0,保证雅可比形状为(2,2)
    return [[2*x[0], 0], [-np.exp(-x[0]), 0]]

def cons_H(x, v):
    return v[0]*np.array([[2,0], [0,0]]) + v[1]*np.array([[np.exp(-x[0]), 0], [0,0]])

nonlin_const = opt.NonlinearConstraint(cons_f, -np.inf, 1, jac=cons_J, hess=cons_H)

# 求解,如果传入自定义雅可比cons_J,就不需要设置jac="2-point"做数值差分
x0 = np.array([0.50, 0.75])
res = opt.minimize(f, x0, method='trust-constr',jac=cons_J, hess=opt.SR1(), bounds=bounds, constraints=[lin_const, nonlin_const], options={'verbose': 1})
print(res.x)

修正点说明

  • 补全非线性约束雅可比第二行的缺失元素,保证雅可比输出形状匹配(约束数, 变量数)要求
  • 移除冗余的恒成立线性约束,简化约束定义
  • 统一雅可比传参:如果传入自定义解析雅可比cons_J,就不需要再设置jac="2-point"用数值差分计算雅可比,避免参数冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:36:20