理论
书上例子预备知识
解释:import numpy as np
#A节点与发电机组关联矩阵
"""
发电机组1,发电机组2,发电机组3
节点1
节点2
节点3
"""
A=np.array([[1,1,0],[0,0,1],[0,0,0]])
#B节点与负荷关联矩阵
"""
节点2负荷,节点3负荷
节点1
节点2
节点3
"""
B=np.array([[0,0],[1,0],[0,1]])
#S为节点与支路关联矩阵。其支路始节点对应元素为1,终节点对应-1
"""
支路12 ,支路13,支路23
节点1
节点2
节点3
"""
S=np.array([[1,1,0],
[-1,0,1],
[0,-1,-1]])
#X为支路电抗矩阵,它是一个对角阵,对角元素为各支路电抗值,其余元素为0
X=np.array([[0.25,0,0],
[0,0.25,0],
[0,0,0.25]])
正文-书上算例
不考虑网络约束
考虑网络约束正文-书上算例求解
目标函数如图
不看这个图,我用脑子想一下
网络安全约束,顾名思义 就是在普通调度上,同时是潮流满足约束,KCL,KVL等
于是我们可以理解为优化目标为传统的经济调度优化目标
约束分别为
- 等式约束 输入功率=负荷。
- 不等式约束 ,发电机组的上下限。
- 等式约束 潮流满足KCL,KVL 。(当是我们通过转移因子算法求出潮流时,其潮流本身就满足KCL,KVL),这是该等式约束我们转换为 潮流的上下限约束。
转移因子算法求潮流
#节点功率净输入向量
Pinj=[PG1,PG2,PG3-PD3]
#SF矩阵格式如下,为某个节点注入功率时, 功率要从参考节点流出
取参考节点为1
- | 节点1注入1功率时, | 节点2注入1功率时 | 节点3注入1功率时 |
---|---|---|---|
支路1-2 | 0(从节点1流入,从参考节点1流出,即不走支路1-2) | -2/3 此时电流方向为2指向1,与1-2相反,所以为- ,根据图可以求得数值2/3 | -1/3 |
2倍支路1-3 | 0 | -1/3,此时电流方向是3指向1 | -2/3 |
支路2-3 | 0 | 1/3 | -1/3 |
得到潮流方程
展开得到图3-5的潮流如下
PD3 = 800
PL12 = -(2 / 3) * PG2 - (1 / 3) * PG3 + (1 / 3) * PD3
PL13 = (-(1 / 3) * PG2 - (2 / 3) * PG3 + (2 / 3) * PD3) * 0.05
PL23 = (1 / 3) * PG2 - (1 / 3) * PG3 + (1 / 3) * PD3
编程语言:python
import numpy as np
from scipy import optimize as opt
import numpy as np
from scipy.optimize import minimize
# 目标函数
def objective(x): #=原文中的mincost
p11=x[0]
p12=x[1]
p13=x[2]
p21=x[3]
p22=x[4]
p23=x[5]
p31=x[6]
p32=x[7]
p33=x[8]
return (40*p11+50*p12+57.5*p13+43.75*p21+46.25*p22+48.75*p23+55.8*p31+57*p32+58.2*p33)
# 约束条件
def constraint1(x): #等式约束
pI11 = x[0]
pI12 = x[1]
pI13 = x[2]
pI21 = x[3]
pI22 = x[4]
pI23 = x[5]
pI31 = x[6]
pI32 = x[7]
pI33 = x[8]
PG1 = 100 + pI11 + pI12 + pI13
PG2 = 100 + pI21 + pI22 + pI23
PG3 = 50 + pI31 + pI32 + pI33
return pI11+pI12+pI13+pI21+pI22+pI23+pI31+pI32+pI33-550
#return PG1+PG2+PG3-800
#上下限
pI11=(0,200)
pI12 = (0,200)
pI13 = (0,100)
pI21 = (0,100)
pI22 = (0,100)
pI23 = (0,100)
pI31 =(0,50)
pI32 = (0,50)
pI33 = (0,50)
bnds=(pI11,pI12,pI13,pI21,pI22,pI23,pI31,pI32,pI33)
# 约束条件
def constraint2(x): #不等式约束 线路PL12 《=300
pI11 = x[0]
pI12 = x[1]
pI13 = x[2]
pI21 = x[3]
pI22 = x[4]
pI23 = x[5]
pI31 = x[6]
pI32 = x[7]
pI33 = x[8]
PD3=800
PG1 = 100 + pI11 + pI12 + pI13
PG2 = 100 + pI21 + pI22 + pI23
PG3 = 50 + pI31 + pI32 + pI33
PL12 = -(2 / 3) * PG2 - (1 / 3) * PG3 + (1 / 3) * PD3
return 300-np.abs(PL12)
# 约束条件
def constraint3(x): #不等式约束 不等式约束 线路PL13 《=300
pI11 = x[0]
pI12 = x[1]
pI13 = x[2]
pI21 = x[3]
pI22 = x[4]
pI23 = x[5]
pI31 = x[6]
pI32 = x[7]
pI33 = x[8]
PD3=800
PG1 = 100 + pI11 + pI12 + pI13
PG2 = 100 + pI21 + pI22 + pI23
PG3 = 50 + pI31 + pI32 + pI33
PL13 = (-(1 / 3) * PG2 - (2 / 3) * PG3 + (2 / 3) * PD3) * 0.05
return 300-np.abs(PL13)
# 约束条件
def constraint4(x): #不等式约束 不等式约束 线路PL23 《=330
pI11 = x[0]
pI12 = x[1]
pI13 = x[2]
pI21 = x[3]
pI22 = x[4]
pI23 = x[5]
pI31 = x[6]
pI32 = x[7]
pI33 = x[8]
PD3=800
PG1 = 100 + pI11 + pI12 + pI13
PG2 = 100 + pI21 + pI22 + pI23
PG3 = 50 + pI31 + pI32 + pI33
PL23 = (1 / 3) * PG2 - (1 / 3) * PG3 + (1 / 3) * PD3
return 330-np.abs(PL23)
con1 = {
'type': 'eq', 'fun': constraint1}
con2 = {
'type': 'ineq', 'fun': constraint2}
con3 = {
'type': 'ineq', 'fun': constraint3}
con4 = {
'type': 'ineq', 'fun': constraint4}
cons = ([con1,con2,con3,con4]) # 4个约束条件
if __name__ =='__main__':
# 初始值
x0 = np.random.uniform(10, 400, 9)
# 计算
solution = minimize(objective, x0, method='SLSQP',
bounds=bnds, constraints=cons)
x = solution.x
pI11 = x[0]
pI12 = x[1]
pI13 = x[2]
pI21 = x[3]
pI22 = x[4]
pI23 = x[5]
pI31 = x[6]
pI32 = x[7]
pI33 = x[8]
#
PG1 = 100 + pI11 + pI12 + pI13
PG2 = 100 + pI21 + pI22 + pI23
PG3 = 50 + pI31 + pI32 + pI33
PL13 = 0.5 * ((0.01 + 0.01) * (PG3 - 800) + 0.01 * PG2) / (0.01 + 0.01 + 0.01)
PL12 = ((0.01 + 0.01) * PG2 + 0.01 * (PG3 - 800)) / (0.01 + 0.01 + 0.01)
PL23 = ((0.01 + 0.01) * (PG3 - 800) + 0.01 * PG1) / (0.01 + 0.01 + 0.01)
print('PG1',PG1)
print('PG2', PG2)
print('PG3', PG3)
print('PL13',np.abs(PL13))
print('PL12',np.abs(PL12))
print("PL23",np.abs(PL23))
结果如图,本代码比书上给的方法简单得多。
更多优化算法见
python求解带约束目标优化问题(非线性规划,粒子群,遗传,差分进化)
难点:理解转移因子法求潮流
作者:电气-余登武。写作不容易,如果你觉得本文不错,请点个赞支持下。