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

中等规模带约束优化问题:是否存在快于SLSQP的算法?

更快的求解方案

针对你的500变量、带边界+少量不等式约束的优化问题,核心提速思路是把问题转化为线性规划(LP)——你的目标函数和约束本质都是线性的,没必要用SLSQP这类通用非线性求解器,专用LP求解器的速度会快很多。以下是具体方案:

1. 改用Scipy的linprog(线性规划专用求解器)

linprog是Scipy专为LP问题设计的求解器,内置高效的内点法/单纯形法,处理中等规模变量的LP问题远快于SLSQP。

首先把你的约束转化为标准LP形式:

  • 目标函数:最大化sum(x*pred) → 等价于最小化-sum(x*pred)
  • 原约束|sum(x*varN)| ≤5拆成两个线性不等式:sum(x*varN) ≤5 和 -sum(x*varN) ≤5
  • 变量上下界保持-0.03 ≤x ≤0.03

代码示例:

from scipy.optimize import linprog
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.rand(500,5),columns=['pred','var1','var2','var3','weights'])

# 提前提取numpy数组,避免DataFrame重复索引开销
pred = df['pred'].values
var1 = df['var1'].values
var2 = df['var2'].values
var3 = df['var3'].values

# 目标函数系数:minimize -sum(x*pred) → c = -pred
c = -pred

# 构造不等式约束矩阵A_ub和向量b_ub
A_ub = np.array([
    var1,   # sum(x*var1) ≤5
    -var1,  # sum(x*var1) ≥-5 → 等价于 -sum(x*var1) ≤5
    var2,
    -var2,
    var3,
    -var3
])
b_ub = np.array([5,5,5,5,5,5])

# 变量上下界
bounds = [(-0.03, 0.03)] * len(pred)

# 用'highs'方法求解(Scipy 1.9+默认,高效内点法)
sol = linprog(
    c=c,
    A_ub=A_ub,
    b_ub=b_ub,
    bounds=bounds,
    method='highs',
    options={'maxiter': 1000}
)

2. 用cvxpy调用更高效的LP求解器

如果Scipy的linprog还不够快,可以用cvxpy——它封装了ECOS、OSQP等更快的开源LP求解器,代码更简洁,自动处理约束转化,适合大规模问题。

在Colab中先安装(若未安装):

!pip install cvxpy

代码示例:

import cvxpy as cp
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.rand(500,5),columns=['pred','var1','var2','var3','weights'])

pred = df['pred'].values
var1 = df['var1'].values
var2 = df['var2'].values
var3 = df['var3'].values

# 定义优化变量
x = cp.Variable(len(pred))

# 目标函数:直接最大化sum(x*pred)
objective = cp.Maximize(x @ pred)

# 约束直接用数学表达式书写,无需手动构造矩阵
constraints = [
    cp.abs(x @ var1) <= 5,
    cp.abs(x @ var2) <= 5,
    cp.abs(x @ var3) <= 5,
    x >= -0.03,
    x <= 0.03
]

# 构建问题并求解(可选ECOS/OSQP等求解器)
prob = cp.Problem(objective, constraints)
prob.solve(solver=cp.ECOS)

# 获取结果
print("最优值:", prob.value)
print("最优解:", x.value)

3. 优化原SLSQP代码(若必须用非线性求解器)

如果因特殊需求坚持用SLSQP,可通过以下细节提速:

  • 提前把DataFrame列转为numpy数组,避免每次函数调用都从DataFrame取数
  • 用矩阵乘法@替代元素乘后求和,减少计算开销
  • 关闭不必要的输出,调整精度参数(若不需要极高精度)

优化后的代码:

from scipy.optimize import minimize, Bounds
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.rand(500,5),columns=['pred','var1','var2','var3','weights'])

# 提前提取numpy数组
pred_arr = df['pred'].values
var1_arr = df['var1'].values
var2_arr = df['var2'].values
var3_arr = df['var3'].values

def obj(x):
  return -(x @ pred_arr)

def c1(x):
  return 5 - abs(x @ var1_arr)

def c2(x):
  return 5 - abs(x @ var2_arr)

def c3(x):
  return 5 - abs(x @ var3_arr)

sol = minimize(
    fun=obj,
    x0=df['weights'].values,
    method='SLSQP',
    bounds=Bounds(-0.03, 0.03),
    constraints=[{'type': 'ineq', 'fun': c1},{'type': 'ineq', 'fun': c2},{'type': 'ineq', 'fun': c3}],
    options={'maxiter': 1000, 'disp': False}
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:31:01