Python.CVXPY学习指南三

凸问题的编程规则(Disciplined Convex Programming)

前言:DCP(Disciplined convex programming )是一个系统,它从已给的基础函数库构造已知曲率的数学表达式。 CVXPY使用DCP确保目标函数为凸.这部分解释了DCP规则以及在CVXPY中的应用。
凸优化问题:凸优化之所以如此重要,是因为凸优化的重要特性, 凸优化的任意局部最优解也是全局最优解
凸优化问题是形式如下:
Python.CVXPY学习指南三_第1张图片
其中 f0,...,fm 为凸函数,凸优化问题附加三个条件:

  • 目标函数必须是凸的,
  • 不等式约束是凸的
  • 等式约束 hi(x)=aTibi 必须是仿射的。
    一个值得注意的问题是:凸优化问题的可行集是凸的。
    凹最大化问题:
    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

每个表达式或子表达式被标记为下列曲率(根据它们的变量):
Python.CVXPY学习指南三_第2张图片使用如下的曲率规则。正如符号分析,结论总是正确的。但是当一个表达式是凸的或者凹的时,一个简单的分析能标记表达式是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.

你可能感兴趣的:(python.cvxpy)