lagrange103
lagrange103

Reputation: 169

CVXPY constraint: variable == 0 OR variable >= min

I am trying to solve a portfolio optimisation problem with the constraint that weights can be either zero or at least min (a Nx1 vector).

import cvxpy as cp

w = cp.Variable(len(mu))
mins = np.ones(len(mu)) * 0.03
risk = cp.quad_form(w, S)

prob = cp.Problem(cp.Minimize(risk), 
                  [cp.sum(w) == 1, 
                   w >= 0,
                   w >= min OR w == 0  # pseudocode for my desired constraint]

This is equivalent to a constraint that the weights are NOT 0 < w <= min, but I cannot find a way to express this in CVXPY (I have googled things like "cvxpy OR constraint" to no avail).

It feels like I'm missing something obvious. Perhaps there is a solution involving some boolean vector?

Upvotes: 2

Views: 2616

Answers (2)

lagrange103
lagrange103

Reputation: 169

Based on Erwin's answer, this is the working code.

import cvxpy as cp

w = cp.Variable(n)
mins = np.ones(n) * 0.03
maxs = np.ones(n)

risk = cp.quad_form(w, S)

prob = cp.Problem(cp.Minimize(risk), 
                  [cp.sum(w) == 1, 
                   w >= 0,
                   w >= cp.multiply(k, mins),
                   w <= cp.multiply(k, maxs)])
prob.solve(solver="ECOS_BB")

EDIT: changed k @ mins to cp.multiply(k, mins) as per comment

Upvotes: 1

Erwin Kalvelagen
Erwin Kalvelagen

Reputation: 16724

This is called w being a semi-continuous variable. Most advanced solvers support this type of variable directly. As CVXPY does not understand semi-continuous variables, we can use binary variables δ ∈ {0,1} and form the constraints:

   δ⋅min ≤ w ≤ δ⋅max

where we can set max=1.

This makes the problem a MIQP (Mixed-Integer Quadratic Programming) problem. This usually means that you need to use a high-end solver that supports this type of model.

Upvotes: 2

Related Questions