python - 为什么此约束会引发 DCP 错误?
问题描述
我已经定义了一个问题,它将最小化运行泵的成本。这被定义为问题的目标。
cost_cp = cp.sum(cp.multiply(cost_,selection))
objective = cp.Minimize(cost_cp)
定义的问题是:
problem = cp.Problem(objective, constraints)
我已经使用cp.multiply
和cp.vec
进行了计算来计算水库体积的差异,这提供了我期望的正确差异的答案。
flow_in = cp.vec(cp.multiply(input_flow_, flow_in_minutes))
flow_out = cp.vec(flow_out_)
flow_diff = flow_in - flow_out
当我使用cp.cumsum
. 它可以正确工作和计算,但是当我希望为此添加约束时DCPError
,我可以确定在这种计算中我哪里出错了,因为它以前对我来说没有问题。
我希望定义的约束是:
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]
volume_constraint
作品完美。问题在于min_level_constraint
and max_level_constraint
。
我尝试使用解决方案
problem.solve(solver=cp.CPLEX, verbose=False)
我提供的回溯是:
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():
我查看了有关 CVXPY 和 Stack Overflow 的文档,但没有发现任何适合我的问题的文档。我很困惑,因为它过去对我有用。
更新
在进一步研究之后,我检查了每个变量,看看它是否is_dcp()
会True
在符合 DCP 的情况下返回。
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
我假设flow_in
失败,那么我的其余计算也将因此失败。
解决方案
经过几个小时的额外审议并解决了这个问题,我能够找出原因。
正如我最初所想的那样,我的计算flow_in
不是 DCP,我不完全确定或理解为什么,但我肯定会在未来的时间里自学这一点。
如果将来有人遇到类似情况,我可以将计算调整为如下所示,并且可以看到我的计算在问题与答案中的变化。
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
推荐阅读
- python - Python bot 在本地运行良好,但在 Heroku 崩溃
- python - python - 如何在使用python中的链接列表抓取网站时保持循环
- vb.net - 从列表视图制作自动打字机
- javascript - 谷歌工作表脚本
- ansible - 从组中的所有主机获取 ansible_fqdn
- typescript - 有没有办法使用 TypeScript 的类型系统将“模板”类型声明为特定类型的字符串
- git - 安全远程访问 GIT 服务器
- .net - 仅在 Windows 7 上出现 .NET SSL 错误(在 Windows 10 上正常)
- javascript - 如果点击计数 JavaScript
- python - 在 Flask 中以 XML 格式获取响应