文章目录
安装与测试
cvxpy是Python的开源凸优化建模库,用于求解满足一定约束条件时的凸函数的最值问题。在凸函数中,任意两点的连线,均在函数的一侧,这种性质非常优良,易于求求解最值。而cvxpy为凸优化问题提供了便捷人性化的语法,使用起来非常方便,下面安装后做一个简单的示例
pip install cvxpy -i https://pypi.tuna.tsinghua.edu.cn/simple
考虑当 x + y ⩾ 1 x+y\geqslant1 x+y⩾1时, x 2 + y 2 x^2+y^2 x2+y2的最小值,用cvxpy求解如下
python
import cvxpy as cp
x, y = cp.Variable(), cp.Variable() # 优化变量
obj = cp.Minimize(x**2 + y**2) # 目标函数
constraints = [x + y >= 1] # 约束条件
prob = cp.Problem(obj, constraints) # 定义问题
prob.solve() # 求解
print("最优状态:", prob.status)
# 最优状态: optimal
print(f"最优目标值{prob.value:.2f}, x={x.value:.2f}, y={y.value:.2f}")
# 最优目标值0.50, x=0.50, y=0.50
基础表达式
从上面的示例可以看出,cvxpy中的优化变量,重载了运算符,遵循其自身的语法进行建模。例如其约束被定义为x+y>=1,目标函数被定义为x**2+y**2,这些不符合Python语法的表达式被称作cvxpy表达式。
在cvxpy中,表达式由变量、参数、数值常量、运算符+, -, *, /, @以及cvxpy中的原子函数构成,示例如下
python
import cvxpy as cp
x, y = cp.Variable(), cp.Variable()
a, b = cp.Parameter(), cp.Parameter(value=2)
# CVXPY表达式示例
3.69 + b/3
x - 4*a
cp.sqrt(x) - cp.minimum(y, x - a)
cp.maximum(2.66 - sqrt(y), square(x + 2*y))
其中,cp.Variable是变量,cp.Parameter是参数。在优化过程中,变量将被优化至最优值,而参数则是固定的,且在优化之前,必须指定其value。从数学过程来看,上面的b和 2 2 2没什么区别。但是,如果想测试多种不同参数的情况,二者就会表现出巨大差异。当a,b作为参数传入到某个优化问题后,该模型便已被cvxpy编译,后续在优化时,只需重新指定a,b的数值即可;但是,如果不使用参数,而直接填入数值,那么每次优化前,都需要重新编译一遍模型。
问题
一个凸优化问题,数学表达式仅包含两个部分,即目标函数和约束条件。cvxpy中定义了两类目标函数,分别是最小化Minimize和最大化Maximize,二者的输入参数均为cvxpy表达式;约束条件则是约束表达式的列表。
通过目标函数和约束条件即可实现Problem对象,调用Problem中的solve方法,即可完成凸优化问题的求解。solve的部分参数如下
- 【solver】 字符串类型,用于指定求解器,可选ECOS, SCS, OSQP等。
- 【verbose】为True时可打印日志
- 【gp】为True时,cvxpy将问题视为几何规划,自动进行变量代换。
- 【qcp】为True时,允许目标函数或约束是拟凸的,cvxpy 会通过二分法将其转化为一系列凸可行性问题来求解。
- 【requires_grad】为True时,开启自动微分。
- 【enforce_dpp】为True时,强制DPP检查,以确保问题对参数可微。
- 【ignore_dpp】为True时,忽略DPP检查,可节省时间。