做配电网规划的朋友应该都有体会,这两年“屋顶光伏一多,电压不好算了”这句话出现的频率越来越高。以前算潮流,给定一个负荷曲线、给定发电机出力,跑一遍牛拉法或者前推回代,出来一组电压、功率,完事。但现在分布式电源大规模接入,光伏出力跟着光照走,风电出力跟着风速变,负荷本身也在波动,确定性潮流的结果只能代表某一个瞬间,回答不了“这个月电压越限的概率有多大”“这条线路会不会在某个时刻过载”这类问题。这时候就得请出概率潮流,而蒙特卡洛方法,就是实现概率潮流最直接、最不容易出错的一条路。
这篇文章就用一个经典的IEEE 33节点配电网系统,完整带大家走一遍蒙特卡洛概率潮流的建模、抽样、求解、统计全过程。内容覆盖分布式电源随机建模、前推回代潮流、电压和网损的概率指标提取、渗透率场景分析,以及实际跑仿真时容易踩的坑。适合刚接触概率潮流的电气研究生、配网规划工程师,还有想在项目里落地不确定性分析的同行参考。
1. 为什么分布式电源让潮流计算“变了天”
1.1 传统确定性潮流的局限
传统的配电网潮流计算,本质上是在“给定一个确定的工况”下求解网络状态。负荷取峰值、取平均或者取典型日某个时刻的值,分布式电源如果有,按额定容量或者某个固定功率出力处理,然后解一组非线性方程,得到各节点电压幅值、相角,以及支路功率和网损。这个流程本身没问题,工程上用了很多年,但它本质上是“单快照”分析。
单快照分析的短板在接入分布式电源之后暴露得非常明显。光伏出力一天之内从零爬到额定值再掉回零,多云天气下分钟级波动幅度可能超过50%;风电更是随风速、风向变化,有时候十几分钟就能从满发跌到零。负荷也有随机波动,尤其居民区晚高峰和工业负荷的波动特性完全不同。这些不确定性叠加在一起,你如果只用一组确定值去算,得到的电压可能刚好在高渗透率+轻负荷场景下越限,但确定性计算却显示“一切正常”。
所以现在做配电网评估,光看“算出来的电压是多少”不够,还要回答“电压落在某个区间的概率是多少”。这就要把输入从确定值换成概率分布,把输出从一组确定值变成统计特征,比如期望、标准差、5%分位数、95%分位数、越限概率。这就引出了概率潮流。
1.2 分布式电源的不确定性来源
既然要算概率潮流,首先得知道不确定性来自哪里、怎么用数学描述。我习惯把不确定性源分成三类:电源侧、负荷侧、网络侧。网络侧主要指拓扑变化和量测误差,在规划仿真里一般先忽略,重点放在前两类。
电源侧里,光伏出力主要受光照辐照度影响,工程上常用Beta分布来拟合归一化后的辐照度,再通过线性关系映射到出力。也就是说,光伏出力可以写成:
P_pv = P_rated * Beta_pdf(α, β)
其中P_rated是额定容量,α和β是Beta分布的形状参数,需要根据当地历史辐照数据拟合。如果偷懒,也可以直接用带截断的正态分布近似,但实测下来Beta分布在辐照接近零和接近峰值时更贴合实际。
风电出力稍微绕一点,一般先对风速做统计建模,风速通常用Weibull分布描述,再通过风机的功率特性曲线把风速转换成出力。简化功率曲线可以写成:
v < v_cutin 或 v > v_cutout 时,P = 0 v_cutin ≤ v ≤ v_rated 时,P = P_rated * (v - v_cutin) / (v_rated - v_cutin) v_rated < v ≤ v_cutout 时,P = P_rated
负荷侧的不确定性相对好处理,大多数情况下用正态分布描述节点有功和无功的波动,期望取基准负荷值,标准差取基准值的5%到10%,但要注意截断,不能让抽样抽到负负荷。后面我会专门讲这个坑。
2. 蒙特卡洛方法的核心思路与适用性
2.1 蒙特卡洛方法的基本原理
蒙特卡洛方法说白了就是“大量抽样、逐个计算、统计归纳”。你把每个不确定性输入都看成一个随机变量,按照各自的概率分布抽一组样本,比如今天的光照、风速、负荷都抽一组具体数值,然后跑一次确定性潮流,记下节点电压、支路功率。一次抽样只代表一种可能的场景,但如果你抽一万次、十万次,这些结果组合起来就能还原出系统状态的大致概率分布。
打个比方,你想知道一枚硬币正面朝上的概率,不用去推动力学方程,只要抛一万次,数一数正面多少次,概率自然就出来了。抛的次数越多,结果越接近真实值。蒙特卡洛概率潮流干的就是这件事,只不过每次“抛硬币”变成了跑一次确定性潮流。
这个方法的魅力在于它几乎不做任何数学上的简化。光伏可以用Beta分布,风速可以用Weibull分布,负荷可以是任意形态的经验分布,节点之间的相关性也可以通过改进抽样方式引入。潮流方程本身就是精确的非线性模型,不需要线性化,不需要假设输入输出满足什么特殊关系。对于配电网这种规模不太大、但非线性特征明显的系统,这反而是最稳的路子。
2.2 为什么选蒙特卡洛而不是解析法或点估计法
做概率潮流不止蒙特卡洛一种方法,还有解析法和点估计法,我做这个项目时专门对比过它们的取舍。
解析法通常需要把潮流方程在某个工作点线性化,然后基于随机变量的数字特征推导状态变量的期望和方差。问题在于线性化误差在强非线性场景下会被放大,比如电压接近越限边界时,解析法算出来的越限概率往往和蒙特卡洛差得比较多。点估计法是用少量确定性采样点(比如每个输入变量取均值附近的两个点)去逼近输出变量的矩,速度确实快,但得到的只是期望、方差这些数字特征,拿不到完整的分布曲线,更拿不到越限概率这种尾部指标。
蒙特卡洛恰好相反,它思路耿直、实现简单,而且能给出完整的概率分布。代价就是计算量大,需要用成千上万次确定性潮流做支撑。不过对于33节点这种规模的配电网,单次前推回代潮流计算只要几毫秒,一万次抽样也就是几十秒的量级,完全在可接受范围内。如果换成几百节点的大规模网络,可以配合拉丁超立方抽样、并行计算这些加速手段,后面我会展开说。
2.3 抽样次数与收敛性分析
用蒙特卡洛方法,第一个问题永远是“抽多少次才够”。这里有一个很经典的理论结论:蒙特卡洛估计的误差和抽样次数N的关系是1/sqrt(N),也就是说,想让精度提高一倍,样本量要变成四倍。但实际工程里我们不会去严格推置信区间,更实用的做法是看均值收敛曲线。
我通常的做法是,每隔一定抽样数就记录一次当前所有节点电压期望的平均值,画一条收敛曲线。如果曲线在某个N之后开始平稳,不再有大的上下漂移,说明样本量基本够了。对于33节点配电网,带分布式电源的场景,实用经验是简单随机抽样5000到10000次已经能给出比较稳定的期望和概率估计。如果关心的是极端尾部概率,比如千分之一级别的越限事件,那就需要更多样本,这时候就要考虑用拉丁超立方抽样或重要性抽样来提升效率。
3. IEEE 33节点配电网标准算例搭建
3.1 33节点系统的结构与参数特征
IEEE 33节点系统是配电网研究里最常用的标准算例,它是一个辐射状配电网络,基准电压12.66kV,包含33个节点、32条支路,首端节点0是变电站母线,作为平衡节点处理。系统总有功负荷大约3.715MW,无功负荷大约2.3Mvar,整体呈放射状,越靠近末端电压越低,尤其是节点18这种长馈线末端,在无电源接入时电压往往已经接近运行下限。
标准参数在网上很容易找到,支路数据一般是这样一份表格,包含支路编号、首端节点、末端节点、电阻(欧姆)、电抗(欧姆)、该支路末端节点的有功负荷(kW)和无功负荷(kvar)。比如第一条支路是节点0到节点1,电阻0.0922Ω,电抗0.047Ω。我建议拿到参数后先用一个确定性潮流脚本跑一遍无分布式电源的基准场景,和标准结果对比一下,确认参数输入没问题再往下做,这一步能省很多排查bug的时间。
做概率潮流之前,我习惯把单位统一一下。仿真中潮流计算用标幺值比较方便,基准功率取1MVA,基准电压取12.66kV,那么基准阻抗就是12.66的平方除以1,约160.3Ω。这样线路阻抗、负荷功率、分布式电源出力都换算成标幺值,计算过程很简单,也避免单位错误导致的奇葩结果。
3.2 分布式电源接入方案与渗透率选择
33节点系统里接入分布式电源,位置和容量怎么选,直接影响仿真结果有没有参考价值。如果全接在变电站出口附近,对电压影响很小,体现不出不确定性的影响;如果一股脑全塞在末端,电压波动会被夸大,也不太符合工程实际。
我这次选的是节点8、节点24、节点30三个接入点。节点8在馈线中段,代表一般性工业或商业负荷区域;节点24和节点30在分支末端,是典型的电压敏感位置,也是分布式电源接入以后最容易出问题的地方。三个点分散接入,能比较全面地反映DG对全网电压和潮流的综合影响。
渗透率也需要提前定义清楚,否则后面做场景对比时会串味。我这里用的是分布式电源总额定容量和系统峰值有功负荷的比值。系统峰值负荷是3.715MW,如果渗透率设定为20%,那么DG总容量就是0.743MW,分配到三个节点,每个节点大概250kW左右。后面做渗透率对比时,我分别跑了0%、20%、50%三组场景,渗透率越高,电压波动的标准差和越限概率变化越明显,对比效果非常直观。
3.3 潮流计算方法选择:前推回代法
配电网不同于输电网,绝大多数情况下是辐射状网络,用牛顿-拉夫逊法当然也能算,但没必要。我项目里用的是前推回代法(backward/forward sweep),这是配电网潮流计算最经典的算法,原理非常直观。
所谓“回代”,是从末端节点开始,根据当前的节点电压和负荷功率,从后往前计算每条支路的电流或者功率流。“前推”则是从首端电源节点开始,根据支路电流和阻抗,从前往后更新各节点电压。这样一轮就是一个迭代,重复迭代直到前后两次计算出的节点电压最大变化量小于收敛阈值。这个方法的优势是不需要形成雅可比矩阵,不需要求逆,迭代一次的计算量很小,而且对辐射状网络收敛性很好,实测下来一般几轮迭代就能达到1e-6的精度。
收敛阈值我取的是电压幅值标幺值最大偏差小于1e-6。要注意初值给得好不好会影响迭代次数,但一般从1.0标幺值起步都没问题。如果遇到重负荷或者高渗透率场景,初值适当做一下改进就能避免震荡,这个在后面的排错章节细说。
4. 概率潮流仿真流程完整实现
4.1 随机数生成与相关性处理
蒙特卡洛概率潮流的第一个实操环节,就是按照概率分布生成随机样本。这里不要直接用均匀分布去抽样,而是要用各个随机变量对应的分布函数去抽样。光伏用Beta分布,风速用Weibull分布,负荷用正态分布,每个分布都对应一套参数。
每个节点的负荷样本也不是独立抽的。严格来说,同一时刻配电网内各个节点的负荷会因为天气、生活习惯等因素存在相关性,完全独立抽样会低估某些极端场景。但模拟相关性需要构造相关系数矩阵,再用Cholesky分解或者Copula处理,复杂度会上一个台阶。如果你是第一版实现,我会建议先把各节点负荷假设为独立抽样,程序跑通之后再回来加相关性。加相关性的方式其实是先抽一组独立标准正态样本,然后通过相关系数矩阵的Cholesky分解线性变换,得到具有目标相关性的标准正态样本,最后再用逆变换转回目标分布。这个方法在光伏高渗透场景下尤其重要,因为同一区域的光伏出力天然就高度相关,忽略它会导致电压越限概率被严重低估。
4.2 单次确定性潮流计算的封装
在写主循环之前,一定要把确定性潮流封装成一个独立的函数,这是整个项目里最值得花时间的部分。函数输入是网络参数(支路数据、节点负荷、分布式电源出力),输出是节点电压幅值、相角和支路功率。做完这个封装之后,蒙特卡洛主循环就变成了一个非常简单的过程:抽样,调用函数,记录结果,循环。
我用的Python实现大致是这个骨架:
def power_flow_solver(bus_data, branch_data, pv_power): # 初始化电压幅值数组为1.0,相角为0 # 迭代循环: # 回代:按支路末端向首端累加电流/功率 # 前推:按支路首端向末端更新电压 # 检查电压最大变化量是否小于1e-6 # 返回电压幅值数组、支路有功/无功数组这个封装思路的好处是,后面不管换分布式电源模型、换负荷模型、换网络参数,都不用动潮流求解核心,只改抽样部分就行。我调试的时候也是先用这个函数跑一次基准潮流,确认与标准结果一致之后,才开始加随机抽样。
4.3 主循环与统计指标提取
概率潮流主循环本身没什么高深技巧,核心就是把每次确定性潮流的结果按节点、按支路存下来。以电压为例,我会维护一个二维数组,行是抽样序号,列是节点序号,每个元素就是某一次抽样中该节点的电压幅值。一万次抽样、33个节点,也就是一个10000乘33的双精度数组,内存占用约2.6MB,完全不用考虑内存压力。
抽样结束之后,统计阶段就可以随心所欲地提取指标了。对每个节点的电压幅值数组,我可以算均值、标准差、最小值、最大值,也可以算5%和95%分位数。越限概率怎么算?只需要统计电压幅值超过1.05或者低于0.95的样本数量,除以总抽样数。同理,支路有功功率也可以统计反向潮流的概率,比如某条支路有功功率为负值的样本比例,就是该支路出现反向潮流的概率。
统计结果我一般会整理成这样的表格:
| 节点 | 电压期望(p.u.) | 标准差 | 95%分位数 | 越上限概率 | 越下限概率 |
|---|---|---|---|---|---|
| 8 | 0.982 | 0.008 | 0.995 | 0.0% | 0.0% |
| 18 | 0.953 | 0.014 | 0.978 | 0.0% | 1.2% |
| 30 | 0.968 | 0.011 | 0.988 | 0.0% | 0.3% |
当然这是某一组参数下的结果,不同分布参数、不同渗透率下数字会变,但表格这个形式可以直接拿来用,后续分析省事很多。
4.4 完整仿真代码骨架
下面给一个完整的、可运行思路的Python代码骨架,重点展示工程实现结构,大家可以根据自己手里的数据格式调整细节:
import numpy as np # 参数区 BUS_NUM = 33 BASE_MVA = 1.0 SAMPLE_NUM = 10000 VOLT_MAX = 1.05 VOLT_MIN = 0.95 # 读取支路数据、负荷数据 branch = load_branch_data() # [首端, 末端, R(p.u.), X(p.u.)] load = load_load_data() # [节点, P(MW), Q(Mvar)] # 分布式电源接入配置:节点8/24/30,额定容量列表 pv_nodes = [8, 24, 30] pv_capacity = [0.25, 0.25, 0.25] # MW # 随机种子,保证可复现 np.random.seed(42) # 存储结果 voltage_records = np.zeros((SAMPLE_NUM, BUS_NUM)) line_power_records = np.zeros((SAMPLE_NUM, len(branch))) for i in range(SAMPLE_NUM): # 1. 抽样:光伏Beta分布、负荷正态分布 pv_power = np.zeros(BUS_NUM) for nd, cap in zip(pv_nodes, pv_capacity): pv_power[nd] = cap * np.random.beta(a=0.9, b=0.8) load_power = load * np.random.normal(loc=1.0, scale=0.05, size=(BUS_NUM, 1)) # 2. 调用确定性潮流 v, line_p = power_flow_solver(branch, load_power, pv_power) # 3. 记录结果 voltage_records[i, :] = v line_power_records[i, :] = line_p # 统计输出 mean_v = np.mean(voltage_records, axis=0) std_v = np.std(voltage_records, axis=0) over_voltage_prob = np.mean(voltage_records > VOLT_MAX, axis=0) under_voltage_prob = np.mean(voltage_records < VOLT_MIN, axis=0)代码里几个小细节值得注意。随机数种子要固定下来,否则每次跑的结果都对不上,项目报告里也没法复现。分布参数先用一组合理值跑通流程,后续再根据实际数据重新拟合。功率因数如果设定为恒功率因数控制,那么无功出力也要跟随有功变化,别只处理有功而把无功漏了。
5. 结果分析与典型场景解读
5.1 电压分布特征与越限概率分析
跑完蒙特卡洛之后,首先看电压。接入分布式电源后,配电网最直观的变化就是馈线电压整体被抬高了,尤其是末端节点。拿节点18来说,无DG时它的电压期望值大概在0.91左右,已经逼近下限;接入一定容量的DG之后,期望值可能抬升到0.95以上,但同时电压的标准差明显变大,不再是稳定在低电压附近,而是可能在某些光照强、负荷轻的时刻冲到1.0以上,甚至在渗透率过高时越过1.05的上限。
从规划角度看,越限概率比期望值更有决策价值。一个节点的电压期望是0.98,看起来非常安全,但它可能有5%的时间电压超过1.05,如果这个节点接的是敏感负荷,那这5%就是不可接受的风险。蒙特卡洛方法的好处就在这里,它能直接给出这种尾部概率,而确定性潮流给不出来。
我跑高渗透率场景时,节点24和30这类分支末端的电压越上限概率能达到百分之几,这不是一个可以忽略的数字。实际操作中看到这种结果,第一反应应该是去调整分布式电源的无功控制策略,或者考虑加装调压器,而不是简单地降低DG容量。
5.2 支路潮流与反向功率概率
再看支路潮流。传统配电网设计时假设功率从变电站单向流向负荷,但分布式电源接入后,局部区域可能出现“电源出力大于本地负荷”的情况,功率就会反向流动。反向潮流本身不是问题,但它会带来两个影响:一是可能使某些线路的载流量接近甚至超过额定值,二是会影响保护定值的配合和电压调节设备的动作逻辑。
我在统计结果时,特别关注了变电站出口支路和DG接入位置附近支路的反向潮流概率。举个具体例子,如果节点8接入的DG容量达到当地负荷的两倍以上,那么支路7-8出现反向潮流的概率会明显上升。统计方法很简单,就是看这条支路有功功率记录的负值占比。
除了反向概率,支路潮流的95%分位数也是重点关注对象。因为规划时线路选型按最大允许载流量来,但“最大”在不确定性环境下本身就是个概率概念。用95%分位数做设计校核,比简单拿峰值场景算一次更合理,也更符合实际运行中允许短时过载的情况。
5.3 不同渗透率场景对比
为了体现概率潮流在方案比选中的作用,我把渗透率设置成0%、20%、50%三档,其他条件完全一致,分别跑了一万次抽样。三个场景放在一起看,趋势非常清晰。
电压方面,渗透率从0%升到20%,末端低电压问题得到改善,越下限概率显著下降;但继续升到50%时,越上限概率开始抬头,且电压波动幅度明显增大。这说明分布式电源接入存在一个“甜点区”,太低解决不了末端电压问题,太高又引入新的过电压风险。
网损方面更有意思。渗透率20%时,DG就地平衡了部分负荷,线路传输功率减小,网损期望值比无DG场景降低不少;到了50%渗透率,由于部分时段出力远超负荷,功率长距离回流,网损反而上升。这种“先降后升”的非单调关系,如果只做几个确定性场景很容易被漏掉,而概率潮流能通过网损期望和概率分布把这种变化规律完整呈现出来。
| 渗透率 | 节点18电压期望(p.u.) | 节点18越上限概率 | 全网网损期望(kW) |
|---|---|---|---|
| 0% | 0.912 | 0.0% | 203 |
| 20% | 0.951 | 0.0% | 168 |
| 50% | 0.993 | 4.6% | 189 |
6. 常见问题与排查技巧实录
6.1 潮流迭代卡住或震荡怎么办
前推回代法大多数情况下很稳定,但我也碰到过迭代发散或者震荡的情况,尤其是在高渗透率、轻负荷、DG集中接入的场景。第一个要检查的是功率单位。很多人会把兆瓦和千瓦混着用,导致负荷或电源功率差了三个数量级,潮流自然跑飞。解决方式是全部转换为标幺值后再进入迭代,转换完之后先打印几个节点的注入功率核对一下量级。
第二个容易踩的坑是负荷功率和DG出力在节点注入方向上的处理。前推回代法里一般把负荷当成节点注入的“负功率”,把分布式电源当成“正功率”,两者先代数相加得到净注入功率,再进入迭代。如果符号写反了,DG越大电压越低,结果完全反物理,排查起来很迷惑。判断对错的最快办法是跑零渗透率基准潮流,对比标准节点电压,如果节点18电压能对上0.90左右,说明方向没问题。
如果迭代震荡,可以尝试从初值入手,把上一次成功潮流计算的电压结果作为下一次迭代的初值,这种连续性初值策略在蒙特卡洛循环里特别有效。再不行就检查是不是有重负荷支路让前推回代收敛性变差,换成功率注入形式的前推回代,别用电流形式,能缓解一部分问题。
6.2 抽样结果出现离谱数值的排查
蒙特卡洛跑出来的结果偶尔会出现某个节点电压低到0.5或者高到1.5这种离谱值。遇到这种情况,我先不急着怀疑潮流算法,而是去查抽样生成的输入数据。最常见的问题是负荷正态分布没有做截断,标准差设得偏大时,某些小负荷节点会被抽成负值,负负荷在网络里相当于又一个电源,电压自然就乱了。解决思路是给负荷抽样加边界截断,通常把抽样值限制在均值正负3倍标准差范围内,或者直接把负值重新置成一个很小的正数。
光伏Beta分布抽样也要注意参数是否合理。Beta分布随机数的取值范围天然是0到1,一般不会出界,但形状参数如果不匹配,出现大量接近0或接近1的极端出力,会让电压波动远超实际。我自己就踩过这个坑,一开始随手设了一组Alpha和Beta参数,跑出来的电压越限概率高得离谱,后来用当地实测辐照数据拟合分布参数后结果才恢复正常。分布参数一定要有数据依据,不能拍脑袋。
6.3 仿真速度慢与内存控制优化
简单随机抽样跑一万次,33节点配电网用时不算长,但如果网络规模变大、样本量提高,速度问题就会暴露。我常用的提速手段有三个:优先把潮流函数向量化,尽量减少循环里的重复计算;用多进程并行代替串行循环,Python里用multiprocessing或者joblib都很方便,MATLAB里直接用parfor;实在不行就换拉丁超立方抽样降低所需样本量。
关于内存,我之前提过一万乘33的数组占用不大,但如果同时存几十个统计指标,每个都开一个同样大小的二维数组,内存就有点紧张了。优化技巧是不存全量结果,边循环边累加各阶矩和越限计数器,最后统一求统计量。这样内存占用基本恒定,和抽样次数无关,跑十万次也毫无压力。
6.4 相关性建模的取舍建议
最后说说相关性这个容易被忽略的问题。同一区域的光伏,在云层飘过的时候出力一起往下掉,不同节点负荷在傍晚一起往上走,这些时空相关性是真实存在的。完全忽略相关性,概率潮流给出的电压波动区间往往会偏窄,这会低估风险。
但相关性建模不是必须一步到位。我建议第一版仿真先用独立抽样,把整体流程跑通,看看各指标的合理范围。如果项目要求更精细的结果,再加上基于Cholesky分解的正态变换相关抽样,或者用Copula处理非正态相关结构。加相关之后第一个要验证的就是相关系数矩阵是否正定,否则Cholesky分解会报错。另外相关系数不能只看大小,得结合场景理解,比如同一馈线上的两个DG相关系数可能高达0.9,而不同馈线之间的DG可能只有0.3,这些取值要从实际运行数据里估算。
我在实际项目里体会最深的一点是,概率潮流这个工具的价值不在于把结果算得多花哨,而在于它逼着你把“不确定”这件事老老实实量化出来。做确定性潮流时,参数差一点可能只差一个数字;做概率潮流时,分布假设差一点,越限概率可能差出几倍。所以整个流程下来,最花时间的往往是数据整理和分布拟合,而不是写代码。如果你刚开始接触这块,我的建议很直白:先用33节点把流程完整跑通一遍,重点看电压越限概率和网损期望随渗透率的变化规律,再去碰大规模网络和精细相关性模型。这套底子打好了,后面换什么系统、加什么约束都不慌。