前言
cvxpy是解決凸優(yōu)化問題的,在使用之前要確保目標(biāo)函數(shù)是一個(gè)凸優(yōu)化問題(包括其中的變量范圍設(shè)置,參數(shù)設(shè)置等)
1
CVXPY是什么?
CVXPY是一種可以內(nèi)置于Python中的模型編程語言,解決凸優(yōu)化問題。它可以自動轉(zhuǎn)化問題為標(biāo)準(zhǔn)形式,調(diào)用解法器,解包結(jié)果集
如下代碼是使用CVXPY解決一個(gè)簡單的優(yōu)化問題:
from cvxpy import *
Create two scalar optimization variables.
在CVXPY中變量有標(biāo)量(只有數(shù)值大小),向量,矩陣。
在CVXPY中有常量(見下文的Parameter)
x = Variable() //定義變量x,定義變量y。兩個(gè)都是標(biāo)量
y = Variable()
Create two constraints.
//定義兩個(gè)約束式
constraints = [x + y == 1,
x - y >= 1]
//優(yōu)化的目標(biāo)函數(shù)
obj = Minimize(square(x - y))
//把目標(biāo)函數(shù)與約束傳進(jìn)Problem函數(shù)中
prob = Problem(obj, constraints)
prob.solve() # Returns the optimal value.
print “status:”, prob.status
print “optimal value”, prob.value //最優(yōu)值
print “optimal var”, x.value, y.value //x與y的解
status: optimal
optimal value 0.999999999761
optimal var 1.00000000001 -1.19961841702e-11
//狀態(tài)域被賦予’optimal’,說明這個(gè)問題被成功解決。
//最優(yōu)值是針對所有滿足約束條件的變量x,y中目標(biāo)函數(shù)的最小值
//prob.solve()返回最優(yōu)值,同時(shí)更新prob.status,prob.value,和所有變量的值。
改變已經(jīng)創(chuàng)建的問題
Problems是不可改變的,意味著在問題被創(chuàng)建之后它不可被改變。為了改變已有問題的目標(biāo)或者約束,應(yīng)該創(chuàng)建一個(gè)新的問題
Replace the objective.//不同的目標(biāo)函數(shù),相同的約束
prob2 = cvx.Problem(cvx.Maximize(x + y), prob.constraints)
print(“optimal value”, prob2.solve())
Replace the constraint (x + y == 1).//不同的約束,相同的目標(biāo)函數(shù)
constraints = [x + y <= 3] + prob.constraints[1:] //注意:此處是列表相加,prob.constraints[1:]取prob的約束集中
//從第二個(gè)開始的所有約束。
prob2 = cvx.Problem(prob.objective, constraints)
print(“optimal value”, prob2.solve())
optimal value 1.0
optimal value 3.00000000006
不可行問題與無邊界問題
如果一個(gè)問題是不可行問題,這個(gè)prob.status將會被設(shè)置為’infeasible’,如果問題是無邊界的,prob.status=unbounded,變量的值域?qū)⒉粫桓隆?
import cvxpy as cvx
x = cvx.Variable()
//一個(gè)不可行問題
An infeasible problem.
prob = cvx.Problem(cvx.Minimize(x), [x >= 1, x <= 0])
prob.solve()
print(“status:”, prob.status)
print(“optimal value”, prob.value)
// 無邊界問題
An unbounded problem.
prob = cvx.Problem(cvx.Minimize(x))
prob.solve()
print(“status:”, prob.status)
print(“optimal value”, prob.value)
status: infeasible
optimal value inf
status: unbounded
optimal value -inf
CVXPY的問題狀態(tài)即prob.status
cvxpy的prob.status可以有如下狀態(tài)值:
OPTIMAL: 問題被成功解決
INFEASIBLE:問題無解
UNBOUNDED:無邊界
OPTIMAL_INACCURATE:解不精確
INFEASIBLE_INACCURATE:
UNBOUNDED_INACCURATE:
If the solver completely fails to solve the problem, CVXPY throws a SolverError exception. If this happens you should try using other solvers. See the discussion of Choosing a solver for details.如果CVXPY求解器求解完全失敗,CVXPY將會拋出一個(gè)SolverError異常,如果這發(fā)生,你應(yīng)該使用其他求解器cvxpy求解器
Solving a problem with different solvers.
x = cvx.Variable(2)
obj = cvx.Minimize(x[0] + cvx.norm(x, 1))
constraints = [x >= 2]
prob = cvx.Problem(obj, constraints)
Solve with ECOS.
prob.solve(solver=cvx.ECOS)
print(“optimal value with ECOS:”, prob.value)
Solve with ECOS_BB.
prob.solve(solver=cvx.ECOS_BB)
print(“optimal value with ECOS_BB:”, prob.value)
Solve with CVXOPT.
prob.solve(solver=cvx.CVXOPT)
print(“optimal value with CVXOPT:”, prob.value)
Solve with SCS.
prob.solve(solver=cvx.SCS)
print(“optimal value with SCS:”, prob.value)
Solve with GLPK.
prob.solve(solver=cvx.GLPK)
print(“optimal value with GLPK:”, prob.value)
Solve with GLPK_MI.
prob.solve(solver=cvx.GLPK_MI)
print(“optimal value with GLPK_MI:”, prob.value)
Solve with GUROBI.
prob.solve(solver=cvx.GUROBI)
print(“optimal value with GUROBI:”, prob.value)
Solve with MOSEK.
prob.solve(solver=cvx.MOSEK)
print(“optimal value with MOSEK:”, prob.value)
Solve with Elemental.
prob.solve(solver=cvx.ELEMENTAL)
print(“optimal value with Elemental:”, prob.value)
Solve with CBC.
prob.solve(solver=cvx.CBC)
print(“optimal value with CBC:”, prob.value)
optimal value with ECOS: 5.99999999551
optimal value with ECOS_BB: 5.99999999551
optimal value with CVXOPT: 6.00000000512
optimal value with SCS: 6.00046055789
optimal value with GLPK: 6.0
optimal value with GLPK_MI: 6.0
optimal value with GUROBI: 6.0
optimal value with MOSEK: 6.0
optimal value with Elemental: 6.0000044085242727
optimal value with CBC: 6.0
//Use the installed_solvers utility function to get a list of the solvers your installation of CVXPY //supports.
print installed_solvers()
[‘CBC’, ‘CVXOPT’, ‘MOSEK’, ‘GLPK’, ‘GLPK_MI’, ‘ECOS_BB’, ‘ECOS’, ‘SCS’
向量和矩陣
Variables變量可以是標(biāo)量、向量、矩陣,意味著它可以是0,1,2維
#A scalar variable.
a = cvx.Variable()
Vector variable with shape (5,).
x = cvx.Variable(5) 列向量,5維
Matrix variable with shape (5, 1).
x = cvx.Variable((5, 1))
Matrix variable with shape (4, 7).
A = cvx.Variable((4, 7))
你可以使用python本身的數(shù)值庫來構(gòu)造矩陣與向量常數(shù),F(xiàn)or instance, if x is a CVXPY Variable in the expression A*x + b, A and b could be Numpy ndarrays, SciPy sparse matrices, etc. A and b could even be different types.
Currently the following types may be used as constants:
NumPy ndarrays
NumPy matrices
SciPy sparse matrices
看如下例子:
// Solves a bounded least-squares problem.
import cvxpy as cvx
import numpy
// Problem data.
m = 10
n = 5
numpy.random.seed(1)
A = numpy.random.randn(m, n)矩陣A
b = numpy.random.randn(m)向量b
//變量x,x是一個(gè)向量
x = cvx.Variable(n)
objective = cvx.Minimize(cvx.sum_squares(A*x - b))
constraints = [0 <= x, x <= 1]
prob = cvx.Problem(objective, constraints)
print(“Optimal value”, prob.solve())
print(“Optimal var”)
print(x.value) # A numpy ndarray.
Optimal value 4.14133859146
Optimal var
[ -5.11480673e-21 6.30625742e-21 1.34643668e-01 1.24976681e-01
-4.79039542e-21]
約束
正如上述代碼所寫,你能夠使用==,<=和>=去構(gòu)造約束條件。無論是否是標(biāo)量、向量以及矩陣,約束是元素性質(zhì)的,F(xiàn)or example, the constraints 0 <= x and x <= 1 mean that every entry of x is between 0 and 1.
你不能使用>與<構(gòu)造不等式
參數(shù)Parameters
Parameters are symbolic representations of constants. The purpose of parameters is to change the value of a constant in a problem without reconstructing the entire problem.參數(shù)是常量的符號表示,參數(shù)存在的目的是:不用重新構(gòu)造整個(gè)問題而改變一個(gè)問題常量的值。
參數(shù)可以是向量或者是矩陣,就像變量一樣。當(dāng)你創(chuàng)建一個(gè)參數(shù)時(shí),可以指明參數(shù)的屬性,例如參數(shù)的正負(fù),參數(shù)的對稱性等,Parameters can be assigned a constant value any time after they are created.
Positive scalar parameter.
m = cvx.Parameter(nonneg=True)
Column vector parameter with unknown sign (by default).
c = cvx.Parameter(5)
Matrix parameter with negative entries.
G = cvx.Parameter((4, 7), nonpos=True)
Assigns a constant value to G.
G.value = -numpy.ones((4, 7))
You can initialize a parameter with a value. The following code segments are equivalent:
Create parameter, then assign value.
rho = cvx.Parameter(nonneg=True)
rho.value = 2
Initialize parameter with a value.
rho = cvx.Parameter(nonneg=True, value=2)
//實(shí)例代碼:
Computing trade-off curves is a common use of parameters. The example below computes a trade-off curve for a LASSO problem.
import cvxpy as cvx
import numpy
import matplotlib.pyplot as plt
Problem data.
n = 15
m = 10
numpy.random.seed(1)
A = numpy.random.randn(n, m)
b = numpy.random.randn(n)
gamma must be nonnegative due to DCP rules.
gamma = cvx.Parameter(nonneg=True)
Construct the problem.
x = cvx.Variable(m)
error = cvx.sum_squares(A
x - b)
obj = cvx.Minimize(error + gamma
cvx.norm(x, 1))
prob = cvx.Problem(obj)
sq_penalty = []
l1_penalty = []
x_values = []
gamma_vals = numpy.logspace(-4, 6)
for val in gamma_vals:
gamma.value = val
prob.solve()
# Use expr.value to get the numerical value of
# an expression in the problem.
sq_penalty.append(error.value)
l1_penalty.append(cvx.norm(x, 1).value)
x_values.append(x.value)
plt.rc(‘text’, usetex=True)
plt.rc(‘font’, family=‘serif’)
plt.figure(figsize=(6,10))
Plot trade-off curve.
plt.subplot(211)
plt.plot(l1_penalty, sq_penalty)
plt.xlabel(r’|x|_1’, fontsize=16)
plt.ylabel(r’|Ax-b|^2’, fontsize=16)
plt.title(‘Trade-Off Curve for LASSO’, fontsize=16)
Plot entries of x vs. gamma.
plt.subplot(212)
for i in range(m):
plt.plot(gamma_vals, [xi[i] for xi in x_values])
plt.xlabel(r’\gamma’, fontsize=16)
plt.ylabel(r’x_{i}’, fontsize=16)
plt.xscale(‘log’)
plt.title(r’\text{Entries of x vs. }\gamma’, fontsize=16)
plt.tight_layout()
plt.show()
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
