2021-12-31

2021-12-31,第1张

2021-12-31

前言:在火电机组经济调度建模及求解——基础篇中,我们介绍了固定负荷情况下,基础的火电机组经济调度模型。然而,有些时候我们需要进行一些灵敏度分析。以"负荷"为例,在实际的火电机组经济调度中,负荷会随着用户需求的改变发生变化,从而会对机组的出力产生影响。因此,当负荷发生改变时,需要对经济调度过程中火电机组的出力变化进行分析。
本期推文内容介绍

  • 负荷灵敏度分析介绍与编程实现
  • pd.Dataframe的用法
Part 1 考虑负荷灵敏度分析的火电机组经济调度模型

基础的火电机组经济调度模型为:
min ⁡ P g , t T C = ∑ g , t a g P g , t 2 + b g P g , t + c g P g min ⁡ ≤ P g , t ≤ P g max ⁡ ∑ g P g , t ≥ L t begin{aligned} min _{P_{g, t}} mathrm{TC}=& sum_{g, t} a_{g} P_{g, t}^{2}+b_{g} P_{g, t}+c_{g} \ & P_{g}^{min } leq P_{g, t} leq P_{g}^{max } \ & sum_{g} P_{g, t} geq L_{t} end{aligned} Pg,t​min​TC=​g,t∑​ag​Pg,t2​+bg​Pg,t​+cg​Pgmin​≤Pg,t​≤Pgmax​g∑​Pg,t​≥Lt​​
以上火电机组的基础模型在推文火电机组经济调度建模及求解——基础篇中做过详细的介绍,这里不在赘述。在之前内容中,将负荷视为一个确定的标量,实际上该经济调度问题对位于区间[281,998]内的任意负荷值都是以可求解的。该区间的上下边界值根据所给出的火电机组出力最小值、最大值之和分别求得。火电机组出力范围参数值请看Part2程序。为了更好反应负荷变化情况,我们在负荷区间
∑ i = 1 N L o a d m i n ( i ) = 281 ∼ ∑ i = 1 N L o a d m a x ( i ) = 998 begin{aligned} sum_{i=1}^{N}Load_{min}(i)=281 sim sum_{i=1}^{N}Load_{max}(i)=998 end{aligned} i=1∑N​Loadmin​(i)=281∼i=1∑N​Loadmax​(i)=998​
内取11个值,并计算相应的火电机组出力情况。其负荷表达式为:
l o a d T o t a l = ∑ i = 1 N L o a d m i n ( i ) + k K ( ∑ i = 1 N L o a d m a x ( i ) − ∑ i = 1 N L o a d m i n ( i ) ) , k ∈ [ 1 , K ] begin{aligned} load_{Total}=sum_{i=1}^{N}Load_{min}(i)+frac{k}{K}(sum_{i=1}^{N}Load_{max}(i)-sum_{i=1}^{N}Load_{min}(i)),k in [1,K] end{aligned} loadTotal​=i=1∑N​Loadmin​(i)+Kk​(i=1∑N​Loadmax​(i)−i=1∑N​Loadmin​(i)),k∈[1,K]​
利用上述负载值分别计算相应的最优经济调度结果,其表达式可以用代码表示为:

load_demand = sum(output_min[i] for i in range(units))+(c/(counter-1))*(sum((output_max[i]-output_min[i] for i in range(units))))

当然,读者也可以选取属于负荷区间[281,998]内的任意值进行灵敏度分析,即: K K K可以取任意值。

Part 2 Python+Gurobi 代码实现
import gurobipy as gp
from gurobipy import GRB
import pandas as pd
# In[] data input
load_demand = 400 ##(Mw)
units = 5 # the total number of thermal units
counter = 11
# In[] minimum and maximum generating limits of each unit
output_min = [28,90,68,76,19] ## P_i^th,min (MW)
output_max = [206,284,189,266,53] ## P_i^th,max (MW)

# In[] the cost coef a b c of these thermal units
coef_A = [3,4.05,4.05,3.99,3.88] ## a_i^th ($/MW^2)
coef_B = [20,18.07,15.55,19.21,26.18] ## b_i^th ($/MW)
coef_C = [100,98.87,104.26,107.21,95.31] ## c_i^th ($)

##Difining the model
m = gp.Model("thermal_unit_dispatch_example ")

##Defining the decision variables
thermal_output  = m.addVars(units, vtype = GRB.CONTINUOUS, name='thermal_output')

## Constranits of the operating
m.addConstrs((thermal_output[i]>=output_min[i] 
              for i in range(units)),name='Operating_Limits_min')

m.addConstrs((thermal_output[i]<=output_max[i]
              for i in range(units)),name='Operating_Limits_max')

## Constranits of the load demanding(In this way, the load is a certain value)
# m.addConstr(gp.quicksum(thermal_output[i] for i in range(units))>=load_demand ,name='demand_load')

## seting the objective function
total_cost = gp.quicksum(coef_A[i]*thermal_output[i]*thermal_output[i]+coef_B[i]*thermal_output[i]+coef_C[i]
                        for i in range(units))

# In[] Sometimes we need  different dispatch patterns, if the load value changed
##### we need to analyze the sensitivity of load value
optimize_cost=[]
load=[]
rows = ['C'+str(c+1) for c in range(counter)] #define rows of the table
dispatch_plan = pd.Dataframe(columns=['g'+str(u+1) for u in range(units)],index=rows,data=0.0)
for c in range(counter):
    load_demand = sum(output_min[i] for i in range(units))+(c/(counter-1))*(sum((output_max[i]-output_min[i] for i in range(units))))
    load.append(load_demand)
    m.addConstr(gp.quicksum(thermal_output[i] for i in range(units))>=load_demand ,name='demand_load')
    m.setObjective(total_cost,GRB.MINIMIZE) #get the minimize total_cost 
    m.optimize()
    for u in range(units):
        dispatch_plan.loc['C'+str(c+1),'g'+str(u+1)]=float(thermal_output[u].x)
    optimize_cost.append(m.objVal)
dispatch_plan['load(MW)']=load
dispatch_plan['cost($/h)']=optimize_cost
# In[] showing the solution for load sencisitity analysis
print(dispatch_plan.round(2))

优化结果如下:

  • Tips 1: 通过一个简单的例子介绍pd.Dataframe的用法:
import pandas as pd
#pd.Dataframe( data, index, columns, dtype)
'''
data:输入的数据,可以是 ndarray,series,list,dict,标量以及一个 Dataframe.
index:行标签
columns:列标签
dtype:数据类型
'''
data=[[100,80,90],[90,100,80]]
table = pd.Dataframe(data,index=['张三','李四'],columns=['语文','数学','英语'])

结果展示如下:

Part 7 创作人员名单

作者| Thor、李同学
代码| Thor
审核| Thor、李同学


欢迎大家关注公众号获取最新资讯

参考文献
  1. A. Soroudi, Power System Optimization Modeling in GAMS
往期内容回顾

13. 拉格朗日乘子法与KKT条件
12. 经济调度问题的建模及求解——考虑爬坡约束
11. 火电机组经济调度建模及求解——基础篇
10. 基于Distflow的最优潮流模型(OPF)–模型推导篇
9. 火电机组经济调度建模及求解——基础篇
8. Python|Gurobi——零基础学优化建模-终章
7. Python|Gurobi——零基础学优化建模-压轴篇:多目标优化
6. Python|Gurobi——零基础学优化建模-分段模型线性化(PWL)
5. Python|Gurobi——零基础学优化建模-QCP
4. Python|Gurobi——零基础学优化建模-NLP
3. Python|Gurobi——零基础学优化建模-MIP
2. Python|Gurobi——零基础学优化建模-LP
1. Python|Gurobi——零基础学优化建模

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5689685.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存