Python.CVXPY學習指南三
前言:DCP(Disciplined convex programming )是一個系統,它從已給的基礎函式庫構造已知曲率的數學表示式。CVXPY使用DCP確保目標函式為凸.這部分解釋了DCP規則以及在CVXPY中的應用。
凸優化問題:凸優化之所以如此重要,是因為凸優化的重要特性,凸優化的任意區域性最優解也是全域性最優解。
凸優化問題是形式如下:
其中
- 目標函式必須是凸的,
- 不等式約束是凸的
- 等式約束
hi(x) 必須是仿射的。
一個值得注意的問題是:凸優化問題的可行集是凸的。
凹最大化問題:
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
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.