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

如何在scipy优化过程中拒绝超出约束范围的局部最小值

关于scipy trust-constr方法约束校验的解决方案

scipy.optimize.minimize 使用trust-constr方法求解后返回的OptimizeResult对象,本身就内置了约束校验相关的属性,不需要额外修改迭代逻辑,你只要在局部优化结束后对返回结果做校验,就能筛选出符合约束的局部最小值。

核心校验属性

trust-constr返回的结果包含两个可直接用于约束判断的属性:

  • status:求解器结束状态码,仅当status == 0时代表求解正常结束,且最终结果满足所有预设约束
  • constr_violation:当前结果的约束违反总量,所有约束都满足时该值为0,数值越高代表违反约束的程度越高

结合basinhopping的实现方式

你可以自定义局部优化的包装函数,在每次调用trust-constr完成后先做约束校验,符合要求就返回当前结果,不符合就返回上一轮的可行局部最小值,不需要拒绝整个basinhopping步骤:

from scipy.optimize import basinhopping, minimize

# 替换为你自己的目标函数、约束、边界定义
def objective(x):
    return x[0]**2 + x[1]**2

constraints = [{"type": "eq", "fun": lambda x: x[0] + x[1] - 1}]
bounds = [(-2, 2), (-2, 2)]

last_feasible_res = None
def filtered_local_min(x):
    global last_feasible_res
    # 调用trust-constr求解局部最小值
    res = minimize(
        objective, 
        x, 
        method="trust-constr", 
        bounds=bounds, 
        constraints=constraints
    )
    # 校验约束(加1e-6阈值避免浮点误差影响)
    if res.status == 0 and res.constr_violation < 1e-6:
        last_feasible_res = res
        return res
    # 不符合约束时返回上一个可行解
    if last_feasible_res is not None:
        return last_feasible_res
    # 首次求解就无可行解时,将目标函数设为极大值避免basinhopping采纳
    res.fun = 1e10
    return res

# basinhopping调用时指定自定义的局部优化器
result = basinhopping(
    objective,
    x0=[0, 0],
    local_minimizer=filtered_local_min
)

可选细粒度控制

如果需要在迭代过程中提前拦截不符合约束的迭代点,可以给minimize传入callback回调函数,每一步迭代都会触发回调,你可以在回调中校验当前迭代点的约束满足情况,不符合要求就返回True提前终止本次局部优化,减少无效计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 12:57:05