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

scipy least_squares如何添加变量间等式约束

实现方案

scipy.optimize.least_squares 原生仅支持变量的上下界约束,不支持变量间的等式/不等式约束,针对你提出的两个线性等式约束场景,有两种可直接落地的实现方式:

方案1:参数消元(最推荐,无精度损失,实现最简单)

你的两个约束是完全线性的,可以直接通过变量替换消去约束,把带约束问题转成无约束最小二乘问题,完全兼容现有least_squares的调用逻辑。
假设你的两个固定约束值为:

  • x - y = c1(c1为你指定的固定常数)
  • z - y = c2(c2为你指定的固定常数)

那么可以直接把x、z用唯一的自由变量y表示:
x = y + c1
z = y + c2
原来的3个优化变量直接缩减为1个自由变量y,优化过程中x、z会自动满足约束条件,不需要额外做约束处理。
代码示例:

from scipy.optimize import least_squares

# 定义约束的固定值,替换为你实际需要的数值即可
c1 = 2  # 对应约束x-y=2
c2 = 3  # 对应约束z-y=3

def loss_func(free_y, *arguments):
    # 从自由变量恢复x,y,z,天然满足预设约束
    x = free_y + c1
    y = free_y
    z = free_y + c2
    # 下方保留你原有的残差计算逻辑即可
    loss = [] # 替换为你实际的残差数组计算逻辑
    return loss

# 初始值只需要传入自由变量y的初始值即可,直接从原初始数组中取y的初始值
y_init = x_arr[1]  # x_arr为你原来存储x,y,z初始值的数组
res = least_squares(loss_func, y_init, args=arguments)

# 优化完成后恢复x,y,z的最优结果
opt_y = res.x[0]
opt_x = opt_y + c1
opt_z = opt_y + c2

方案2:改用支持约束的优化接口(适合约束复杂、不便消元的场景)

如果后续约束变复杂无法直接消元,可以放弃least_squares,改用scipy.optimize.minimize接口,自己构造最小二乘目标函数(即残差平方和),同时传入等式约束即可。
代码示例:

import numpy as np
from scipy.optimize import minimize

# 定义约束的固定值,替换为你实际需要的数值即可
c1 = 2
c2 = 3

def obj_func(x_arr, *arguments):
    x, y, z = x_arr
    # 计算你原来定义的残差数组
    resi = [] # 替换为你原来loss_func中的残差计算逻辑,返回数组格式
    # 最小二乘的优化目标是残差平方和最小
    return np.sum(np.array(resi)**2)

# 定义等式约束
constraints = [
    {"type": "eq", "fun": lambda x: x[0] - x[1] - c1}, # 对应约束x-y = c1
    {"type": "eq", "fun": lambda x: x[2] - x[1] - c2}  # 对应约束z-y = c2
]

# 传入初始值、约束、其他参数启动优化
res = minimize(obj_func, x_arr, args=arguments, constraints=constraints)
# 最优x,y,z结果直接从res.x中读取即可
opt_x, opt_y, opt_z = res.x

注意:如果你的残差计算逻辑没有特殊的强非线性复杂度,优先选择方案1,消元后用原生least_squares的求解效率和精度都高于通用带约束优化器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:57:17