
做电力系统分析的人十有八九都被这个问题卡过分布式光伏和风电装机一上来负荷今天和明天不一样馈线潮流的波动幅度越来越大可你手上能用的确定性潮流程序却在某个时刻怎么调都不收敛。这时候你就知道单点运行的潮流计算已经撑不住整个运行分析的需求了概率潮流计算Probabilistic Power Flow的价值就出来了。概率潮流计算的核心任务是在已知负荷、电源出力的概率分布之后求出节点电压、支路潮流的概率分布从而评估系统运行的风险比如电压越限概率、线路过载概率。它不是某一条运行曲线而是一整套“系统运行状态的概率画像”。我这次在IEEE34节点系统上用半不变量法Cumulant Method在Matlab里完整跑通了一遍整个过程踩了不少坑也把很多原理性的细节重新捋了一遍。这篇博文就把整套思路、数学原理、代码实现和排坑记录都整理出来给正要入坑概率潮流的朋友们做一个可复现的参考。这篇内容适合三类人看一是正在做毕业设计或课程项目、需要快速实现概率潮流算法的同学二是做配电网规划或运行分析、想评估新能源出力不确定性影响的工程师三是对解析法概率潮流感兴趣、想搞明白半不变量到底怎么用在实际系统里的研究者。我会把从原理到代码的每个环节都讲透尤其是那些论文里不会明说、但实操里躲不开的细节。1. 概率潮流到底是什么——从单点计算到概率画像1.1 确定性潮流解决不了的问题传统的确定性潮流输入是一组确定的负荷和发电数据某个时刻的负荷有功无功、发电机的机端电压输出是这个时刻的节点电压和支路潮流。它回答的问题是“如果系统处于这个运行状态各部分电气量是多少”。但实际系统从来没有“静止”过负荷在变光伏出力在变风电出力也在变尤其分布式电源大规模接入之后馈线级别的功率波动幅度可以达到装机容量的20%甚至更高。单靠确定性潮流做运行分析通常只能靠“选取最恶劣工况”或“典型工况”来兜底但问题在于最恶劣工况未必真的会同时发生典型工况又代表不了系统的整体风险水平。比如某个节点的电压90%的时候都在正常范围内只有5%的概率越上限这个5%的越限概率在确定性框架里是算不出来的。概率潮流要解决的就是这个事让输入变量按概率分布随机波动求输出电气量的概率分布以及越限概率、期望值、分位数这些统计指标。1.2 三类主流算法路线对比概率潮流的算法路线大体分三类模拟法、近似法、解析法。蒙特卡洛模拟Monte Carlo Simulation, MCS是最直观的方法从输入随机变量的概率分布中抽样每一组样本做一次确定性潮流计算重复成千上万次之后对输出结果做统计。优点是原理简单、几乎不受系统非线性的影响结果可以作为基准缺点是计算量非常大IEEE34节点这种规模算5000次潮流可能只要几十秒但放到几百节点的大系统里每次潮流都要迭代求解成本会迅速累积。点估计法Point Estimate Method, PEM是典型的近似法只在输入变量的少数几个代表性取值处做确定性潮流然后加权组合估计输出变量的矩。PEM不用知道输入随机变量的完整分布只需要前几阶矩计算量小但精度受限于取点个数尾部信息丢失明显。半不变量法属于解析法也是我这篇博文的主角。它不走抽样路线而是通过数学变换直接求出输出变量的半不变量也就是累积量再用级数展开恢复概率密度函数和累积分布函数。在输入变量独立或可解耦的前提下半不变量法计算速度极快精度在中低阶矩范围内可以和蒙特卡洛打到同一水平。这几种方法对比下来半不变量法赢在“快”和“解析”输在“假设多”和“非线性误差”所以工程上做在线评估、方案对比的时候非常好用。1.3 半不变量法在工程场景里的定位实际工程项目里我比较多的用法是这样先用半不变量法做大量场景的快速扫描比如不同光伏渗透率、不同负荷水平下的电压越限风险和支路过载风险找到问题最集中的几个运行场景再针对这些场景用蒙特卡洛做精细化分析。两套方法结合既保证效率又保证精度。这种“粗扫描精分析”的打法在半不变量法出现之前很难落地。因为之前的解析法要么推导复杂要么对网络拓扑限制太多很难适配真实配电系统的三相不平衡和辐射状结构。半不变量法配合灵敏度矩阵把非线性的潮流方程在运行点附近做线性化处理相当于把“复杂系统随机分析”降维成“线性系统随机分析”数学上的实现难度一下子降低了很多。这也是为什么近些年配电网概率潮流研究里半不变量法的出镜率一直很高。2. 半不变量法原理拆解核心数学工具2.1 矩与半不变量两种等价的统计描述讲到半不变量就绕不开矩论。矩大家比较熟一阶原点矩就是期望二阶中心矩就是方差。但半不变量Cumulant在国内教材里讲得不多初次接触容易懵。半不变量在概率论里也叫累积量本质是特征函数的对数展开系数。随机变量X的特征函数定义为 φ(t)E[e^{itX}]对其取自然对数K(t)ln[φ(t)]在t0处做泰勒展开展开系数就是各阶半不变量κ1,κ2,κ3,...。这个定义对不熟悉特征函数的读者可能有点抽象但不要紧你只需要记住两条性质就足够工程使用了。第一条性质是半不变量和各阶矩之间有固定的转换关系。前四阶的转换公式如下κ1 m1κ2 m2 - m1²κ3 m3 - 3m1·m2 2m1³κ4 m4 - 4m1·m3 - 3m2² 12m1²·m2 - 6m1⁴其中m1到m4分别是原点矩m1E[X]m2E[X²]m3E[X³]m4E[X⁴]。对于常见分布半不变量可以直接查表不需要每次都从矩去转换。比如正态分布N(μ,σ²)的前四阶半不变量就是κ1μκ2σ²κ30κ40。均匀分布、Beta分布、离散分布也都有现成公式写代码的时候可以直接调用。第二条性质是独立随机变量之和的半不变量等于各分量半不变量之和。这是半不变量法最大的杀器K(t)ln(φ(t))本身是对数而独立变量之和的特征函数是各特征函数之积取对数后就变成了求和。也就是说节点注入功率由20个负荷和10个光伏电源共同决定正态、Beta、离散分布混在一起只要求出每个输入变量的各阶半不变量加起来就得到总输入的各阶半不变量不需要做卷积分不用做数值积分把复杂的卷积运算降维成了简单的代数求和。2.2 线性变换下的半不变量传递除了“独立变量之和”这条性质还有一条性质在潮流计算里同样关键线性变换下的半不变量传递规则。假设随机变量X的前四阶半不变量已知做线性变换YaXb那么Y的各阶半不变量为κ_Y,1 a·κ_X,1 bκ_Y,2 a²·κ_X,2κ_Y,3 a³·κ_X,3κ_Y,4 a⁴·κ_X,4也就是说除了均值项受线性加常数影响之外二阶以上的半不变量只体现在对a的幂次缩放。这一性质意味着一旦我们建立了“输入随机扰动→输出电气量变化”的线性映射关系就能通过简单的幂次运算把输入半不变量传递给输出变量整个计算链条没有任何抽样过程全部是解析运算。这里需要提醒一句线性变换规则是精确的但潮流方程本身是非线性的。我们做的事情本质上是在运行点附近对潮流方程做一阶泰勒展开忽略二阶及以上项。这个线性化近似的精度直接决定了半不变量法最终结果的精度。对于电压幅值这种在正常工况下偏离基准运行点不太远的量线性化精度通常足够对于重负荷线路的末端电压、或者接近电压崩溃临界点的工况线性化误差就会被放大这也是后面排查问题时需要重点关注的环节。2.3 潮流方程的线性化与灵敏度矩阵下面把潮流方程和半不变量法对接起来。极坐标形式的节点功率方程可以写成P_i V_i·ΣV_j(G_ij·cosθ_ij B_ij·sinθ_ij)Q_i V_i·ΣV_j(G_ij·sinθ_ij - B_ij·cosθ_ij)在基准运行点(θ0, V0)处做一阶泰勒展开可以得到矩阵形式的线性化方程[ΔP; ΔQ] J·[Δθ; ΔV]其中J就是牛顿-拉夫逊法里的雅可比矩阵。如果我们在基准运行点处已经完成了一次确定性潮流计算雅可比矩阵自然是现成的。对等式两边求逆就得到[Δθ; ΔV] J⁻¹·[ΔP; ΔQ]这个J⁻¹就是节点电压对注入功率扰动的灵敏度矩阵。换句话讲在正常运行点附近如果某个节点的注入功率增加了ΔP节点电压相角的变化量可以近似用J⁻¹对应位置的元素乘以ΔP来估计。支路潮流的处理要稍微绕一点。支路潮流本身是节点电压V和相角θ的非线性函数但我们可以在基准运行点处先对支路潮流求偏导得到支路潮流对节点电压相角的雅可比矩阵再和J⁻¹相乘最终形成支路潮流对节点注入功率的灵敏度矩阵。这个推导过程和确定性潮流里PQ解耦法的思路一致具体实现时可以直接用数值差分法求支路灵敏度矩阵避免手推偏导公式出错。有了这两个核心灵敏度矩阵整个线性化链条就完整了节点注入功率随机变量→灵敏度矩阵→节点电压和支路潮流输出随机变量。后面对应关系的核心是输出变量的半不变量可以借助2.2小节的线性变换规则由输入变量的半不变量直接算出来。2.4 Gram-Charlier级数恢复概率分布半不变量本身只是分布的数字特征不是密度函数本身。要画出概率密度曲线、计算越限概率还需要用级数展开的方法把概率密度函数恢复出来。工程上最常用的是Gram-Charlier级数。它的思路是以标准正态分布为基准在正态密度函数上叠加修正项来逼近真实分布。把输出随机变量标准化z (Y - μ) / σ则概率密度函数的Gram-Charlier展开为f(z) φ(z)·[1 (γ1/6)·H3(z) (γ2/24)·H4(z)]其中φ(z)是标准正态密度函数γ1和γ2分别是偏度系数和峰度系数由三阶、四阶半不变量计算得到γ1 κ3 / σ³γ2 κ4 / σ⁴H3(z)和H4(z)是Hermite多项式具体形式为H3(z) z³ - 3zH4(z) z⁴ - 6z² 3累积分布函数同样可以展开F(z) Φ(z) φ(z)·[(γ1/6)·H2(z) (γ2/24)·H3(z)]这里Φ(z)是标准正态累积分布函数H2(z) z² - 1。截断到四阶已经能捕捉大多数配电网概率潮流场景下的分布特征。如果随机变量的分布偏度很大可以考虑继续展开到六阶甚至八阶但要注意高阶半不变量本身对输入分布参数比较敏感偏移量稍大时数值稳定性会变差。这个在后面排查问题里会遇到。3. IEEE34节点系统与Matlab实现要点3.1 IEEE34节点算例的基本特性IEEE34节点系统是一个真实存在的中压配电馈线模型基准电压24.9kV在IEEE PES配电系统测试算例里属于经典中的经典。它有别于IEEE标准节点系统的明显特点大多数是辐射状结构、线路总长度很长、包含单相、两相、三相线路段、含有调压器和变压器负荷分布在很长的馈线沿线。这套特性对概率潮流算法提出了相当苛刻的测试条件。辐射状结构意味着前推回代法收敛非常快但和半不变量法结合时通常还是基于牛顿-拉夫逊雅可比矩阵来构造灵敏度因为前推回代法本身不直接给出雅可比矩阵后面求灵敏度就得多花一番功夫。线路长短不一导致各节点电压偏离基准值的程度差异很大远端节点电压可能已经到了0.90p.u.以下离正常运行范围下限很近这正好用来检验概率潮流计算出的电压越限概率是否符合实际。在Matlab里搭建这套系统时数据来源有两个常用途径一个是IEEE PES官网上直接下载的标准数据文件另一个是用Matpower格式转换。我用的做法是在Matpower的case34数据基础上修改扩展把分布式电源接入点加在馈线末端附近人为制造电压越限场景这样对比起来结果更明显。3.2 代码架构与模块划分我实现的代码整体按功能划分成五个模块每个模块单独一个文件这样方便调试和复用case34.m定义IEEE34节点的网络参数包括线路阻抗、负荷数据、发电机数据。run_pf.m确定性潮流求解函数采用牛顿-拉夫逊法输出节点电压、相角、支路潮流以及雅可比矩阵。sensitivity.m根据雅可比矩阵和支路潮流偏导计算电压和支路潮流的灵敏度矩阵。cumulant_ppf.m概率潮流主函数负责构建输入随机变量的概率模型计算半不变量通过灵敏度矩阵传递再调用Gram-Charlier级数输出结果。run_mc.m蒙特卡洛模拟基准程序用于验证半不变量法结果。模块之间的调用关系非常清晰先run_pf求解基准运行点顺便拿到雅可比矩阵再把雅可比矩阵传给sensitivity生成灵敏度矩阵然后cumulant_ppf里的输入随机变量半不变量乘以灵敏度矩阵得到输出半不变量最后用Gram-Charlier画曲线、算越限概率。run_mc独立存在作为“标准答案”做交叉验证。3.3 灵敏矩阵的数值实现这一节我踩过的坑最多值得单独说说。理论上灵敏度矩阵就是雅可比矩阵的逆但你直接把Matlab的inv(J)算出来大概率会在某些节点类型上出错。原因在于潮流方程里边平衡节点的电压幅值和相角是已知的PV节点的无功注入方程是缺席的这些已知量对应的行列在雅可比矩阵里本身没有对应的方程。正确的处理方法是先做“矩阵约简”。以IEEE34节点为例系统1号节点是平衡节点假定从34个节点里去掉2个PV节点和1个平衡节点那么实际参与迭代的未知量只有31个电压幅值和31个相角雅可比矩阵的维度是62×62。但节点注入功率扰动ΔP和ΔQ只定义在PQ节点上你在计算灵敏度矩阵时需要把J矩阵中与平衡节点、PV节点对应的行列剔掉只保留PQ节点对应的子矩阵求逆之后再做扩展。我第一次实现时只顾着整体求逆结果电压灵敏度矩阵里出现了大量非零元素运行结果和蒙特卡洛对不上。后来把PV节点和平衡节点的行删掉只对PQ节点子矩阵求逆再按原节点编号映射回去结果立刻就对上了。相似的问题在选择支路潮流灵敏度矩阵时也可能出现因为支路潮流对相角的偏导也得分清哪些节点是独立的、哪些是已知的。3.4 半不变量与Gram-Charlier的代码实现输入侧的处理我以三种典型随机变量为例常规负荷用正态分布N(0.05, 0.01²)的有功注入波动无功按功率因数联动光伏出力用Beta分布形状参数取a2, b5按容量标幺化到[0.1, 0.9]区间还有一个离散随机变量模拟某个大用户的投切状态取值0或1概率各50%。三种分布的前四阶半不变量可以直接用公式计算也可以从蒙特卡洛样本估算后代入验证阶段用样本估算更稳妥。核心代码如下% 计算输入随机变量的半不变量以正态分布为例 function kappa cum_normal(mu, sigma) kappa zeros(1, 4); kappa(1) mu; kappa(2) sigma^2; % 三阶、四阶半不变量为0 end % 线性变换传递半不变量 function kappa_out linear_trans(kappa_in, a, b) kappa_out zeros(1, 4); kappa_out(1) a * kappa_in(1) b; kappa_out(2) a^2 * kappa_in(2); kappa_out(3) a^3 * kappa_in(3); kappa_out(4) a^4 * kappa_in(4); end % Gram-Charlier级数概率密度 function [x, fx] gram_charlier(mu, sigma, kappa) x linspace(mu - 4*sigma, mu 4*sigma, 500); z (x - mu) / sigma; gamma1 kappa(3) / sigma^3; gamma2 kappa(4) / sigma^4; fx normpdf(z) .* (1 gamma1/6 .* (z.^3 - 3*z) gamma2/24 .* (z.^4 - 6*z.^2 3)); fx fx ./ sigma; end这里有一个容易忽略的细节如果直接对z的公式乘标准差x和fx的尺度会对不上最终概率密度曲线的纵轴单位会出错。所以我先把x全部标准化为z再在最后统一除以σ恢复尺度。这个细节我在最初版本里就漏了画出来的密度曲线看起来形状对但积分面积不是1检查了很久才定位到是尺度变换写错了。支路潮流的概率密度曲线绘制方法一致只不过输出变量从节点电压换成支路有功和无功。因为支路潮流的灵敏度矩阵维度和节点电压不一样注意在传递半不变量时保持矩阵维度匹配即可。3.5 蒙特卡洛验证的配置要点为了验证半不变量法的精度我在IEEE34节点系统上跑了10000次蒙特卡洛模拟。每次模拟生成一组输入随机变量样本调用run_pf计算一组节点电压和支路潮流最后把10000组结果做统计直方图和经验CDF与半不变量法的解析结果叠加对比。在Matlab里做蒙特卡洛模拟时新手最容易犯的错误是循环体内重复加载网络数据。run_pf每次执行都从case34重新读取数据10000次下来光数据解析就浪费了不少时间。正确的做法是在循环外先把系统数据和稀疏因子结构提取好只更新注入功率向量这样单次潮流计算的平均耗时能压到几十毫秒级别10000次运行也就两三分钟。我用的采样代码如下% 生成输入随机变量样本 N 10000; load_sample randn(N, 1) * 0.01 0.05; % 负荷有功波动 beta_sample betarnd(2, 5, N, 1); % 光伏出力样本 discrete_sample (rand(N, 1) 0.5); % 大用户投切 for k 1:N % 更新注入功率并调用潮流 Sbus base_Sbus build_delta(load_sample(k), beta_sample(k), discrete_sample(k)); [V(k,:), ~] run_pf_once(Sbus); end注意每次计算的基准运行点必须保持一致不能中途替换网络参数。如果每次抽样都重新初始化V0计算结果方差会明显偏大。4. 常见问题与排查技巧实录4.1 雅可比矩阵奇异或不收敛半不变量法的第一步是跑确定性潮流求基准运行点这个环节出问题后面一切免谈。我在IEEE34节点上遇到的最典型现象是把光伏接入馈线末端后末端节点电压被抬高到1.05p.u.以上牛顿-拉夫逊法在迭代初期出现振荡雅可比矩阵接近奇异程序直接报错。排查思路是这样的先检查潮流初值把平衡节点以外的节点电压初值统一设成1.0p.u.、相角设成0看是否收敛如果不收敛再检查负荷数据是否有量纲错误。IEEE34节点原始数据里的负荷单位是kW/kVarMatpower默认单位是p.u.转换时基准功率取100kVA还是1MVA结果的差别非常大。我最终把基准功率定在1MVA换算之后迭代很快就收敛了。如果初值正确但仍然奇异常见原因是运行点太靠近PV曲线的鼻尖点即接近静稳极限。对这种工况半不变量法的线性化近似本身就会失真建议要么调整运行点要么改用其它算法。工程上概率潮流本来就要求系统在接近正常运行范围内波动强行在临界点附近做概率分析没有现实意义。4.2 Gram-Charlier级数出现负概率或振荡使用Gram-Charlier展开时概率密度曲线出现轻微负值不是什么罕见事。原因在于级数展开本质上是无穷级数的截断截断到四阶后真实分布和正态近似之间的偏差会以多项式项的形式表现出来而这些多项式项在某些尾巴位置可能把密度函数顶成负值。解决思路有两个。第一检查输入变量是否真的“长得像正态”如果输入分布偏度过大建议把展开阶数提高比如包含H5和H6项这样对偏态的修正能力更强。第二检查三阶和四阶半不变量的计算是否准确尤其是离散随机变量和Beta分布混合时高阶矩对抽样噪声非常敏感。我自己遇到过一次结果莫名其妙出现负概率排查后发现是Beta分布半不变量的四阶矩公式里少乘了一个系数。如果调整之后仍有小范围负值不用过于纠结因为工程上真正关心的是累积分布函数的尾部也就是越限概率负密度对CDF的影响通常很小。但如果你要拿概率密度图去汇报负值区域会显得很难看可以做一个非负修正把负值强制归零后重新归一化曲线看起来会舒服很多精度损失在工程可接受范围内。4.3 输入变量相关性对结果的影响半不变量法最关键的假设之一是输入随机变量相互独立。但实际配电网里同一片区域的光伏出力有很强的正相关性相邻节点负荷之间也受气温、时段影响呈正相关。一旦这个假设失效半不变量法会系统性低估输出变量的方差导致越限概率偏小。针对配电网这种场景工程上的处理办法是先做输入变量的去相关化把相关变量通过线性变换转成独立变量再应用半不变量法。比如对多个光伏电站的出力采用主成分分析或Cholesky分解把相关矩阵对角化后再做半不变量传递可以部分修正相关性带来的误差。不过这个操作会引入额外的近似在处理强非线性变量时误差会重新放大建议还是结合蒙特卡洛验证一下。我在IEEE34节点上做了一组对照实验把两个相邻节点的负荷加上0.6的相关系数用半不变量法算出来的电压标准差比蒙特卡洛基准低了17%电压越上限概率低了将近一半。这个差距足以影响风险评估结论大家在用半不变量法做工程报告时一定要先做输入变量的相关性检验别默认“近似独立”就万事大吉。4.4 计算速度对比与精度评估在我的Matlab实现中半不变量法从基准潮流到画出所有节点的电压概率密度曲线耗时在0.5秒以内不包含蒙特卡洛基准的时间而10000次蒙特卡洛模拟大约需要3分钟左右。这套系统还只是34节点如果把规模扩大到几百个节点的配电网或者输电网半不变量法的速度优势会指数级放大因为它本质上只做了一次确定性潮流和几次矩阵运算。精度方面以蒙特卡洛10000次为基准我在IEEE34节点上统计了所有PQ节点电压幅值的均值误差和标准差误差。结果是均值误差全部在0.0003p.u.以内标准差误差在0.002p.u.以内电压越限概率的误差在1个百分点以内。对于工程评估来说这个精度完全够用。对于支路潮流末端重载线路的有功功率概率分布比电压分布偏离正态更明显半不变量法的误差也会相应增大。我在第20号支路上计算的有功功率标准差误差约为3%偏度系数能对得上蒙特卡洛结果的整体趋势但尾部细节略有偏差。这个结果和半不变量法“用前四阶矩近似分布”的本质是一致的——细节部位总归是近似。我今天这份实现里手上测试过的场景还包括把光伏渗透率从0%逐步加到80%观察末端节点电压越上限概率的变化曲线。半不变量法在这一系列场景中都能保持几百毫秒级别的计算速度这种批量场景扫描能力是蒙特卡洛很难做到的。如果你后续要做光伏容量规划、储能选址或者运行风险评估这套代码框架可以直接拿过去改输入分布和灵敏度矩阵扩展性还是相当不错的。具体怎么接你自己的数据我建议先从两个节点的小系统开始验证代码逻辑再换到IEEE34节点全系统这样排查问题会容易很多。