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

基于IPOPT求解器的Python绝对值函数非线性优化求解方法

Python调用IPOPT求解含绝对值目标的非线性优化问题

前置环境准备

你需要先安装IPOPT求解器本体和对应的Python调用库,推荐同时安装CasADi做建模工具(内置自动微分,无需手动推导梯度、雅可比矩阵,大幅减少代码量),安装命令如下:

  • 用conda安装(全平台通用,优先选):
    conda install -c conda-forge ipopt cyipopt casadi
  • Linux平台也可以用系统源安装后再装Python库:
    sudo apt install coinor-libipopt-dev
    pip install cyipopt casadi
    

绝对值目标的兼容处理

IPOPT本身是针对连续可微非线性规划问题设计的求解器,而绝对值函数在零点处不可导,直接传入会导致求解报错,通用处理方案是引入松弛变量将绝对值项转为线性约束,完全适配IPOPT的求解要求:

原目标项为 min |x|,可等价转换为 min t,额外添加两条约束:t >= x、t >= -x,其中t为新增的非负松弛变量。

这种转换没有精度损失,比光滑近似(比如Huber损失、双曲正切近似)的效果更好,优先选择。

完整代码示例

我们以求解以下简单优化问题为例,演示用CasADi封装调用IPOPT的流程:

优化目标:min |x₁| + 2*|x₂|
约束条件:x₁ + x₂ ≥ 3,x₂ ≥ 0

import casadi as ca

# 1. 定义决策变量
x = ca.SX.sym('x', 2)  # x1, x2两个决策变量
t = ca.SX.sym('t', 2)  # 对应两个绝对值项的松弛变量t1, t2

# 2. 定义目标函数
obj = t[0] + 2 * t[1]

# 3. 定义约束
g = []
# 绝对值对应的约束
g.append(t[0] - x[0])  # t1 >= x1
g.append(t[0] + x[0])  # t1 >= -x1
g.append(t[1] - x[1])  # t2 >= x2
g.append(t[1] + x[1])  # t2 >= -x2
# 原题的约束
g.append(x[0] + x[1])  # x1 + x2 >=3
g.append(x[1])         # x2 >=0
# 松弛变量本身非负约束
g.append(t[0])
g.append(t[1])

g = ca.vertcat(*g)
# 定义约束的上下界:所有约束都是 >=0,所以下界是0,上界是无穷大
lbg = [0] * g.size1()
ubg = [ca.inf] * g.size1()

# 4. 构建优化问题并指定求解器为IPOPT
nlp = {'x': ca.vertcat(x, t), 'f': obj, 'g': g}
solver = ca.nlpsol('solver', 'ipopt', nlp, {'ipopt.print_level': 0, 'print_time': 0})

# 5. 求解并输出结果
res = solver(lbg=lbg, ubg=ubg)
x_opt = res['x'][:2].full().flatten()
obj_opt = res['f'].full().flatten()[0]

print(f"最优解x1: {x_opt[0]:.2f}, x2: {x_opt[1]:.2f}")
print(f"最优目标值: {obj_opt:.2f}")

代码运行输出

最优解x1: 3.00, x2: 0.00
最优目标值: 3.00

如果你需要用原生cyipopt接口调用,只需要按照上述转换规则处理绝对值项,再手动实现目标函数的梯度、约束的雅可比矩阵等接口即可,逻辑完全一致。

内容的提问来源于stack exchange,提问作者Gaurav K Bilas Paujikeshra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:57:03