如何优化电力系统潮流分布:最优潮流(OPF)问题

文章目录

  • [1 基本介绍](#1 基本介绍)
  • [2 公式](#2 公式)
  • [3 项目实战](#3 项目实战)
  • [4 问题特性](#4 问题特性)

1 基本介绍

最优化潮流问题,一般来说就是指一个优化问题,在特定的条件限制下需要实现最优分布潮流。从本质上讲,最优潮流是对电力系统潮流的扩展,它将描述系统稳态运行的非线性潮流方程作为必须满足的等式约束,从而将问题构建为一个大规模、非凸、非线性的约束优化问题。由于其数学上的复杂性,寻求OPF问题的全局最优解极具挑战,因此在工程实践中,大量研究集中于开发高效的数值计算方法,例如非线性规划的内点法、线性规划或二次规划的顺序逼近、以及近年来兴起的基于人工智能的求解方法,以在可接受的时间内获得满足工程精度要求的局部最优解。

2 公式

任何一个优化问题都包含三个基本要素:决策变量、目标函数和约束条件,OPF也不例外。

2.1 决策变量

  • 发电机有功出力 : P G i P_{Gi} PGi( i ∈ G i \in G i∈G,G为发电机节点集合)
  • 发电机机端电压幅值 : V i V_i Vi( i ∈ G i \in G i∈G)
  • 节点电压相角 : θ i \theta_i θi( i ∈ N i \in N i∈N,N为节点集合,通常设参考节点相角为0)

决策变量向量表示为:
x = [ ... , P G i , ... , V i , ... , θ i , ... ] T \mathbf{x} = [\ldots, P_{Gi}, \ldots, V_{i}, \ldots, \theta_{i}, \ldots]^{T} x=[...,PGi,...,Vi,...,θi,...]T

2.2 目标函数

最经典的目标是总发电成本最小化,采用二次成本函数:

min ⁡ F ( x ) = ∑ i ∈ G ( a i P G i 2 + b i P G i + c i ) \min F(\mathbf{x}) = \sum_{i \in G} (a_i P_{Gi}^2 + b_i P_{Gi} + c_i) minF(x)=i∈G∑(aiPGi2+biPGi+ci)

其中 a i > 0 a_i > 0 ai>0, b i b_i bi, c i c_i ci为发电机成本系数。

2.3 约束条件

a) 等式约束 - 潮流方程

描述电力网络物理定律,每个节点 i i i满足:

有功功率平衡
P G i − P D i = V i ∑ j = 1 N V j ( G i j cos ⁡ θ i j + B i j sin ⁡ θ i j ) P_{Gi} - P_{Di} = V_i \sum_{j=1}^{N} V_j (G_{ij} \cos \theta_{ij} + B_{ij} \sin \theta_{ij}) PGi−PDi=Vij=1∑NVj(Gijcosθij+Bijsinθij)

无功功率平衡
Q G i − Q D i = V i ∑ j = 1 N V j ( G i j sin ⁡ θ i j − B i j cos ⁡ θ i j ) Q_{Gi} - Q_{Di} = V_i \sum_{j=1}^{N} V_j (G_{ij} \sin \theta_{ij} - B_{ij} \cos \theta_{ij}) QGi−QDi=Vij=1∑NVj(Gijsinθij−Bijcosθij)

其中:

  • θ i j = θ i − θ j \theta_{ij} = \theta_i - \theta_j θij=θi−θj
  • G i j + j B i j G_{ij} + jB_{ij} Gij+jBij为节点导纳矩阵元素
  • P D i P_{Di} PDi, Q D i Q_{Di} QDi为负荷功率(已知)

b) 不等式约束 - 安全运行限制

发电机出力限制
P G i min ⁡ ≤ P G i ≤ P G i max ⁡ , ∀ i ∈ G P_{Gi}^{\min} \le P_{Gi} \le P_{Gi}^{\max}, \quad \forall i \in G PGimin≤PGi≤PGimax,∀i∈G
Q G i min ⁡ ≤ Q G i ≤ Q G i max ⁡ , ∀ i ∈ G Q_{Gi}^{\min} \le Q_{Gi} \le Q_{Gi}^{\max}, \quad \forall i \in G QGimin≤QGi≤QGimax,∀i∈G

节点电压限制
V i min ⁡ ≤ V i ≤ V i max ⁡ , ∀ i ∈ N V_{i}^{\min} \le V_{i} \le V_{i}^{\max}, \quad \forall i \in N Vimin≤Vi≤Vimax,∀i∈N

线路容量限制
∣ S l ( x ) ∣ ≤ S l max ⁡ , ∀ l ∈ L |S_l(\mathbf{x})| \le S_l^{\max}, \quad \forall l \in L ∣Sl(x)∣≤Slmax,∀l∈L

其中 S l = P l 2 + Q l 2 S_l = \sqrt{P_l^2 + Q_l^2} Sl=Pl2+Ql2 为线路视在功率。

2.4 完整OPF数学模型

minimize x F ( x ) = ∑ i ∈ G ( a i P G i 2 + b i P G i + c i ) subject to g i P ( x ) = P G i − P D i − V i ∑ j V j ( G i j cos ⁡ θ i j + B i j sin ⁡ θ i j ) = 0 g i Q ( x ) = Q G i − Q D i − V i ∑ j V j ( G i j sin ⁡ θ i j − B i j cos ⁡ θ i j ) = 0 P ‾ G i ≤ P G i ≤ P ‾ G i Q ‾ G i ≤ Q G i ≤ Q ‾ G i V ‾ i ≤ V i ≤ V ‾ i ∣ S l ( x ) ∣ ≤ S ‾ l \begin{aligned} & \underset{\mathbf{x}}{\text{minimize}} & & F(\mathbf{x}) = \sum_{i \in G} (a_i P_{Gi}^2 + b_i P_{Gi} + c_i) \\ & \text{subject to} & & g^P_i(\mathbf{x}) = P_{Gi} - P_{Di} - V_i \sum_{j} V_j (G_{ij}\cos\theta_{ij} + B_{ij}\sin\theta_{ij}) = 0 \\ & & & g^Q_i(\mathbf{x}) = Q_{Gi} - Q_{Di} - V_i \sum_{j} V_j (G_{ij}\sin\theta_{ij} - B_{ij}\cos\theta_{ij}) = 0 \\ & & & \underline{P}{Gi} \le P{Gi} \le \overline{P}{Gi} \\ & & & \underline{Q}{Gi} \le Q_{Gi} \le \overline{Q}{Gi} \\ & & & \underline{V}{i} \le V_{i} \le \overline{V}_{i} \\ & & & |S_l(\mathbf{x})| \le \overline{S}_l \end{aligned} xminimizesubject toF(x)=i∈G∑(aiPGi2+biPGi+ci)giP(x)=PGi−PDi−Vij∑Vj(Gijcosθij+Bijsinθij)=0giQ(x)=QGi−QDi−Vij∑Vj(Gijsinθij−Bijcosθij)=0PGi≤PGi≤PGiQGi≤QGi≤QGiVi≤Vi≤Vi∣Sl(x)∣≤Sl

3 项目实战

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize, BFGS
import warnings
warnings.filterwarnings('ignore')
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
class StableOPF:
    """
    数值稳定的最优潮流实现
    """
    
    def __init__(self):
        # 3节点系统
        self.n_buses = 3
        self.slack_bus = 0
        
        # 发电机参数
        self.generators = [
            {'bus': 0, 'pmin': 0.1, 'pmax': 3.0, 'a': 0.11, 'b': 5.0, 'c': 0.0},
            {'bus': 1, 'pmin': 0.1, 'pmax': 2.0, 'a': 0.085, 'b': 1.2, 'c': 0.0}
        ]
        
        # 负荷参数(进一步简化)
        self.loads = {
            1: {'pd': 0.8, 'qd': 0.3},
            2: {'pd': 0.6, 'qd': 0.2}
        }
        
        # 线路参数
        self.lines = [
            {'from': 0, 'to': 1, 'r': 0.02, 'x': 0.06, 'b': 0.0, 'rate': 2.0},
            {'from': 1, 'to': 2, 'r': 0.03, 'x': 0.08, 'b': 0.0, 'rate': 1.5},
            {'from': 2, 'to': 0, 'r': 0.04, 'x': 0.10, 'b': 0.0, 'rate': 2.5}
        ]
        
        # 电压限制
        self.v_min = 0.95
        self.v_max = 1.05
    
    def build_ybus(self):
        """构建矩阵"""
        Ybus = np.zeros((self.n_buses, self.n_buses), dtype=complex)
        
        for line in self.lines:
            i, j, r, x, b = line['from'], line['to'], line['r'], line['x'], line['b']
            z = r + 1j * x
            y = 1.0 / z
            
            Ybus[i, j] = Ybus[j, i] = -y
            Ybus[i, i] += y + 1j * b / 2
            Ybus[j, j] += y + 1j * b / 2
            
        return Ybus
    
    def calculate_power_flow(self, V, theta):
        """计算潮流方程"""
        Ybus = self.build_ybus()
        P_calc = np.zeros(self.n_buses)
        Q_calc = np.zeros(self.n_buses)
        
        for i in range(self.n_buses):
            for j in range(self.n_buses):
                theta_ij = theta[i] - theta[j]
                G, B = Ybus[i,j].real, Ybus[i,j].imag
                P_calc[i] += V[i] * V[j] * (G * np.cos(theta_ij) + B * np.sin(theta_ij))
                Q_calc[i] += V[i] * V[j] * (G * np.sin(theta_ij) - B * np.cos(theta_ij))
        
        return P_calc, Q_calc
    
    def parse_variables(self, x):
        """解析变量"""
        # x = [V1, V2, theta1, theta2, Pg0, Pg1]
        V = np.array([1.0, x[0], x[1]])  # 平衡节点V0=1.0
        theta = np.array([0.0, x[2], x[3]])  # 平衡节点theta0=0.0
        Pg = np.array([x[4], x[5], 0.0])  # 节点2无发电机
        
        return Pg, V, theta
    
    def objective(self, x):
        """目标函数"""
        Pg, _, _ = self.parse_variables(x)
        cost = 0.0
        for gen in self.generators:
            bus, a, b, c = gen['bus'], gen['a'], gen['b'], gen['c']
            cost += a * Pg[bus]**2 + b * Pg[bus] + c
        return cost
    
    def power_balance(self, x):
        """功率平衡约束(简化版)"""
        Pg, V, theta = self.parse_variables(x)
        P_calc, Q_calc = self.calculate_power_flow(V, theta)
        
        # 负荷
        Pd = np.zeros(self.n_buses)
        Qd = np.zeros(self.n_buses)
        for bus, load in self.loads.items():
            Pd[bus] = load['pd']
            Qd[bus] = load['qd']
        
        constraints = []
        
        # 有功平衡(所有节点)
        for i in range(self.n_buses):
            constraints.append(Pg[i] - Pd[i] - P_calc[i])
        
        # 无功平衡(PQ节点)
        for i in [1, 2]:  # PQ节点
            constraints.append(-Qd[i] - Q_calc[i])
        
        return np.array(constraints)
    
    def constraints_ineq(self, x):
        """不等式约束(简化版)"""
        Pg, V, theta = self.parse_variables(x)
        constraints = []
        
        # 发电机限制
        for gen in self.generators:
            bus, pmin, pmax = gen['bus'], gen['pmin'], gen['pmax']
            constraints.extend([Pg[bus] - pmin, pmax - Pg[bus]])
        
        # 电压限制
        for i in range(self.n_buses):
            constraints.extend([V[i] - self.v_min, self.v_max - V[i]])
        
        return np.array(constraints)
    
    def solve_stable(self):
        """稳定的优化求解"""
        # 更好的初始猜测
        total_load = sum(load['pd'] for load in self.loads.values())
        x0 = np.array([1.0, 1.0, 0.0, 0.0, total_load*0.6, total_load*0.4])
        
        bounds = [
            (0.98, 1.02), (0.98, 1.02),    # V1, V2
            (-0.2, 0.2), (-0.2, 0.2),      # theta1, theta2  
            (0.1, 3.0), (0.1, 2.0)         # Pg0, Pg1
        ]
        
        constraints = [
            {'type': 'eq', 'fun': self.power_balance},
            {'type': 'ineq', 'fun': self.constraints_ineq}
        ]
        
        # 使用更稳健的优化方法
        result = minimize(
            self.objective, x0,
            method='trust-constr',  # 更稳健的方法
            bounds=bounds,
            constraints=constraints,
            options={'verbose': 1, 'gtol': 1e-6, 'maxiter': 200}
        )
        
        return result
    
    def print_simple_results(self, result):
        """简化结果输出"""
        print("="*60)
        print("简化OPF结果")
        print("="*60)
        
        if hasattr(result, 'x'):
            x_opt = result.x
            Pg, V, theta = self.parse_variables(x_opt)
            
            print(f"状态: {'成功' if result.success else '优化困难'}")
            print(f"成本: {result.fun:.4f} $/h")
            print(f"信息: {result.message}")
            print()
            
            # 节点结果
            Pd = np.zeros(self.n_buses)
            for bus, load in self.loads.items():
                Pd[bus] = load['pd']
            
            print("节点结果:")
            for i in range(self.n_buses):
                print(f"节点{i}: Pg={Pg[i]:.3f}MW, Pd={Pd[i]:.3f}MW, "
                      f"V={V[i]:.3f}pu, θ={np.degrees(theta[i]):.2f}°")
            
            # 功率平衡
            total_pg = sum(Pg)
            total_pd = sum(Pd)
            loss = total_pg - total_pd
            
            print(f"\n功率平衡:")
            print(f"发电: {total_pg:.3f}MW, 负荷: {total_pd:.3f}MW, "
                  f"网损: {loss:.3f}MW ({loss/total_pg*100:.1f}%)")
            
            # 约束检查
            power_eq = self.power_balance(x_opt)
            ineq = self.constraints_ineq(x_opt)
            
            print(f"\n约束检查:")
            print(f"功率平衡误差: {max(abs(power_eq)):.6f}")
            print(f"不等式约束裕度: {min(ineq):.6f}")
            
            return True
        return False

def main():
    """主函数 - 简化版本"""
    print("创建简化OPF实例...")
    opf = StableOPF()
    
    print("开始优化求解...")
    result = opf.solve_stable()
    
    print("\n" + "="*60)
    if opf.print_simple_results(result):
        print("\n优化完成!")
        
        # 简单可视化
        x_opt = result.x
        Pg, V, theta = opf.parse_variables(x_opt)
        
        fig, axes = plt.subplots(2, 2, figsize=(10, 8))
        
        # 电压分布
        axes[0,0].bar(range(3), V, color='lightblue', alpha=0.7)
        axes[0,0].set_title('节点电压')
        axes[0,0].set_ylabel('电压 (pu)')
        
        # 发电机出力
        gen_power = [Pg[0], Pg[1]]
        axes[0,1].bar([0, 1], gen_power, color='lightgreen', alpha=0.7)
        axes[0,1].set_title('发电机出力')
        axes[0,1].set_ylabel('功率 (MW)')
        
        # 相角分布
        angles_deg = np.degrees(theta)
        axes[1,0].bar(range(3), angles_deg, color='lightcoral', alpha=0.7)
        axes[1,0].set_title('电压相角')
        axes[1,0].set_ylabel('角度 (°)')
        
        # 成本分布
        costs = []
        for gen in opf.generators:
            bus, a, b, c = gen['bus'], gen['a'], gen['b'], gen['c']
            costs.append(a * Pg[bus]**2 + b * Pg[bus] + c)
        
        axes[1,1].bar([0, 1], costs, color='gold', alpha=0.7)
        axes[1,1].set_title('发电成本')
        axes[1,1].set_ylabel('成本 ($/h)')
        
        plt.tight_layout()
        plt.show()
    else:
        print("优化失败!")

if __name__ == "__main__":
    main()

4 问题特性

该模型是典型的大规模、非线性、非凸优化问题:

  • 大规模:实际电网节点数众多,变量和约束数量庞大
  • 非线性:潮流方程包含电压乘积和三角函数项
  • 非凸:可行域非凸,存在多个局部最优解

这一数学模型是OPF理论研究与算法开发的基础。

相关推荐
DanCheng-studio7 小时前
网安毕业设计简单的方向答疑
python·毕业设计·毕设
轻抚酸~8 小时前
KNN(K近邻算法)-python实现
python·算法·近邻算法
独行soc9 小时前
2025年渗透测试面试题总结-264(题目+回答)
网络·python·安全·web安全·网络安全·渗透测试·安全狮
汤姆yu10 小时前
基于python的外卖配送及数据分析系统
开发语言·python·外卖分析
如何原谅奋力过但无声10 小时前
TensorFlow 1.x常用函数总结(持续更新)
人工智能·python·tensorflow
翔云 OCR API10 小时前
人脸识别API开发者对接代码示例
开发语言·人工智能·python·计算机视觉·ocr
AndrewHZ11 小时前
【图像处理基石】如何在图像中提取出基本形状,比如圆形,椭圆,方形等等?
图像处理·python·算法·计算机视觉·cv·形状提取
温轻舟12 小时前
Python自动办公工具05-Word表中相同内容的单元格自动合并
开发语言·python·word·自动化办公·温轻舟
习习.y13 小时前
python笔记梳理以及一些题目整理
开发语言·笔记·python