前言:DCP(Disciplined convex programming )是一个系统,它从已给的基础函数库构造已知曲率的数学表达式。CVXPY使用DCP确保目标函数为凸.这部分解释了DCP规则以及在CVXPY中的应用。
凸优化问题:凸优化之所以如此重要,是因为凸优化的重要特性,凸优化的任意局部最优解也是全局最优解。
凸优化问题是形式如下:
其中f0,...,fm为凸函数,凸优化问题附加三个条件:
- 目标函数必须是凸的,
- 不等式约束是凸的
- 等式约束hi(x)=aTi−bi必须是仿射的。
一个值得注意的问题是:凸优化问题的可行集是凸的。
凹最大化问题:
maximize f0(x)
s.t. fi(x)≤0,i=1,...,m
aTix=bi,i=1,...,p
如果目标函数f0是凹的而不等式约束函数f1,...,fm是凸的,也成为凸优化问题,这个凹最大化问题可以简单通过极小化凸目标函数−f0得以求解。
1、表达式
在cvxpy中表达式由变量、参数、数值常量(例如Python floats、Numpy matrices)、标准算数运算符(+, -, *, /) 和标准库函数。
如下是cvxpy表达式的例子:
from cvxpy import *
# Create variables and parameters.
//建立变量与参数
x, y = Variable(), Variable()
a, b = Parameter(), Parameter()
# Examples of CVXPY expressions.
//cvxpy表达式:
3.69 + b/3
x - 4*a
sqrt(x) - min_elemwise(y, x - a)
max_elemwise(2.66 - sqrt(y), square(x + 2*y))
表达式可以是标量、向量或者矩阵。表达式的维度被存储在expr.size,如果使用表达式的维度没有意义,cvxpy将会抛出异常,例如两个不同size的矩阵相加。
import numpy
X = Variable(5, 4)
A = numpy.ones((3, 5))
# Use expr.size to get the dimensions.
print "dimensions of X:", X.size
print "dimensions of sum_entries(X):", sum_entries(X).size
print "dimensions of A*X:", (A*X).size
# ValueError raised for invalid dimensions.
try:
A + X
except ValueError, e:
print e
dimensions of X: (5, 4)
dimensions of sum_entries(X): (1, 1)
dimensions of A*X: (3, 4)
Incompatible dimensions (3, 5) (5, 4)
CVXPY uses DCP analysis to determine the sign and curvature of each expression.
CVXPY使用DCP分析来求每个表达式的正负号与曲率
2、正负号Sign
每一个表达式或者子表达式被标记为非负、非正、零或者未知。复合表达式的正负号可以从它的子表达式的正负号求出。
例如,expr1*expr2的正负号:
- Zero if either expression has sign zero.只要expr1或者expr2一个为0,则表达式为0
- Positive if expr1 and expr2 have the same (known) sign.
- Negative if expr1 and expr2 have opposite (known) signs.
Unknown if either expression has unknown sign.
给一个表达式符号总是正确的,但是当一个表达式能通过更加复杂的分析标记符号时,DCP可能标记一个表达式为unknown。
例如x*x符号为正,但是x被标记为unknown。
cvxpy根据常量的值决定它的符号,对于标量常量,它的符号是容易求的。如果向量或者矩阵的每一项都是正(负),则向量或者矩阵常数被标记为正(负)。如果向量或矩阵的每一项有正有负,则向量或者矩阵被标记为unknown sign.
The sign of an expression is stored as expr.sign:
x = Variable()
a = Parameter(sign="negative")
c = numpy.array([1, -1])
print "sign of x:", x.sign
print "sign of a:", a.sign
print "sign of square(x):", square(x).sign
print "sign of c*a:", (c*a).sign
sign of x: UNKNOWN
sign of a: NEGATIVE
sign of square(x): POSITIVE
sign of c*a: UNKNOWN
3、曲率Curvature
每个表达式或子表达式被标记为下列曲率(根据它们的变量):
使用如下的曲率规则。正如符号分析,结论总是正确的。但是当一个表达式是凸的或者凹的时,一个简单的分析能标记表达式是unknown。注意常量标记为affine,任何仿函数能标记为凸的或者凹的。
4、DCP problems
一个问题能够由目标函数和一系列约束构造。如果问题遵从DCP规则,这个问题将是凸的,能够被cvxpy解决。DCP规则要求目标函数有以下两种形式:
- Minimize(convex)
- Maximize(concave)
在DCP规则下的有效约束为: - affine == affine
- convex <= concave
- concave >= convex
你能调用object.is_dcp()来检查一个问题、约束、目标函数是否满足DCP规则。
//Here are some examples of DCP and non-DCP problems:
x = Variable()
y = Variable()
# DCP problems.
prob1 = Problem(Minimize(square(x - y)), [x + y >= 0])
prob2 = Problem(Maximize(sqrt(x - y)),
[2*x - 3 == y,
square(x) <= 2])
print "prob1 is DCP:", prob1.is_dcp()
print "prob2 is DCP:", prob2.is_dcp()
# Non-DCP problems.
# A non-DCP objective.
prob3 = Problem(Maximize(square(x)))
print "prob3 is DCP:", prob3.is_dcp()
print "Maximize(square(x)) is DCP:", Maximize(square(x)).is_dcp()
# A non-DCP constraint.
prob4 = Problem(Minimize(square(x)), [sqrt(x) <= 2])
print "prob4 is DCP:", prob4.is_dcp()
print "sqrt(x) <= 2 is DCP:", (sqrt(x) <= 2).is_dcp()
prob1 is DCP: True
prob2 is DCP: True
prob3 is DCP: False
Maximize(square(x)) is DCP: False
prob4 is DCP: False
sqrt(x) <= 2 is DCP: False
CVXPY will raise an exception if you call problem.solve() on a non-DCP problem.
# A non-DCP problem.
prob = Problem(Minimize(sqrt(x)))
try:
prob.solve()
except Exception as e:
print e
Problem does not follow DCP rules.
本文介绍了使用CVXPY进行凸优化编程的基本规则,包括目标函数和约束条件的要求,以及DCP(Disciplined Convex Programming)分析。详细讨论了表达式的正负号和曲率,帮助理解如何构建有效的凸优化问题。

被折叠的 条评论
为什么被折叠?



