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>
     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)
    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
--> 938         data, solving_chain, inverse_data = self.get_problem_data(
    939             solver, gp, enforce_dpp, verbose)

~\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)

~\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)
    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.

  • 1
    $\begingroup$ You don't show the complete program, and in particular, don't show how res_level is calculated, so I don't even know what your DCP-noncompliant constraint is. In any event, the error message says the program(?) follows DQCP (Disciplined Quasiconvex Programming) rules, so did you try qcp=True` as suggested in the error message? $\endgroup$ Oct 22 at 17:04

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.