简体   繁体   中英

Why does this constraint raise a DCP Error?

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM