电气距离与谱聚类:电力系统分区实战指南 📅 发布时间:2026/8/31 20:37:12 👁 浏览次数: 简介本资源面向电力系统分析方向的研究生、科研人员及高年级本科生聚焦于利用谱聚类算法实现电网分区这一核心工程问题。针对传统分区方法难以刻画节点间非线性电气耦合关系的难点资源提供基于电气距离构建相似度矩阵、拉普拉斯矩阵分解与特征向量聚类的完整MATLAB实现方案适用于IEEE标准测试系统建模与算法验证场景。压缩包共含2个MATLAB源文件.m总大小仅1KB轻量紧凑分别实现IEEE 30节点系统的数据预处理、电气距离计算、谱聚类核心流程及分区结果输出代码结构清晰、注释完备便于理解算法逻辑与快速复现。目前已有501人学习下载读者可直接运行获取分区结果、分析特征向量投影分布、调整聚类数K值并观察分区稳定性是掌握图论方法在电力系统中落地应用的实用入门材料。 电气距离和谱聚类分区这套组合我是真被折腾出感情了。最开始接触这个课题是因为一个新能源消纳项目电网调度那边要求把区域网架重新划分既要保证区域内电气耦合紧密又要让各分区之间解耦尽量彻底方便后续做网架优化和故障隔离。当时组里的人第一反应是用模糊聚类跑了一轮FCM之后发现分区结果不太稳定换了几组初始中心结果飘得厉害。后来我找了一圈文献发现国外做电力系统分区基本都把谱聚类当作默认工具于是把方向切到谱聚类上折腾了两周总算把整条链路跑通最后交出去的分区方案调度那边也很认可。这篇文章就把我踩过的坑、总结的套路、可复现的代码一次讲清楚。先说结论电力系统分区不是一个单纯的聚类问题本质上是一个带物理约束的图划分问题。谱聚类之所以适合干这个活是因为它天然处理的是节点之间的相似度而电气距离恰好可以编码成节点对的相似度。你只要把电网抽象成一个加权图节点是母线边权是两个母线之间的电气耦合强度然后用谱聚类在这个图上做划分得到的分区既符合数学上的最优切割原则又具备物理上的可解释性。这套方法论在IEEE 39节点、IEEE 118节点系统上都验证过我会在后面给出完整的实操流程和代码。1. 为什么电力系统分区不能靠拍脑袋也不能靠普通聚类电力系统分区这件事调度领域做了几十年了。早期就是按行政区域或者地理边界划某个地市管一片省调管大的区域。这种划分在电网规模小、运行方式稳定的时候够用但是到了新能源占比升高、网架结构越来越复杂的阶段地理分区和电气耦合的错位越来越明显。同一个地理区域里可能横跨好几个电气断面而电气上强耦合的节点反而分散在行政边界两侧这给调度决策和继电保护整定都带来了麻烦。从应用需求看分区结果主要服务于以下几个场景故障隔离与黑启动分区需要把电网拆成若干可以独立恢复供电的黑启动孤岛各岛之间尽量少耦合故障时能快速解列。电压/无功分区控制现在电网普遍采用分级电压控制二级电压控制需要把电网划分成电压控制区域每个区域内的中枢母线能代表区域电压水平。经济调度与电力市场结算分区电力价格、分区备用容量评估需要网架分区作为基础。新能源消纳与网架规划判断哪些区域的新能源和负荷能够就地平衡哪些需要跨区输送。所以分区不是简单的把点分成几堆它要求每个分区内部强连接分区之间弱连接同时分区结果要符合电力系统的物理规律。传统的K-means和FCM模糊聚类为什么在这个问题上水土不服核心原因是它们默认在欧氏空间里工作。你把每根母线的电气坐标拉成一个向量喂给K-means它只能按几何距离划分但这个几何距离未必等价于电气耦合强度。电气上接近的节点在坐标空间里可能离得很远。这就像你把一张城市地铁网络画在地理地图上两个站看起来隔了一整条街但实际上它们在同一站台换乘物理连通性极强。K-means看的是地图上的直线距离而电力调度关心的是能不能一趟车直达。谱聚类处理这个问题的思路完全不同。它需要的输入不是欧氏坐标系下的点而是节点间两两相似度矩阵。这个相似度矩阵可以由电气距离直接构造也就是说你可以把电气耦合强不强这个领域知识精确编码成算法输入。算法内部再通过拉普拉斯矩阵的特征分解把节点映射到一个低维谱空间在这个谱空间里再用K-means就非常合适了。这就是谱聚类能吊打普通聚类解决电力系统分区的根本原因。2. 电气距离谱聚类分区的底层坐标系不讲电气距离的电力系统分区方案都是耍流氓。谱聚类只是那个做划分的工具真正决定分区质量的是你喂给它的相似度矩阵长什么样。而这个相似度矩阵的每一项都必须来自电气距离。2.1 电气距离和地理距离完全是两码事电气距离定义的是两个母线之间电气耦合的紧密程度。最直观的理解方式是电气距离越短表示两个母线的电压/相角越容易互相影响或者说在两个母线之间传输功率的电气代价越小。常见定义方式有这么几种基于节点阻抗矩阵Zbus的定义两个节点间的等效转移阻抗。基于电压灵敏度的定义一个节点注入无功/有功后另一个节点电压变化的灵敏度大小。基于潮流分布和网络拓扑的复合定义结合线路电抗、变压器变比、潮流分布等因素加权。实际工程中用Zbus里的转移阻抗来定义电气距离是最常见、也最容易落地的做法。设系统有N个节点节点阻抗矩阵Z是N×N的复数矩阵那么节点i和节点j之间的等效电气距离定义为[ Z_{ij}^{eq} Z_{ii} Z_{jj} - Z_{ij} - Z_{ji} ]这个值的物理含义是当节点i和节点j之间发生功率传输时整个网络对这条传输路径的等效阻抗。这个值越小说明两个节点之间电气联系越紧密。2.2 导纳矩阵与潮流数据是怎么参与计算的要得到Z矩阵第一步是构建系统的节点导纳矩阵Y。Y矩阵的对角元是各节点自导纳非对角元是两个节点之间线路导纳的负值。对Y矩阵求逆就得到Z矩阵。实际应用时需要注意如果有多条线路并行导纳需要按并联公式合并。变压器绕组会引入变比和漏抗需要在Y矩阵构建时用变压器模型修正。线路充电电容在高压电网220kV以上中影响不可忽略Y矩阵中要包含对地导纳。有了Z矩阵之后把所有节点对的等效阻抗算出来就得到一个N×N的电距离矩阵D。D矩阵中每个元素d_ij表示节点i和j之间的电气距离。2.3 从电气距离到相似度矩阵的配方谱聚类需要的是相似度矩阵S要求数值越大表示越相似而电距离是越小越紧密。所以必须做一个转换。最常用的是高斯核函数[ S_{ij} \exp\left(-\frac{d_{ij}^2}{2\sigma^2}\right) ]这个公式看起来简单里面藏着一个对结果影响巨大的参数σ。σ选大了所有节点的相似度都接近1分区区分度不够σ选小了相似度迅速衰减只有电气上紧邻的节点才有非零相似度分区会变得非常碎片化。我个人的经验是σ可以取电距离矩阵所有非对角元素的均值或者中位数然后结合谱间隙eigenvalue gap做微调。在IEEE 39节点系统上用均值的效果要优于中位数在118节点系统上中位数效果更好说明没有一个一劳永逸的经验值必须针对具体网架试。2.4 要不要对相似度矩阵做归一化这一步很多人都忽略了但直接影响结果稳定性。如果系统里既有220kV节点又有500kV节点阻抗量纲跨度很大相似度矩阵的行和/列和可能相差悬殊导致拉普拉斯矩阵的特征分解偏向高权重节点低权重节点被结构性淹没。常用的处理办法对D矩阵做标准化每个元素减去均值除以标准差再做高斯核变换。对S矩阵做行归一化让每一行和为1。直接用归一化拉普拉斯矩阵做谱分解这在算法层面就能规避部分尺度问题。我在实际项目中是两者都做先对电距离标准化再用归一化拉普拉斯矩阵做特征分解两条保险下来分区结果稳定很多。3. 谱聚类算法从拉普拉斯矩阵到最终分区这一节把谱聚类的原理用人话讲透。很多博客把谱聚类讲成黑魔法其实它的核心思想不过三句话把图划分问题转化为谱分解问题用特征向量给节点重新定位再用K-means收尾。3.1 图划分问题的数学本质把电网抽象成加权图G(V,E,W)V是母线节点集合E是线路集合W是权重矩阵权重越大表示两个节点耦合越强。那么分区问题就变成了把顶点集V划分为k个互不相交的子集使得割集权重尽量小同时每个子集内部的权重尽量大。一个直接定义是割集权重[ Cut(A,B) \sum_{i\in A, j\in B} W_{ij} ]最小割问题直接求解是NP难的而且即便求出来也倾向产生极不平衡的划分——比如一个分区里只有一个孤立节点另一个分区包含其余全部节点这时候割集权重最小但没任何物理意义。所以实际用的是归一化割Normalized Cut, NCut不仅考虑割掉的权重还考虑每个子集占整体权重的比例[ NCut(A_1,...,A_k) \sum_{i1}^{k} \frac{Cut(A_i,\bar{A_i})}{vol(A_i)} ]其中vol(A_i)是子集A_i内部所有边的权重之和。这个目标函数天然惩罚微小分区保证了每个分区在电气上都有足够规模。3.2 从NCut到拉普拉斯矩阵的特征分解NCut最小化问题同样难直接解但数学上有一个惊人的结论如果我们允许指示向量在实数域上放松本来是0/1离散值那么NCut最小化和拉普拉斯矩阵的广义特征分解等价。定义度矩阵D_d它是一个对角阵对角元是每个节点的加权度即相似度矩阵行和。定义未归一化拉普拉斯矩阵L[ L D_d - S ]或归一化形式[ L_{sym} D_d^{-1/2} L D_d^{-1/2} ]把L_sym做特征分解取前k个最小特征值对应的特征向量按行堆叠成一个N×k的矩阵再对每一行做归一化。这时矩阵的每一行就相当于原图节点在谱空间里的一个新坐标。在这个谱空间里属于同一分区的节点坐标彼此接近不同分区的节点坐标距离较远。最后对这个N×k矩阵跑一次K-means聚类结果就是分区方案。这就是谱聚类全套流程。它牛的地方在于通过特征分解这种全局操作把图切割这个局部优化问题转化成了一个全局谱聚类问题天然规避了局部最优陷阱。3.3 归一化拉普拉斯 vs 未归一化拉普拉斯两种形式在电力系统分区中的表现有差异我用同一组IEEE 39节点数据做过对比拉普拉斯形式分区结果特点适用场景未归一化L对节点度差异敏感连接多的枢纽节点容易独自成区网络均匀、节点度差异小的场景归一化L_sym对节点度做了均衡枢纽节点不会霸占单一分区大多数电力系统场景推荐默认使用实际工程项目里我基本只用L_sym。因为电力网架中总有那么几个500kV枢纽站连接数比普通220kV站高一个量级如果不用归一化分区结果很容易被枢纽节点牵着走。3.4 谱聚类和模糊聚类FCM的横向对比既然项目标题里同时出现了模糊聚类和谱聚类这里多写几句。FCM模糊C均值属于软聚类方法每个节点给一组隶属度归属关系是模糊的。当年用它做分区遇到的问题是隶属度矩阵结果不稳定。换一组初始聚类中心同一批节点的隶属度可能发生较大变化。对初始中心敏感。FCM本质上是梯度下降类方法初始中心选不好很容易掉进局部最优。无法自然融入电气距离信息。虽然可以把电气距离当特征输入但FCM假设聚类簇是凸的、近似球形的电力系统的电气结构不满足这个假设。谱聚类没有这些问题。它先做全局的谱分解再做K-meansK-means在谱空间里只需要做简单划分对初始中心的敏感性大大降低。稳定性实测下来同一组数据跑20次分区结果完全一致。4. 全流程实操从IEEE 39节点数据到分区结果下面进入真正的实操环节。我用的语言是Python核心库是numpy、scipy、scikit-learn。完整代码可以直接跑。4.1 环境准备和数据集说明IEEE 39节点系统也叫New England系统包含10台发电机、39条母线、46条线路和变压器是电力系统分区研究最常用的测试系统之一。数据可以从Matpower的case39.m提取也可以用pandapower自带的数据文件。需要用到的Python库pip install numpy scipy scikit-learn matplotlib networkx pandapower4.2 构建导纳矩阵并计算电气距离为了聚焦本文主题这里用pandapower加载系统数据然后提取导纳矩阵。import numpy as np import pandapower as pp import pandapower.networks as nw # 加载IEEE 39节点系统 net nw.case39() # 构建节点导纳矩阵Ybus Ybus pp.pf._build_bus_ppc(net._ppc)[bus] # 简化示意 # 实际更推荐直接用pandapower内部接口 from pandapower.auxiliary import _init_runpp_options from pandapower.pf.ppci_variables import _get_powerflow_results # 不过为了清晰我们直接用matpower格式的Ybus # pandapower内部在运行潮流后可以拿到Ybus pp.runpp(net) Ybus net._ppc[internal][Ybus] Zbus np.linalg.inv(Ybus.todense()) N Zbus.shape[0]这一步要注意Ybus是复数矩阵求逆后Zbus也是复数。电气距离用的是转移阻抗的幅值所以后续要取模或者取实部。工程上取|Z_ij^eq|的情况比较多因为复数的虚部包含了无功耦合的信息幅值更能反映综合耦合强度。# 计算电气距离矩阵D D np.zeros((N, N)) for i in range(N): for j in range(N): if i j: D[i, j] 0.0 else: z_eq Zbus[i, i] Zbus[j, j] - Zbus[i, j] - Zbus[j, i] D[i, j] abs(z_eq)N39时双层循环没有性能问题但如果换成1000节点以上的系统就要用向量化方式或者只计算上三角矩阵再对称填充。4.3 电距离标准化和高斯核相似度# 标准化电距离 D_std (D - np.mean(D)) / np.std(D) # 高斯核带宽sigma这里取标准差的均值 sigma np.mean(D_std[D_std 0]) S np.exp(-D_std**2 / (2 * sigma**2)) np.fill_diagonal(S, 0) # 自相似度清零避免对角占优关于sigma我建议至少试三组0.5sigma_base、sigma_base、2sigma_base。如果三组结果分区数差异很大说明这个网架对sigma敏感需要仔细分析。如果差异不大说明谱聚类在这个数据上是稳的可以放心用中间那组。4.4 谱聚类核心流程与可视化直接调scikit-learn的SpectralClustering可以省很多事但为了让你看清内部原理我拆开写一遍同时也便于后面调参。from sklearn.cluster import KMeans # 归一化拉普拉斯矩阵 D_d np.diag(S.sum(axis1)) D_d_inv_sqrt np.diag(1.0 / np.sqrt(S.sum(axis1) 1e-10)) L_sym np.eye(N) - D_d_inv_sqrt S D_d_inv_sqrt # 特征分解取前k个最小特征值对应的特征向量 eigenvalues, eigenvectors np.linalg.eigh(L_sym) k 4 # 分区数选法见下一节 X eigenvectors[:, :k] # 对特征向量做行归一化 X_norm X / np.linalg.norm(X, axis1, keepdimsTrue) # K-means收尾 kmeans KMeans(n_clustersk, n_init20, random_state42) labels kmeans.fit_predict(X_norm) # 输出每个节点的分区归属 for node, label in enumerate(labels): print(fBus {node1}: Region {label1})4.5 用networkx画分区图分区结果光看编号不够直观最好把网架拓扑画出来按分区上色。这一步在项目交付时尤其重要非算法背景的同事和调度人员看彩色拓扑图比看编号快得多。import matplotlib.pyplot as plt import networkx as nx # 从pandapower构建networkx图 mg pp.topology.create_nxgraph(net) plt.figure(figsize(14, 10)) pos nx.spring_layout(mg, seed42, k0.8) # 按分区标签上色 node_colors [C0, C1, C2, C3] for node, label in enumerate(labels): if node in mg.nodes: nx.draw_networkx_nodes(mg, pos, nodelist[node], node_colornode_colors[label], node_size400, alpha0.8) nx.draw_networkx_edges(mg, pos, alpha0.3) nx.draw_networkx_labels(mg, pos, font_size8) plt.title(IEEE 39-Bus System Partition Result via Spectral Clustering) plt.show()实测跑出来的四分区结果在拓扑图上非常干净区域边界基本沿着弱联络线切开和人工划分的主观判断基本吻合但是比人工划分要客观得多。4.6 评估分区的质量指标分区不是画完图就结束了至少要用几个指标评估一下。我常用的三个模块度Q值衡量社区划分强度Q值越大说明分区内部连接越紧密分区之间连接越稀疏。一般在0.3以上算可接受。def compute_modularity(S, labels): m S.sum() / 2 Q 0.0 for i in range(len(labels)): for j in range(len(labels)): if labels[i] labels[j]: Q (S[i, j] - S[i].sum() * S[j].sum() / (2 * m)) return Q / (2 * m)分区均衡度计算每个分区节点数或者总装机容量占比避免出现一个分区占了50%节点、另一个只有3个节点的极端情况。断面功率/解列代价用给定分区方案下的跨区联络线总功率流变化评估。这个需要结合潮流计算结果属于工程级验证。5. 实测中踩过的坑和参数调节心得这一部分全是我真金白银换来的经验。谱聚类做电力系统分区原理清楚之后细节才是决定成败的关键。5.1 sigma的坑分区数和sigma的敏感度曲线我第一次用谱聚类跑分区sigma拍脑袋取了个0.1结果39个节点分了12个区碎片化严重调度那边直接打了回来。后来我把sigma从0.01到10做了网格扫描固定k4观察分区结果变化发现sigma过小时相似度矩阵几乎全是零拉普拉斯矩阵的谱结构趋近于多个连通块分区结果跟着连通块走特别碎。sigma过大时相似度矩阵趋近于全1矩阵特征值趋近于0的个数少于k谱间隙不明显K-means在谱空间里等于在噪声上聚类结果随机性很大。sigma落在合理区间时分区结果稳定且和人工经验吻合。经验做法先画出sigma和分区鲁棒性的曲线找一个平台区间取区间中间的sigma值。平台区间越宽说明这个网架的分区结构越稳固。5.2 分区数k怎么定谱间隙法和评价指标法k的选择本质上是聚类数选择问题。电力系统场景里k通常由业务需求决定——比如黑启动方案需要几个独立恢复分区或者调度运行需要几个电压控制区。如果没有业务约束就用谱间隙法。特征分解后把特征值从小到大排列找相邻特征值差值最大的位置。如果第k和第k1个特征值的gap明显大于其他相邻gap这个k就是合适的聚类数。因为谱间隙大说明图的社区结构在k这一点上最清晰。还可以配合模块度来选择k。遍历k从2到10计算每个分区方案的模块度Q取Q最大的k。我实测IEEE 39节点系统模块度在k4时最高和人工经验一致。5.3 孤立节点和弱连接节点会把分区结果搞乱这是电网分区特有的坑。某些终端变电站只有一条线路连接到主网电气上天然是弱连接节点。谱聚类会倾向把这些弱连接节点单独划成一个分区因为割断一条线路的代价很小。但实际调度中这种终端站孤岛化没有意义。解决方式有两种一是在构建相似度矩阵时对连接数低于某阈值的节点做邻域修正把它的相似度强制向电气上最近的枢纽节点靠拢二是在K-means之后做后处理把小于某个节点数阈值的碎片分区合并到电气距离最近的相邻分区。5.4 大规模电网的特征分解效率问题IEEE 39节点直接np.linalg.eigh很轻松但真实省级电网动辄几千上万个节点全量特征分解是不可行的。这个场景下有两个优化方向使用稀疏特征分解算法比如scipy的eigsh只计算前k个最小特征值对应的特征向量。k通常不超过10计算量从O(N^3)降到接近O(N)。先用图粗化graph coarsening把大规模网络压缩到几百个代表节点在粗化图上做谱聚类再把标签映射回原始节点。我在一个1000节点级别的区域网上试过用eigsh算特征分解只需要几秒钟完全满足工程需求。from scipy.sparse.linalg import eigsh # L_sym是稀疏矩阵格式 eigenvalues, eigenvectors eigsh(L_sym, kk, whichSM)5.5 仿真的结果和实际调度的一致性验证算法算出来的分区方案最后一定要回到潮流仿真里验证。我当时的做法是对每个分区检查区域内各母线电压水平是否接近跨区联络线的功率波动是否在合理范围。另外还做了一个故障仿真在某个分区的关键联络线上设置N-1故障观察分区内是否出现电压越限。仿真结果显示谱聚类分区方案在N-1故障下受影响节点被控制在分区内部没有向其他分区扩散这恰恰是分区想要的效果。6. 分区结果的工程落地与向非技术同事解释最后聊一聊落地。算法写完只是第一步分区方案要真正进入调度流程还要过很多关。6.1 让分区结果看得见、讲得出调度运行人员和运检人员不一定懂谱聚类但他们一看彩色拓扑图就明白。我每次交付都会生成三张图分区拓扑图、分区内联络线单线图、分区断面功率表。文字结论只写三句话每个分区包含哪些主要站点、分区间联络线是哪几条、每个分区的受电/送电特征。6.2 在可视化图上叠加地理信息纯拓扑图对调度不够直观他们更习惯地理接线图。可以把谱聚类的标签直接映射到地理坐标图上用basemap或cartopy叠加站点经纬度信息。如果系统里没有经纬度至少按变电站所属地市做颜色映射调度能快速对应到自己的辖区。6.3 扩展方向动态分区和在线更新这套方法虽然是离线分区但完全可以扩展成在线版本。新能源出力随机波动会导致电气距离实时变化理论上可以定期重跑谱聚类基于最新的潮流断面更新分区方案。不过在线更新要解决分区结果震荡的问题前后两个时段的标签不能跳变太厉害需要加时序平滑约束。这个方向我已经在验证后面跑出结果再单独写一篇。最后再分享一个小技巧很多人问我谱聚类和模糊聚类到底选哪个我的回答是如果你要的是可解释、稳定、能落地的分区方案优先谱聚类如果你要分析节点归属的模糊程度比如某些节点处于两个分区边界、归属不明那可以在谱聚类结果基础上对边界节点算隶属度两种方法互补用。这种组合拳在工程上效果最好。本文还有配套的精品资源点击获取