Pyomo求解光伏水泵调度优化问题无可行解求助
Pyomo整数规划无可行解排查与修复方案
核心排查方向
- 基础负荷覆盖检查:先确认所有时段的光伏出力
power_m_pyomo[m][i]是否都≥90kW的基础负荷。如果存在任意时段光伏出力连基础负荷都满足不了,哪怕水泵全停,总需求也会超过光伏出力,直接导致无可行解。 - 变量与约束验证:
- 检查
model.Id是否正确覆盖8-17时(共10个小时),总和约束sum(model.P[i] for i in model.Id) == 9是否对应正确的时段数量。 - 确认
model.P的整数约束和上下限设置正确:domain=Integers,且0 ≤ model.P[i] ≤3。
- 检查
- 目标函数线性化与除零问题:原需求用
max函数属于非线性,改为比值平均值时,要确保表达式线性。另外如果存在光伏出力为0的时段,会触发除零错误,需添加约束过滤这类时段或做特殊处理。
代码修正示例(针对常见问题)
假设你的代码缺失了总负荷不超过光伏出力的关键约束,且未明确水泵单台功率,以下是修正后的核心片段:
import pyomo.environ as pyo # 假设已加载power_m_pyomo数据,格式为分月份的小时出力字典 # 示例:power_m_pyomo = {'1': {8:100, 9:120, ..., 17:95}, '2': {...}, ...} model = pyo.ConcreteModel() # 定义索引:月份m,小时Id(8-17共10小时) model.m = pyo.Set(initialize=power_m_pyomo.keys()) model.Id = pyo.Set(initialize=range(8, 18)) # 变量:每小时运行水泵数量,0-3的整数 model.P = pyo.Var(model.Id, domain=pyo.Integers, bounds=(0, 3)) # 参数:光伏出力、基础负荷 model.pv_output = pyo.Param(model.m, model.Id, initialize=lambda m, i: power_m_pyomo[m][i]) model.base_load = pyo.Param(model.Id, initialize=90) # 补充:水泵单台功率(需替换为实际值,比如每台50kW) PUMP_POWER = 50 # 约束1:每日水泵总运行等效时长为9小时 def total_runtime_rule(model): return sum(model.P[i] for i in model.Id) == 9 model.total_runtime = pyo.Constraint(rule=total_runtime_rule) # 约束2:每小时总负荷(基础+水泵)不超过光伏出力(关键约束,缺失会导致无约束或冲突) def load_limit_rule(model, m, i): return model.base_load[i] + model.P[i] * PUMP_POWER <= model.pv_output[m][i] model.load_limit = pyo.Constraint(model.m, model.Id, rule=load_limit_rule) # 约束3:可选,确保光伏出力至少覆盖基础负荷,避免无可行解 def pv_min_base_rule(model, m, i): return model.pv_output[m][i] >= model.base_load[i] model.pv_min_base = pyo.Constraint(model.m, model.Id, rule=pv_min_base_rule) # 目标函数:最小化各时段过剩功率与光伏出力比值的平均值 def objective_rule(model): total_excess = 0 total_pv = 0 for m in model.m: for i in model.Id: pv = model.pv_output[m][i] load = model.base_load[i] + model.P[i] * PUMP_POWER total_excess += max(pv - load, 0) # 过剩功率非负 total_pv += pv # 避免除零 if total_pv == 0: return 0 return total_excess / total_pv model.obj = pyo.Objective(rule=objective_rule, sense=pyo.minimize) # 使用整数规划求解器(如CBC,需提前安装) solver = pyo.SolverFactory('cbc') result = solver.solve(model) # 输出结果 print(result) if result.solver.status == pyo.SolverStatus.ok and result.solver.termination_condition == pyo.TerminationCondition.optimal: print("最优运行方案:") for i in model.Id: print(f"小时{i}:运行{pyo.value(model.P[i])}台水泵") else: print("无可行解或求解失败,建议检查约束冲突")
关键注意事项
- 水泵单台功率:你未明确给出该参数,这是计算水泵总负荷的核心,必须替换为实际值。
- 年度优化调整:如果目标是年度过剩最小化,需将月份维度纳入总运行时长约束(比如每月按30天计算,全年总时长=93012)。
- 求解器选择:整数规划必须用支持整数变量的求解器(如CBC、Gurobi),不要用仅支持线性规划的求解器。
内容的提问来源于stack exchange,提问作者Owen Sgbd
相关产品推荐
相关产品推荐

