Reputation: 389
I have defined a problem which will minimize the cost of to run a pump. That is defined as the objective of the problem.
cost_cp = cp.sum(cp.multiply(cost_,selection))
objective = cp.Minimize(cost_cp)
The problem defined is:
problem = cp.Problem(objective, constraints)
I have ran calculations using the cp.multiply
and cp.vec
to calculate the difference in reservoir volumes which provides my the answer I would expect with the correct differences.
flow_in = cp.vec(cp.multiply(input_flow_, flow_in_minutes))
flow_out = cp.vec(flow_out_)
flow_diff = flow_in - flow_out
The problem arises when I calculated an accumulative summation using cp.cumsum
. It works and calculates correctly, but when I wish to add constraints around this is provides me with the DCPError
, I am unsure where I am going wrong in such calculation as it has worked previously no problem for me.
The constraints I wish to define are:
volume_constraint = volume_cp >= 300000
min_level_constraint = res_level >= min_level
max_level_constraint = res_level <= max_level
constraints = [assignment_constraint, volume_constraint, min_level_constraint, max_level_constraint]
The volume_constraint
works perfectly. The problem is with the min_level_constraint
and max_level_constraint
.
I attempt a solution using
problem.solve(solver=cp.CPLEX, verbose=False)
A traceback in which I am provided with is:
DCPError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_14560/1602474026.py in <module>
33
34 # Problem solve
---> 35 problem.solve(solver=cp.CPLEX, verbose=False)
~\AppData\Local\Programs\Python\Python38\lib\site-packages\cvxpy\problems\problem.py in solve(self, *args, **kwargs)
457 else:
458 solve_func = Problem._solve
--> 459 return solve_func(self, *args, **kwargs)
460
461 @classmethod
~\AppData\Local\Programs\Python\Python38\lib\site-packages\cvxpy\problems\problem.py in _solve(self, solver, warm_start, verbose, gp, qcp, requires_grad, enforce_dpp, **kwargs)
936 return self.value
937
--> 938 data, solving_chain, inverse_data = self.get_problem_data(
939 solver, gp, enforce_dpp, verbose)
940
~\AppData\Local\Programs\Python\Python38\lib\site-packages\cvxpy\problems\problem.py in get_problem_data(self, solver, gp, enforce_dpp, verbose)
563 if key != self._cache.key:
564 self._cache.invalidate()
--> 565 solving_chain = self._construct_chain(
566 solver=solver, gp=gp, enforce_dpp=enforce_dpp)
567 self._cache.key = key
~\AppData\Local\Programs\Python\Python38\lib\site-packages\cvxpy\problems\problem.py in _construct_chain(self, solver, gp, enforce_dpp)
789 candidate_solvers = self._find_candidate_solvers(solver=solver, gp=gp)
790 self._sort_candidate_solvers(candidate_solvers)
--> 791 return construct_solving_chain(self, candidate_solvers, gp=gp,
792 enforce_dpp=enforce_dpp)
793
~\AppData\Local\Programs\Python\Python38\lib\site-packages\cvxpy\reductions\solvers\solving_chain.py in construct_solving_chain(problem, candidates, gp, enforce_dpp)
153 if len(problem.variables()) == 0:
154 return SolvingChain(reductions=[ConstantSolver()])
--> 155 reductions = _reductions_for_problem_class(problem, candidates, gp)
156
157 dpp_context = 'dcp' if not gp else 'dgp'
~\AppData\Local\Programs\Python\Python38\lib\site-packages\cvxpy\reductions\solvers\solving_chain.py in _reductions_for_problem_class(problem, candidates, gp)
89 append += ("\nHowever, the problem does follow DQCP rules. "
90 "Consider calling solve() with `qcp=True`.")
---> 91 raise DCPError(
92 "Problem does not follow DCP rules. Specifically:\n" + append)
93 elif gp and not problem.is_dgp():
I have looked around the documentation on CVXPY and on Stack Overflow but I have found nothing in which works for my problem. I am baffled as it has worked for me in the past.
UPDATE
After researching a bit further my I checked each variable to see if it is_dcp()
which will return True
if DCP compliant.
flow_in = cp.vec(cp.multiply(input_flow_, flow_in_minutes)) # False
flow_out = cp.vec(flow_out_) # True
flow_diff = flow_in - flow_out # False
res_level = cp.cumsum(flow_diff) * FACTOR + 2.3 # False
I am assuming as the flow_in
fails then the rest of my calculations will also fail as a result.
Upvotes: 0
Views: 319
Reputation: 389
After a few hours extra deliberation and and working on the problem, I was able to figure out the reason.
It was as I thought initially and my calculation for my flow_in
wasn't DCP and I am not entirely sure or understand why, but I will be definitely teaching myself this in the time going forward.
I was able to adjust the calculation to look like the following if anyone comes across something like this in the future, and can see how my calculations changed in the question versus the answer.
flow_in = cp.sum(cp.multiply(volume_,selection),axis=1)
flow_out = cp.vec(flow_out_) # Value in litres -> must convert to a volume
flow_diff = (flow_in - flow_out) / 1000
res_level = cp.cumsum(flow_diff) / 160.6 + 2.3
Upvotes: 1