水泵调度凸优化问题变量减半后无可行解的原因是什么
问题根因定位
首先明确:这不是CPLEX求解器的特性导致的问题,核心是你的代码存在时间单位硬编码错误,同时时段粒度调整后约束兼容性没有适配。
核心错误点
- 时间转换系数硬编码错误
你代码中的FACTOR = 0.001*1800*self.RESERVOIR_VOLUME里的1800是固定值,对应30分钟的秒数,而你15分钟间隔运行时的时间步长是900秒,这个系数本身在15分钟场景下就存在计算偏差,只是刚好没触发约束越界。当你调整为30分钟间隔后,要么是步长计算逻辑不匹配,要么是流量/水位的转换比例完全错误,导致计算出来的蓄水池水位res_level不符合约束范围,直接触发无解。 - 整数变量边界被自动修改
日志里的Warning: Non-integral bounds for integer variables rounded提示CPLEX自动对非整数的整数变量边界做了四舍五入,这个操作很可能直接修改了你原本的约束阈值,比如把总输水量的最低要求、水位上下限做了不符合预期的调整,导致原本可行的场景变成不可行。 - 时段粒度变粗后约束可行性下降
15分钟间隔下你每15分钟就可以调整一次泵速,灵活控制水位变化;调整为30分钟间隔后,泵速调整的灵活度下降一半,很容易出现某30分钟内要么进水量太多导致水位超2.6m上限,要么进水量太少导致水位低于2.0m下限,本身就不存在能满足所有约束的可行解,和求解器无关。
修复步骤
- 把硬编码的
FACTOR改为动态计算:根据当前使用的时间步长秒数计算转换系数,不要写死1800,确保流量到水位变化的计算逻辑和时段长度完全匹配。 - 修复整数变量的边界:把所有布尔变量、整数变量的边界调整为整数,避免CPLEX自动 rounding 破坏约束条件,也可以在求解参数里关闭自动边界修正。
- 验证约束可行性:先临时松弛水位上下限、总输水量约束,运行模型看是否能得到可行解。如果松弛后有解,说明30分钟粒度下原约束确实无法满足,你要么恢复15分钟粒度,要么适当放宽约束阈值。
- 定位冲突约束:调用CVXPY的冲突约束检测工具
cp.infeasible.get_conflicting_constraints(assign_prob),可以直接输出具体是哪条约束导致的无解,方便快速定位问题。
内容的提问来源于stack exchange,提问作者Aidan Donnelly
相关产品推荐
相关产品推荐

