You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用CVXPY实现二进制变量与条件约束,避免电池同时充放电

解决离网混合可再生能源系统中电池同时充放电的约束问题

我正在做离网混合可再生能源系统的容量优化配置,现有代码可正常运行并输出结果,但存在电池同时充放电的问题。需要添加约束实现:当充电功率p_c为正时,放电功率p_d必须为0;反之当p_d为正时,p_c必须为0。之前尝试在约束中使用if语句,出现语法错误。

参数定义

"""
Parameters for optimization
c_0: 弃电权重
c_wt: 风力发电机成本
c_pv: 光伏组件成本
p_N: 电池最大充/放电功率
C_B: 电池最大容量
C_B_low: 电池最低容量
C_0: 电池初始容量
n_d: 放电效率
n_c: 充电效率
"""
params = {'c_0': 100,
          'c_wt': 1000,
          'c_pv': 500,
          'p_N': 10000,
          'C_B':45000,
          'C_B_low':9000,
          'C_0':25000,
          'n_d':0.9,
          'n_c':0.95}

原优化函数代码

### 变量长度、权重及成本为假设值
n = len(p_l)

### 优化变量
s_pvs = cp.Variable(1, integer=True,)
s_pvsw = cp.Variable(1, integer=True)
s_pvse = cp.Variable(1, integer=True)
s_wt = cp.Variable(1, integer=True)

# 充电功率
p_c = cp.Variable(n)
# 放电功率
p_d = cp.Variable(n)
# 电池荷电状态
SOC = cp.Variable(n)

# 弃电功率
p_lcurt = cp.Variable(n)

### 目标函数
obj = cp.sum(params["c_0"]*p_lcurt + params["c_wt"]*s_wt + params["c_pv"]*(s_pvs + s_pvsw + s_pvse))

### 约束条件
constraints = [params["p_N"] >= p_c, p_c >= 0,
              
               params["p_N"] >= p_d, p_d >= 0,
              
               s_pvs >= 0, s_pvsw >= 0, s_pvse >= 0, 
              
               s_wt >= 0, p_lcurt >= 0, 
              
               SOC >= params["C_B_low"], SOC <= params["C_B"],
              
               SOC[0] == params["C_0"] + p_c[0]*params["n_c"] - p_d[0]/params["n_d"],
              
               SOC[1:] == SOC[:-1] + p_c[1:]*params["n_c"] - p_d[1:]/params["n_d"],
             
               s_pvs*p_pvs + s_pvse*p_pvse + s_pvsw*p_pvsw + s_wt*p_wt
               - p_l + p_lcurt - p_c + p_d == 0]

problem = cp.Problem(cp.Minimize(obj), constraints)
problem.solve(solver = cp.GLPK_MI, verbose = True)

print("s_pvsw:",s_pvsw.value,"s_pvse:",s_pvse.value,"s_pvs:", s_pvs.value,"s_wt:",
      s_wt.value,"问题解", problem.value)

return s_pvsw.value, s_pvse.value, s_pvs.value, s_wt.value, SOC.value, p_lcurt.value, p_d.value, p_c.value

解决方案:添加互斥线性约束

CVXPY等凸优化框架不支持直接在约束中使用if语句(逻辑判断属于非凸操作,无法被线性规划求解器处理),需通过二进制辅助变量+大M法将互斥逻辑转化为线性约束。

修改步骤:

  1. 新增二进制辅助变量:定义长度为n的二进制变量b,每个b[t]取0或1,代表t时刻的操作状态:

    • b[t] = 0:允许充电(或无操作),禁止放电
    • b[t] = 1:允许放电(或无操作),禁止充电
  2. 添加互斥约束:利用电池最大充放电功率params["p_N"]作为大M值,构造约束确保同一时刻p_c和p_d不同时为正。

修改后的完整代码(关键部分标注)

### 变量长度、权重及成本为假设值
n = len(p_l)

### 优化变量
s_pvs = cp.Variable(1, integer=True,)
s_pvsw = cp.Variable(1, integer=True)
s_pvse = cp.Variable(1, integer=True)
s_wt = cp.Variable(1, integer=True)

# 充电功率
p_c = cp.Variable(n)
# 放电功率
p_d = cp.Variable(n)
# 电池荷电状态
SOC = cp.Variable(n)
# 弃电功率
p_lcurt = cp.Variable(n)

# -------------------------- 新增二进制辅助变量 --------------------------
# 二进制变量:0表示允许充电/无操作,1表示允许放电/无操作
b = cp.Variable(n, boolean=True)
# -----------------------------------------------------------------------

### 目标函数
obj = cp.sum(params["c_0"]*p_lcurt + params["c_wt"]*s_wt + params["c_pv"]*(s_pvs + s_pvsw + s_pvse))

### 约束条件
constraints = [params["p_N"] >= p_c, p_c >= 0,
              
               params["p_N"] >= p_d, p_d >= 0,
              
               s_pvs >= 0, s_pvsw >= 0, s_pvse >= 0, 
              
               s_wt >= 0, p_lcurt >= 0, 
              
               SOC >= params["C_B_low"], SOC <= params["C_B"],
              
               SOC[0] == params["C_0"] + p_c[0]*params["n_c"] - p_d[0]/params["n_d"],
              
               SOC[1:] == SOC[:-1] + p_c[1:]*params["n_c"] - p_d[1:]/params["n_d"],
             
               s_pvs*p_pvs + s_pvse*p_pvse + s_pvsw*p_pvsw + s_wt*p_wt
               - p_l + p_lcurt - p_c + p_d == 0,
               
               # -------------------------- 新增互斥约束 --------------------------
               p_c <= params["p_N"] * (1 - b),
               p_d <= params["p_N"] * b,
               # -----------------------------------------------------------------------
               ]

problem = cp.Problem(cp.Minimize(obj), constraints)
problem.solve(solver = cp.GLPK_MI, verbose = True)

print("s_pvsw:",s_pvsw.value,"s_pvse:",s_pvse.value,"s_pvs:", s_pvs.value,"s_wt:",
      s_wt.value,"问题解", problem.value)

return s_pvsw.value, s_pvse.value, s_pvs.value, s_wt.value, SOC.value, p_lcurt.value, p_d.value, p_c.value

约束逻辑说明

  • 当b[t] = 1时,p_c[t] <= params["p_N"]*(1-1) = 0,结合p_c >=0的约束,强制p_c[t] = 0,此时p_d[t]可在0到params["p_N"]之间取值。
  • 当b[t] = 0时,p_d[t] <= params["p_N"]*0 =0,结合p_d >=0的约束,强制p_d[t] =0,此时p_c[t]可在0到params["p_N"]之间取值。
  • 若p_c[t]和p_d[t]都为0,b[t]可取0或1,不影响结果。

内容的提问来源于stack exchange,提问作者Frederik Springer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 04:57:03