3

I'm trying to solve a convex optimisation problem using CVXPY. I've values x, y which are 150 and 60. These are the initial demand of 2 timeslots. The objective is to minimise the total cost.

Total cost = x * price1 + y * price2 + penalty
Penalty = (150 - x) * 6

So I want to find what are the optimal values of x and y. price1 and price 2 are based on the demand value.

My code is

import cvxpy as cp

def price_func(demand):
    prices = [14, 15, ......., 36.3]
    limits = [0.51, 0.61, ......, 1]
    for i in range(len(limits)):
        if limits[i] * 155 >= demand:
            return prices[i]


x = cp.Variable()
y = cp.Variable()
x.value = 150
y.value = 60

constraints = [x + y == 210,
               x >= y,
               y >= 60]

# Form objective.
obj = cp.Minimize((x*price_func(x.value) + y*price_func(y.value)) * 0.5 + (150 - x.value) * 6)

# Form and solve problem.
prob = cp.Problem(obj, constraints)
prob.solve(warm_start=True)

However, as I understand, my objective in cvxpy looks as

minimize (var0 @ 144.6 + var1 @ 14.0) @ 0.5 

This implies cvxpy doesn't use my price function. But rather it as a fixed value.

How can I fix that issue and make sure cvxpy pick my correct objective function?

  • 2
    1) **You cannot feed cvxpy black-box functions**. You will **need to express your model by only using cvxpy-provided expressions**. 2) Your objective-function is very incompatible (`if` usually means: non-smooth!) and will need some more preprocessing / linearization (which probably is easier if those arrays are nondecreasing, but it's not defined exactly). 3) Also: `x.value` is expected to be garbage until you solved the problem. Before that, you cannot use it! It's not an expression-proxy, but a getValue-like call (for some yet unknown value). – sascha Aug 16 '20 at 12:51
  • @sascha Thanks for the info. I'm not using if in the objective function. That is the price function where I need to find the corresponding price of given demand. – Thusitha Thilina Dayaratne Aug 16 '20 at 14:10
  • Your objective (`cp.Minimize`) evals `price_func` (depending on yet unknown *optimization var* `x`) which is a python-function which branches using if internally. Even with black-box support like in scipy.minimize, this would be non-smooth. – sascha Aug 16 '20 at 14:17
  • @sascha thanks. So are you implying that cvxpy doesn't support non-smooth objective functions? – Thusitha Thilina Dayaratne Aug 16 '20 at 14:31
  • No i'm not. Nearly all of scipy's NLP-algorithms (Nelder-Mead probably the sole exception) do not support non-smooth objectives (or constraints). Being twice differentiable is the common assumption there. cvxpy on the other hand do allow lots of non-smooth things (see for example the min-function) which comes from it's conic background. But still... it's a closed system of expressions and cannot use outside-things. – sascha Aug 16 '20 at 14:33
  • Thanks :) I'll look into that – Thusitha Thilina Dayaratne Aug 16 '20 at 23:16

0 Answers0