Python+Gurobi实现简单的微网优化运行小算例
之前一直用Matlab和工具箱的方式求解优化问题,今年暑期负责了暑期的Python课程,对Python有了更多的认识,Python确实是一个很简洁方便的语言。下面就以Python+Gurobi为例进行讲解。
准备工作
如何在PyCharm环境使用Gurobi,可参考官网说明。
在程序中使用了numpy、scipy和matplotlib(一个绘图库),需在Pycharm环境中通过pip install方式安装相应的库。
算例说明
在此假设一个并网型光储微电网,做一个24小时的优化运行问题,已知24小时负荷和光伏功率数据,在分时电价下,求解微电网的最优运行方案。
算例中的参数可根据自身情况做修改。
代码实现
import numpy as np
import scipy.sparse as sp
import gurobipy as gp
import matplotlib.pyplot as plt
from gurobipy import GRB
try:
#定义输入数据,如负荷、光伏、电价信息等
P_load = [700, 650, 500, 450, 600, 900, 1200, 1400, 1200, 1300, 1500, 1700, 1600, 1500, 1300, 1200, 1300, 1500, 1900, 1700, 1600, 1400, 1200, 1000] #24小时负荷数据
P_pv = [0, 0, 0, 0, 0, 0, 200, 400, 800, 1200, 1500, 1800, 1950, 2000, 1800, 1500, 1000, 500, 100, 0, 0, 0, 0, 0] #24小时光伏数据
Pricein = [0.43, 0.43, 0.43, 0.43, 0.43, 0.43, 0.43, 0.43, 0.69, 0.69, 0.69, 1.21, 1.21, 1.21, 1.21, 0.69, 0.69, 0.69, 1.21, 1.21, 1.21, 0.69, 0.69, 0.69] #购电电价
Priceout = [0.27, 0.27, 0.27, 0.27, 0.27, 0.27, 0.27, 0.27, 0.5, 0.5, 0.5, 1.02, 1.02, 1.02, 1.02, 0.5, 0.5, 0.5, 1.02, 1.02, 1.02, 0.5, 0.5, 0.5] # 售电电价
#定义系统相关参数,如电池参数,联络线功率参数等
#电池参数
Ess_max = 1500
Ess_min = 300
P_chmax = 500
P_dismax = 500
#联络线功率限制
P_gridmax = 3000
#定义优化时间
T = 24
#定义优化问题
m = gp.Model("OptMG")
#电池决策变量
P_ch = m.addMVar(T, lb= 0.0, ub= P_chmax, vtype=GRB.CONTINUOUS, name="P_ch")
P_dis = m.addMVar(T,lb=0.0, ub= P_dismax, vtype=GRB.CONTINUOUS, name="P_dis")
F_ch = m.addMVar(T, vtype=GRB.BINARY, name="F_ch")
F_dis = m.addMVar(T, vtype=GRB.BINARY, name="F_dis")
Ess = m.addMVar(T+1, lb= Ess_min, ub=Ess_max, vtype=GRB.CONTINUOUS, name="P_dis")
#电网交互功率决策变量
P_gridin = m.addMVar(T, lb= 0.0, ub= P_gridmax, vtype=GRB.CONTINUOUS, name="P_gridin")
P_gridout = m.addMVar(T, lb=0.0, ub=P_gridmax, vtype=GRB.CONTINUOUS, name="P_gridout")
F_gridin = m.addMVar(T, vtype=GRB.BINARY, name="F_gridin")
F_gridout = m.addMVar(T, vtype=GRB.BINARY, name="F_gridout")
#目标函数
obj = 0
for t in range(T):
obj += Pricein[t] * P_gridin[t] - Priceout[t] * P_gridout[t]
m.setObjective(obj, GRB.MINIMIZE)
#约束条件
m.addConstr(Ess[0] == 300)
m.addConstr(Ess[0] == Ess[T])
for t in range(T):
m.addConstr(P_load[t] + P_ch[t] + P_gridout[t] == P_pv[t] + P_dis[t] + P_gridin[t])
m.addConstr(P_ch[t] <= P_chmax * F_ch[t])
m.addConstr(P_dis[t] <= P_dismax * F_dis[t])
m.addConstr(F_ch[t] + F_dis[t] <= 1)
m.addConstr(P_gridin[t] <= P_gridmax * F_gridin[t])
m.addConstr(P_gridout[t] <= P_gridmax * F_gridout[t])
m.addConstr(F_gridin[t] + F_gridout[t] <= 1)
for t in range(T-1):
m.addConstr(Ess[t+1] == Ess[t] + P_ch[t] - P_dis[t])
m.optimize()
print('Obj: %g' % m.objVal)
Pgrid = P_gridin.X - P_gridout.X
P_ess = P_ch.X - P_dis.X
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
xlab = np.linspace(0,24,24)
plt.plot(xlab,Pgrid,color='y',label=u'电网功率')
plt.plot(xlab, P_ess, color='r',label=u'电池功率')
plt.plot(xlab, P_load, color='b',label=u'负荷')
plt.plot(xlab, P_pv, color='g',label=u'光伏')
plt.show()
except gp.GurobiError as e:
print('Error code ' + str(e.errno) + ': ' + str(e))
except AttributeError:
print('Encountered an attribute error')
