CVXPY建模如何实现流量爬坡约束与流量变化检测布尔变量
CVXPY水库入流模型添加爬坡速率约束实现
问题描述
- 建模场景:基于CVXPY开发24小时尺度水库预估入流计算程序,将24小时划分为7个时长不等的时段,所有时段按30分钟间隔拆分为独立计算步长。当前逻辑为通过布尔选择变量确定各时段目标流量,再重构得到全步长入流向量,作为后续水位、库容约束的计算基础。
- 现存缺陷:模型未考虑实际流量调整的爬坡速率限制,流量会直接跳变到时段目标值,例如从15l/s调整到17l/s实际需要4个30分钟步长(单步爬坡上限0.5l/s),模型会直接在步长边界跳变,导致小表面积水库的计算结果偏差较大。
效果对照
无爬坡约束时,00:00-08:00共16个30分钟步长的输出为:
[120 120 120 120 120 120 120 120 120 120 120 120 120 120 120 120]
设置单步爬坡率0.5l/s、初始流量118l/s时,期望输出为:
[118 118.5 119 119.5 120 120 120 120 120 120 120 120 120 120 120 120]
原有未加爬坡约束的代码
FACTOR = 1/self.SURFACE_AREA input_flow_matrix=np.zeros((max(period_lengths),len(period_lengths))) for i,l in enumerate(period_lengths): input_flow_matrix[:l,i]=1 selection = cp.Variable(shape=cost_.shape,boolean=True) assignment_constraint = cp.sum(selection,axis=1) == 1 input_flow_= cp.sum(cp.multiply(flow_,selection),axis=1) input_flow_vector=cp.vec(cp.multiply(input_flow_matrix,np.ones((max(period_lengths), 1)) @ cp.reshape(input_flow_,(1,len(period_lengths))))) res_flow= (input_flow_vector-cp.vec(out_flow_)) net_volume = res_flow * 1.8 res_level=cp.cumsum(net_volume) * FACTOR + initial_level volume_= cp.sum(cp.multiply(volume_,selection)) volume_constraint = volume_ >= v_min min_level_constraint = res_level >= min_level max_level_constraint = res_level <= max_level constraints = [assignment_constraint, max_level_constraint, min_level_constraint, volume_constraint] cost_ = cp.sum(cp.multiply(cost_,selection)) assign_prob = cp.Problem(cp.Minimize(cost_),constraints) assign_prob.solve(solver=cp.CPLEX, verbose=False)
实现方案
不需要额外引入标记时段流量变化的布尔变量,直接在全步长入流向量上添加相邻步长的流量差约束即可,具体修改如下:
- 新增两个基础参数:单30分钟步长允许的最大流量变化值
RAMP_RATE、调度周期初始时刻的入流值initial_input_flow。 - 补充两类爬坡约束:
- 首个计算步长的入流值与初始入流的差值绝对值不超过单步爬坡上限
- 所有相邻计算步长的入流差值绝对值不超过单步爬坡上限
- 将新约束加入原有约束列表即可,求解器会自动在爬坡限制下匹配最优流量过程,不需要手动编写爬坡过渡段的重构逻辑。
修改后代码片段
首先补充参数定义:
# 单30分钟步长允许的最大流量变幅,单位l/s RAMP_RATE = 0.5 # 调度起始时刻的实际入流值,单位l/s initial_input_flow = 118
替换原有约束定义部分:
# 初始步长爬坡约束 ramp_init = cp.abs(input_flow_vector[0] - initial_input_flow) <= RAMP_RATE # 全序列相邻步长爬坡约束 ramp_seq = cp.abs(input_flow_vector[1:] - input_flow_vector[:-1]) <= RAMP_RATE constraints = [ assignment_constraint, max_level_constraint, min_level_constraint, volume_constraint, ramp_init, ramp_seq ]
扩展说明
- 该实现基于CVXPY原生的线性绝对值约束,CPLEX求解混合整数规划问题时可直接处理,不需要额外引入0-1变量做big-M转换,求解效率更高。
- 如果实际场景中流量上升、下降的爬坡速率不一致(例如关阀调节速度快于开阀调节速度),可将绝对值约束拆分为两个单向不等式,示例如下:
# 单步上升最大变幅0.5l/s,单步下降最大变幅1l/s ramp_up = input_flow_vector[1:] - input_flow_vector[:-1] <= 0.5 ramp_down = input_flow_vector[:-1] - input_flow_vector[1:] <= 1 - 若出流过程同样存在爬坡限制,使用相同逻辑对出流向量添加相邻步长差值约束即可。
内容的提问来源于stack exchange,提问作者Aidan Donnelly
相关产品推荐
相关产品推荐

