I'm trying to solve an optimisation problem in python using CVXPY. Specifically, I am trying to optimise two available resources based on some data.
Below is a toy example of the problem I am having. I have some data y which can be thought of as a vector of daily unit demand and I have two resources which are available each day to meet this demand. a is a constant resource where the same amount will be available each day. b is essentially a daily quantity of buffer resource which can be used if needed.
There are three daily costs for the two resources, a has a standard cost, while b has a used cost and an unused cost.
There are two constraints, a must be positive and b can't be negative. I believe this should now be trivial as the optimal solution should be a=1 and b=0. Once this works I will add another constraint to limit the number of days taht are allowed to be under resourced
import cvxpy as cp
import numpy as np
# some random data
n_days = 5
y = np.random.randint(low=0, high=10, size=n_days)
# Two variables to be optimised - These are available resources, a is always used, b is used based on demand
a = cp.Variable(integer=True)
b = cp.Variable(integer=True)
# These are unit costs
r_a_used = 1
r_b_used = 1.5
r_b_unused = 0.2
a_used = a * n_days # The same amount of a will be used at every time point
b_unused = cp.sum(cp.maximum((b - cp.maximum((y - a), 0)), 0)) # calculate how much resource of b is used over all time points
b_used = (b * n_days) - b_unused # calculate how much resource of b is used at each time point
# Calculate the cost
cost = (a_used * r_a_used) + (b_used * r_b_used) + (b_unused * r_b_unused)
# Both a and b must be greater than equal to zero
constraints = [a >= 0, b >= -1]
# solve
objective = cp.Minimize(cost)
prob = cp.Problem(objective, constraints)
prob.solve()
I'm getting the following error:
Traceback (most recent call last):
File "/home/user/Documents/toy_example.py", line 30, in <module>
prob.solve()
File "/home/user/anaconda3/envs/myenv/lib/python3.10/site-packages/cvxpy/problems/problem.py", line 503, in solve
return solve_func(self, *args, **kwargs)
File "/home/user/anaconda3/envs/myenv/lib/python3.10/site-packages/cvxpy/problems/problem.py", line 1072, in _solve
data, solving_chain, inverse_data = self.get_problem_data(
File "/home/user/anaconda3/envs/myenv/lib/python3.10/site-packages/cvxpy/problems/problem.py", line 646, in get_problem_data
solving_chain = self._construct_chain(
File "/home/user/anaconda3/envs/myenv/lib/python3.10/site-packages/cvxpy/problems/problem.py", line 898, in _construct_chain
return construct_solving_chain(self, candidate_solvers, gp=gp,
File "/home/user/anaconda3/envs/myenv/lib/python3.10/site-packages/cvxpy/reductions/solvers/solving_chain.py", line 217, in construct_solving_chain
reductions = _reductions_for_problem_class(problem, candidates, gp, solver_opts)
File "/home/user/anaconda3/envs/myenv/lib/python3.10/site-packages/cvxpy/reductions/solvers/solving_chain.py", line 132, in _reductions_for_problem_class
raise DCPError(
cvxpy.error.DCPError: Problem does not follow DCP rules. Specifically:
The objective is not DCP. Its following subexpressions are not:
maximum(Promote(var2, (5,)) + -maximum([9. 5. 1. 5. 0.] + Promote(-var1, (5,)), 0.0), 0.0)
maximum(Promote(var2, (5,)) + -maximum([9. 5. 1. 5. 0.] + Promote(-var1, (5,)), 0.0), 0.0)
I think this should be a convex optimisation problem, so I think it might be the formulation of the problem in CVXPY. Below are the visualisation trees of the atomic operations I am applying:
If anyone could help then it would be greatly be appreciated.
(Edited based on Michal's comment below)


