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

使用Scipy fmin_slsqp求解器进行优化时遇到问题求助

问题修正与代码优化

原代码核心问题

  • 约束函数参数顺序错误:cons1的第一个参数应为优化变量w,fmin_slsqp会优先传递优化变量,再传递额外参数,原代码参数顺序完全颠倒。
  • args传递不匹配:目标函数和约束函数的额外参数需统一传递,原代码传递的w0属于冗余参数,且未正确给cons1传递fixed_value。
  • mdd函数边界缺失:当序列无回撤(min=0)时,serie[:min]为空数组,np.nanargmax会返回nan,引发索引错误。
  • 冗余变量定义:w = np.ndarray(shape=(5))未实际使用,可通过mat.shape[1]实现代码对任意列数的适配。

修正后的完整代码

import numpy as np
from scipy.optimize import fmin_slsqp

def mdd(serie):
    # 处理短序列或无回撤的边界情况
    if len(serie) < 2:
        return 0.0
    drawdowns = np.fmax.accumulate(serie) - serie
    min_idx = np.nanargmax(drawdowns)
    if drawdowns[min_idx] == 0:
        return 0.0
    max_idx = np.nanargmax(serie[:min_idx])
    return serie[max_idx] - serie[min_idx]

# 输入数据
mat = np.array([
    [1, 0, 0, 1, 1],
    [2, 0, 5, 3, 4],
    [3, 2, 4, 3, 7],
    [4, 1, 3, 3.1, -6],
    [5, 0, 2, 5, -7],
    [6, -1, 4, 1, -8]
]).astype('float32')
w0 = np.array([1/5]*mat.shape[1], dtype='float32')  # 自动适配列数的初始权重
fixed_value = 4.32

# 目标函数:最小化加权序列的最大回撤
def objective(w, mat):
    series = np.sum(mat * w, axis=1)
    return mdd(series)

# 约束1:各列最后一行与权重乘积之和等于fixed_value
def constraint1(w, mat, fixed_value):
    return np.sum(mat[-1, :] * w) - fixed_value

# 约束2:所有权重之和等于1
def constraint2(w):
    return np.sum(w) - 1

# 执行优化
result = fmin_slsqp(
    func=objective,
    x0=w0,
    f_eqcons=[constraint1, constraint2],
    bounds=[(0.0, 1.0)]*mat.shape[1],
    args=(mat, fixed_value),
    full_output=True
)

weights, fW, its, imode, smode = result
print("最优权重:", weights)
print("最小最大回撤:", fW)

关键修正说明

  1. 约束函数参数调整:将constraint1的第一个参数改为w,匹配fmin_slsqp的参数传递逻辑,通过args统一传递mat和fixed_value。
  2. mdd函数鲁棒性提升:增加序列长度判断、无回撤场景处理,避免空数组索引错误。
  3. 代码通用性优化:用mat.shape[1]替代固定列数,支持任意列数的输入数组。
  4. 冗余代码清理:删除未使用的变量,简化初始权重定义逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 14:39:15