CVXOPT es una librería en Python para optimización convexa que hace interface a librerías ya establecidas (como LAPACK, FFTW, GLPK, MOSEK, etc) para resolver los problemas de manera eficiente.
In [1]:
from cvxopt import matrix, solvers
Consideramos el siguiente problema:
In [2]:
%%latex
$$
\begin{array}{rr}
\text{minimizar} & 2x_1 + x_2 \quad
\\ \text{sujeto a} & -x_1 + x_2 \le 1
\\ & x_1 + x_2 \ge 2
\\ & x_2 \ge 0
\\ & x_1 - 2 x_2 \le 4
\end{array}
$$
De acuerdo a la documentación de cvxopt.solvers.lp, tenemos que expresar el problema como:
In [3]:
%%latex
$$
\begin{array}{rr}
\text{minimizar} & c^t x \qquad
\\ \text{sujeto a} & G x + s = h
\\ & A x = b
\\ & s \succeq 0
\end{array}
$$
Entonces:
In [4]:
%%latex
$$
\begin{array}{rr}
\text{minimizar} & \begin{pmatrix}2 & 1 \end{pmatrix} \begin{pmatrix}x_1 \\ x_2\end{pmatrix} \qquad\qquad\qquad
\\ \text{sujeto a} & \begin{pmatrix} -1 & 2 \\ -1 & -2 \\ 0 & -1 \\ 1 & -2\end{pmatrix}
\begin{pmatrix}x_1 \\ x_2\end{pmatrix} + \begin{pmatrix}s_1 \\ s_2\end{pmatrix}
= \begin{pmatrix}1 \\ -2 \\ 0 \\ 4 \end{pmatrix}
\\ & \text{ con } s_1,s_2 \gt 0
\end{array}
$$
Por lo tanto los argumentos estan dado de la siguiente manera:
In [5]:
# Notese que el objeto matrix() se declara por-columna en lugar del usual por-fila.
A = matrix([[-1., -1., 0., 1.], [1., -1., -1., -2.]])
b = matrix([1., -2., 0., 4.])
c = matrix([2., 1.])
print A
print b
print c
Finalmente encontramos la solución:
In [6]:
sol = solvers.lp(c, A, b)
print sol['x']
Consideremos el siguiente problema:
In [7]:
%%latex
$$
\begin{array}{rr}
\text{minimizar} & 2x_1^2 + x_2^2 + x_1 x_2 + x_1 + x_2
\\ \text{sujeto a} & -x_1 \ge 0 \qquad
\\ & x_2 \ge 0 \qquad
\\ & x_1 + x_2 = 1 \qquad
\end{array}
$$
De acuerdo a la documentación de cvxopt.solvers.qp, tenemos que expresar el problema como:
In [8]:
%%latex
$$
\begin{array}{rr}
\text{minimizar} & \frac{1}{2} x^t P x + q^t
\\ \text{sujeto a} & G x \preceq h
\\ & A x = b
\end{array}
$$
Entonces:
In [9]:
%%latex
$$
\begin{array}{rr}
\text{minimizar} & \frac{1}{2} \begin{pmatrix}x_1 & x_2 \end{pmatrix}
\begin{pmatrix} 4 & 1 \\ 1 & 2 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \end{pmatrix}
+ \begin{pmatrix} 1 & 1 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \end{pmatrix}
\\ \text{sujeto a} & \begin{pmatrix} -1 & 0 \\ 0 & -1 \end{pmatrix}
\begin{pmatrix}x_1 \\ x_2\end{pmatrix} \preceq \begin{pmatrix} 0 \\ 0 \end{pmatrix} \qquad\qquad
\\ & \begin{pmatrix} 1 & 1 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \end{pmatrix}
= \begin{pmatrix} 1 \end{pmatrix} \qquad\qquad
\end{array}
$$
Por lo tanto, resolvemos el problema de la siguiente manera:
In [10]:
P = matrix([[4., 1.], [1., 2.]])
q = matrix([1., 1.])
G = matrix([[-1., 0.], [0., -1.]])
h = matrix([0., 0.])
A = matrix([[1.], [1.]])
b = matrix([1.])
sol = solvers.qp(P, q, G, h, A, b)
print sol['x']
Referencias: