上个月帮朋友所在的一家做园区增量配电的公司做技术方案评审,对方拿出的规划报告厚厚一沓,建设成本算得很细,但一追问“这个网架遇到检修或者故障,哪些负荷会失电、一年预计停多久、损失多少钱”,对方答不上来。这个现象在混合配电系统规划里特别典型:一方面交流馈线和直流母线、储能、分布式电源耦合在一起,运行方式比传统辐射网复杂得多;另一方面经济性指标和可靠性指标本来就是一对此消彼长的矛盾,不放在同一个框架里权衡,做出来的方案要么成本高得离谱,要么可靠性差得不敢用。用Python把这套“经济与可靠性双目标”的配电系统规划和可靠性评估完整实现一遍,涉及交直流混合网架建模、时序负荷处理、年费用折算、蒙特卡洛仿真这些环节,踩坑不少,写出来供刚接触这个方向的同学和同行参考。
1. 先搞清楚这个题目要解决什么问题
1.1 为什么传统配电规划算法算不了混合系统
传统配电网规划的核心逻辑其实不复杂:给定负荷预测结果,在候选走廊里选线路,在候选位置上定变电站容量,保证满足电压和载流能力约束,然后让建设投资和运行损耗最小。手算或者用Excel都能做十节点以下的小网架,加上一点枚举法也能应付。但混合配电系统出现后,情况变了。
所谓混合配电系统,通常指交流馈线、直流馈线、AC/DC换流器、分布式光伏、储能和各类柔性负荷共存的配电网。交流系统里的潮流用牛顿-拉夫逊法能解,但直流母线段的电压和功率分配遵循另一套规律,换流器本身又有损耗和容量约束。规划人员面对的不再是“选线、选变电站”这种单一决策,而是新增了“换流器放哪、直流线路怎么接、储能容量配多少、分布式电源怎么接入、什么时候该切换运行方式”这一串问题。
我见过不少同行用传统N-1校验加安全约束的方式硬算,结果普遍在换流器容量和直流母线电压水平上出问题。原因不是约束写错,而是交流潮流和直流功率分配的耦合关系没有被建模进去——规划方案的可行性判断都是错的。要用程序把这类问题完整算明白,第一步就是换一套能同时表达交流和直流潮流特征的建模工具。
1.2 经济性与可靠性的“此消彼长”到底矛盾在哪
先举个例子。同样的一个10千伏馈线片区,方案A把关键分段开关全部换成断路器,投资高出一截,但故障隔离时间从半小时缩短到几十秒;方案B只加联络线不做自动化,建设费用省了很多,可一回故障就可能造成大片负荷长时间停电。如果不把停电折算成钱,两个方案根本没法公平比较。
经济性目标追求的是年费用最小,包括等年值投资、运行维护、网损和停电损失;可靠性目标追求的是不供电量最小或者系统平均停电时间最短。矛盾在于,提高可靠性基本都要靠增加设备、冗余和自动化水平,这些都会抬高投资;而压缩投资往往以牺牲备用和分段为代价,停电概率和停电范围就上去了。
更麻烦的是,电网企业评价项目时经常两个指标都要看:既要有能过财务评审的投资回收期,又要有能对外的供电可靠性承诺。所以规划不能只求单目标最优,必须在两者之间找一个可接受的平衡点。这个平衡点不是拍脑袋定的,需要先用数学化的可靠性指标把风险量化,再用双目标优化的方法把候选方案排出来。
2. 双目标规划模型怎么搭才不跑偏
2.1 经济性目标函数:年费用法里面的细节
经济目标用年费用法最直观。把全寿命周期里的投入折算到每年,再和每年的运行支出加在一起。表达式可以写成:
AC = CRF × C_inv + C_OM + C_loss + C_EENS
其中C_inv是初始建设投资,CRF是等年值系数,C_OM是年运行维护费用,C_loss是年网损费用,C_EENS是停电损失费用。这里有个容易算错的点是CRF,它由折现率i和规划年限n决定:
CRF = i × (1+i)^n / [(1+i)^n - 1]
我做实际项目时折现率通常取8%,配电网设备寿命按20年算,算下来CRF大约是0.1018。这个参数别看小,它对总投资占比较高的方案影响非常大。同一个方案,折现率从8%改成5%,等年值投资能差出百分之十几,所以工程评审时折现率口径必须统一,否则算出来的经济性排名根本没有可比性。
C_inv里面需要区分一次性设备购置和施工费用:线路按长度乘以单位造价,变压器和换流器按容量算,储能按千瓦时容量算,光伏按峰值功率算。在实际建模中,这些参数最好都做成独立的配置表,不要硬编码在目标函数里。后面做敏感性分析时,只要改表就能批量重算,省不少事。
还有一个细节是C_loss的计算。网损费用要基于典型日负荷曲线逐时段的潮流结果累计,不能只算一个最大负荷工况然后乘以利用小时数。因为分布式光伏出力中午高、傍晚低,负荷峰值又往往出现在晚间,两者的时序配合直接决定损耗电量。只用峰值工况算网损,误差动辄百分之二三十,对方案排序有实质影响。
2.2 可靠性指标怎么选、停电损失怎么折算
规划阶段评估可靠性,最常用的指标有三个:系统平均停电持续时间(SAIDI)、系统平均停电频率(SAIFI)和期望缺供电量(EENS)。前两个偏运行统计视角,EENS偏电量损失视角,规划优化里我更推荐用EENS作为目标,因为它能直接乘上单位停电损失系数,变成经济性评估的一部分。
EENS的工程计算思路是:先对每个负荷点求出年停电概率和年平均停电时间,再乘以该节点的年平均负荷。对于由多个元件串联供电的简单辐射结构,负荷点年不可用率U可以用故障率和修复时间估算:U = λ × r / 8760,其中λ是元件年故障率,r是单次故障平均修复时间。这个式子虽然简化,但规划阶段已经有足够参考价值。
把这些负荷点不可用率累加全部节点,乘以对应负荷功率,就是系统EENS。把EENS乘上单位停电电量损失费用系数VOLL,就得到了停电损失费用C_EENS。VOLL怎么取是个敏感问题,不同用户类型差异很大:居民用户每千瓦时几块钱,商业用户可能几十块钱,有个别工业用户甚至上百块。做研究时可以先统一取一个值,做工程方案比选时建议按负荷构成加权,不然会严重低估或高估可靠性改善的收益。
2.3 规划阶段必须写进模型的约束条件
先列一份我在建模时一定会加的约束清单:
- 交流节点电压幅值约束,一般要求在0.95到1.05倍额定电压之间;
- 直流母线电压约束,根据换流器控制策略,通常在0.9到1.1倍额定值之间;
- 线路和变压器、换流器的视在功率载流约束;
- 分布式电源接入容量上限,受变电站短路容量和电能质量指标制约;
- 储能系统荷电状态SOC的上下限,以及年度充放电次数限制;
- 规划的辐射状拓扑约束,防止闭环运行带来的保护配合问题;
- N-1安全校验约束,即任一元件退出运行后,系统不能出现失负荷或者越限。
N-1校验在优化迭代里非常耗时,因为每个候选方案都要枚举N个元件逐一退出后的潮流结果。实际工程中我一般分两阶段处理:第一阶段先满足正常工况下的潮流和电压约束,第二阶段只对进入短名单的前几个方案做N-1校验。直接在所有个体里都跑完整N-1,计算量会爆炸,优化算法根本跑不动。
2.4 双目标怎么合并才科学
双目标优化最常见的处理办法是加权求和,把两个目标线性合并成一个综合目标。但这里有个坑:经济费用的数量级通常是几百万到几千万,EENS的数量级可能是几百兆瓦时,直接加权的话,量纲和尺度都不一样,结果必然被大数量级的那个目标主导。
正确做法是先把两个目标做归一化。比如方案i的经济性目标fi_cost除以所有候选方案中最大费用f_max_cost,可靠性目标fi_eens除以最大EENS值,然后再加权。这样两个目标都在0到1的区间里,权重系数才有实际含义。
不过加权法有一个固有缺陷:权重本身就是主观设定,很难让业主从决策角度接受“为什么可靠性占0.6而不是0.4”。我自己的做法是用非支配排序的思路求帕累托前沿,把一批互有取舍的方案全部保留下来,最后再用TOPSIS或者层次分析法帮决策者选。这样输出的不是单一答案,而是一组带含义的备选方案,项目评审时说服力强得多。
3. Python代码实现的完整技术栈与关键模块
3.1 用哪套工具链,环境怎么配
做这类研究,Python是最高效的选择。关键在于库的搭配:潮流计算用pandapower,数值计算和随机抽样用numpy,优化算法自己写或者用pymoo,后期画图用matplotlib。
第一次搭建环境的朋友,先把Python装好,然后用pip把pandapower、numpy、matplotlib、pymoo这几个库装上即可。pandapower这套库比较特殊的地方是它自带一个基于牛顿-拉夫逊法的潮流求解器,输入输出都是DataFrame结构,跟规划程序的衔接非常顺手。我用它处理过IEEE 33节点改造网架,几十个节点的潮流一次求解在毫秒级,足够支撑遗传算法迭代几千次。
相比自己从零写潮流程序,用pandapower能省掉大量调试时间。但要提醒一句:这个库里的电气量单位必须严格统一,功率用兆伏安和兆瓦,电压用千伏,电阻电抗用欧姆。单位混用了,潮流结果看起来正常,实际可能差一百倍,这种错误最难排查。
3.2 数据准备:负荷时序、网架参数、可靠性参数
规划计算需要三类输入数据,缺一不可。
第一类是负荷时序数据。我做规划研究时一般先构造典型日曲线:季节分冬季、夏季、过渡季,日类型分工作日和休息日,再叠加一个随机波动项模拟日内不确定性。光伏出力的时序曲线也同样处理,这样潮流计算能反映分布式电源与负荷的时序配合关系。
第二类是网架参数。包括线路长度、单位电阻电抗、载流量上限,变压器的容量和短路阻抗,换流器的容量与损耗率,还有节点坐标。这些数据最好维护成独立的CSV文件,程序启动时统一读取。实际项目里用户的原始台账往往数据格式不统一,需要先做清洗。
第三类是可靠性参数。这里最费功夫,需要每个元件的故障率λ和平均修复时间r。测试算例可以从文献里找典型值,但工程项目的参数最好来自配网运检系统的历史故障记录:按设备类型统计年故障次数和平均停电持续时间,再折算成规划用的数值。我实测下来,用自主统计的数据算出的EENS,比直接套文献参数的结果更贴合业主的实际感知。
3.3 核心目标函数与约束的代码落地
目标函数写起来不复杂,难在把潮流计算嵌进优化框架。核心结构大致是这样:
def evaluate_plan(individual, network_data=None): # 1. 对规划决策进行解码,作用于网架模型 net = build_network(network_data, individual) # 2. 对每个典型日时段做潮流计算 loss_energy = 0.0 for scenario in scenarios: for hour in range(24): set_load_and_pv(net, scenario, hour) try: pp.runpp(net, algorithm="nr", tolerance_mva=1e-6) except pp.LoadflowNotConverged: return [1e10, 1e10] # 不可行方案直接给大惩罚值 loss_energy += net["res_line"]["pl_mw"].sum() * time_step # 3. 计算经济性目标 inv_cost = calc_investment(individual) om_cost = calc_om_cost(individual) loss_cost = loss_energy * price_loss annual_cost = crf * inv_cost + om_cost + loss_cost + penalty_constraint(individual) # 4. 调用可靠性评估函数 eens = reliability_assess(net, individual, reliability_params) return annual_cost, eens这段代码里有个很重要的处理:潮流不收敛时,直接返回一个极大的惩罚值,而不是让它继续参与筛选。因为不收敛往往代表方案在物理上不可行,如果加0或者很小的惩罚,遗传算法里的劣质个体会一直存活,拖慢收敛。我的经验是惩罚值设成正常目标函数上限的100倍以上,这样个体很快就会被淘汰。
约束条件的处理上,我没有把所有约束都硬塞给求解器,而是把电压越限、载流越限这类连续约束设计成惩罚项,按越限量的平方累计加进目标函数。只有拓扑约束这种0/1逻辑约束用专门的文件检查函数处理。这种做法的好处是优化过程不会因为可行性太强而陷入局部最优,前期先允许少量越限个体参与进化,后期再逐步收紧。
3.4 编码方式与求解器:为什么我没直接调商用求解器
理论上,这种规划问题可以写成混合整数非线性规划,然后用商用求解器求最优解。但实际做下来,我放弃了这条路。原因有三:第一,非凸潮流方程和双目标结构让全局最优求解变得极其困难,10节点以内还能勉强算,节点多了求解时间指数增长;第二,分布式电源和储能带来的时序耦合让整数变量规模暴涨;第三,商用求解器的授权和建模门槛对很多学生和工程人员并不友好。
我最终选用的是求解框架是NSGA-II,代码可以直接用pymoo库实现,也可以自己写基础框架。决策变量编码分两类:离散变量比如线路是否新建、导线截面等级,用整数编码;连续变量比如储能容量、光伏接入容量,用实数编码。在混合整数编码下,遗传算法的交叉和变异算子要分别处理,否则会产生非法个体。我建议在解码环节加一个修复函数,比如把越界的实数变量重新映射到可行区间,把超出预算的组合直接标记为不可行。
这种启发式算法虽然不保证全局最优,但对规划问题来说足够实用。因为工程上真正需要的是“一组在费用和可靠性之间合理取舍的方案”,而不是理论上的绝对最优解。我实测下来,种群规模60到100,迭代100到200代,IEEE 33节点改造方案的结果就已经很稳定。继续加大代数,目标值变化不大,只是白白增加计算时间。
3.5 结果可视化与多方案对比
规划结果只给两个目标值没有说服力,必须可视化。我一般画三张图:第一张是网架地理接线图,把选中的新建线路、分布式电源和储能位置标出来;第二张是帕累托前沿散点图,横轴是年费用,纵轴是EENS,把候选方案全部描在图上,给决策者直观感受取舍关系;第三张是典型日24小时的电压分布图,重点检查有没有节点电压靠近边界。
帕累托前沿图我习惯把“年费用最小方案”和“可靠性最优方案”在图上特别标记,再用文字描述两个极端方案的差异:一个偏经济、一个偏可靠,中间还有三四个折中方案。这样汇报时,业主通常自己就能看出问题,而不是被动接受程序给的一个答案。我实际经历的评审里,这种“给选择而不是给结论”的汇报方式通过率最高。
4. 可靠性评估模块的工程实现与细节
4.1 序贯蒙特卡洛:抽样、推演与统计
规划方案算出的EENS不能靠解析公式一步到位,尤其是含储能和分布式电源的方案,时序运行策略直接影响停电风险。这时候要用序贯蒙特卡洛仿真:按时间顺序模拟每个元件的运行、故障、修复过程,累计系统失负荷事件。
实现逻辑并不复杂,核心是对每个元件抽样它的无故障工作时间TTF和修复时间TTR:
TTF = -(1/λ) × ln(U)
TTR = -r × ln(U)
其中U是0到1之间均匀分布的随机数。每产生一次故障事件,仿真时间就跳到下一次故障发生的时刻,然后判断此刻系统是否出现失负荷。系统状态更新后,还要按修复时间生成下一次元件的运行时段。如此循环推进,仿真一整年或很多年,统计总的缺供电量除以仿真年数,就得到EENS。
这个算法直接用Python写很容易:
def monte_carlo_sim(net, components, hours=87600, seed=42): rng = np.random.default_rng(seed) clock = 0.0 outage_energy = 0.0 # 初始化所有元件的下一次事件时间 next_event = {} for comp in components: next_event[comp.id] = rng.exponential(1 / comp.lam) # TTF while clock < hours: comp_id = min(next_event, key=next_event.get) clock = next_event[comp_id] # 检查当前系统状态是否有失负荷 loss = check_load_loss(net, comp_id, clock) if loss > 0: outage_energy += loss # 生成修复时间,然后安排下一次故障 repair = rng.exponential(comp.r) next_event[comp_id] = clock + repair + rng.exponential(1 / comp.lam) return outage_energy / (hours / 8760)实际做的时候要注意:仿真时长不能太短,否则随机波动太大。一般建议仿真年限不少于100年,也就是876000小时。这样EENS的方差系数才能降到可接受水平。为了加速,我通常先用公式法估算一个基准EENS,再用蒙特卡洛在最终方案上做验证,而不是把原始方案也全部跑一遍。
4.2 枚举法和序贯法怎么搭配
状态枚举法(也叫故障模式影响分析法)的思路是枚举所有一阶或二阶故障事件,算出每个故障场景下的失负荷量和持续时间,再按概率加权求和。它比序贯蒙特卡洛快得多,适合在优化迭代的初期阶段做大规模筛选。
实际操作中我是这样搭配的:整个优化过程里,候选方案先用枚举法快速算EENS作为目标函数;等遗传算法收敛后,把帕累托前沿上的十来个方案拿出来,再用序贯蒙特卡洛做精细评估。这样既保证了优化搜索的高效率,又保证了最终方案的指标可信度。直接全程用序贯蒙特卡洛配NSGA-II也不是不行,但一天只跑得完一两代,心态容易崩。
枚举法的另一个作用是诊断薄弱环节。它可以统计每个元件故障造成失负荷的概率和电量占比,找出网架里的关键设备。我做完可靠性评估后,经常会额外输出这个“薄弱元件排行表”,比单纯给一个EENS数字更能指导后续改造决策。
4.3 评估结果如何反哺规划方案
可靠性评估不是终点,它的结果要回传到优化模型里形成闭环。我在代码里处理后,优化迭代每一代的统计结果都会写到日志,包括当代最优年费用、EENS、最大电压越限量。通过观察这些数值的变化,我能判断算法是否收敛、是否陷入局部最优。
比如有一个加了储能方案的案例,首轮优化EENS很高,查看薄弱元件排行后发现是直流母线所带的敏感负荷侧变压器故障率太高。于是我把换流器容量和线路规格作为一个待优化变量重新放进去,第二轮就明显改善了。如果没有可靠性评估的反哺,这个问题只靠直觉很难定位到具体元件。
另外,可靠性参数对规划结果的影响远大于很多人的预期。故障率参数提高一倍,最优方案会自动倾向于多分段、多联络,投资额明显上升。因此做结论前一定要做参数敏感性分析,至少把关键元件的故障率上下浮动20%再各算一遍,看方案排序有没有变化。如果排序稳定性差,说明规划结果对可靠性参数过于敏感,这时候建议业主先去补强数据基础。
5. 我实测中踩过的坑和排查方法
5.1 潮流不收敛,先查这五件事
我用pandapower做规划时,碰到潮流不收敛,90%以上是下面五个原因:
第一,线路参数电阻电抗值输入错误,比如把毫欧当欧姆、把单相值当成三相值;第二,变压器分接头设置不合理,导致无功潮流不平衡;第三,分布式电源节点的初值电压设得太离谱,牛顿-拉夫逊法直接发散;第四,直流线路模型里的损耗参数单位理解错误,导致换流器有功越限;第五,孤岛节点没有平衡电源,系统出现功率缺额。
排查方式也有固定套路:先减小负荷到0试试,如果收敛,说明是线路参数或过载问题;如果还不收敛,检查交流母线电压初值,再逐个断开分布式电源定位。这个顺序能帮你快速缩小范围,避免在模型里瞎猜。
5.2 蒙特卡洛仿真慢得没法用怎么办
我最早跑测试算例时,仿真十年、元件三十个,一个方案要跑快一分钟,放在遗传算法里完全没法接受。后来总结出三个提速手段。
第一个手段是用方差缩减方法,把随机数种子固定,用共同随机数比较不同方案,这样方案之间的差距主要由系统差异决定,而不是由随机波动决定,能显著减少需要的仿真年限。第二个手段是把影响小的低故障率元件单独用解析公式处理,只对关键元件做序贯抽样。第三个手段是并行计算,每个CPU核心跑一个独立仿真任务,最后汇总统计量,程序基本能线性加速。
这三个手段叠加起来,我的最终计算时间从每个方案一分钟降到了几秒,优化过程才算跑得起来。
5.3 权重系数主观性太强,怎么让最终方案更有说服力
做加权单目标时,总有评审人问“权重凭什么这么取”。我现在的应对办法是不再纠结于权重,改用帕累托前沿配合多准则决策来收尾。这样权重的作用从“唯一的决定因素”退化为“后续排序的参数之一”,争议小很多。
即便用加权法,我也会先肉眼观察前沿图的形状再做归一化。如果前沿在中段有明显的“膝点”,也就是增加一点投资可靠性提升特别大的转折区域,我会直接建议业主把膝点附近的方案作为推荐项。这个膝点分析比任何权重公式都好解释,也更符合工程直觉。
另外有几次项目,我把帕累托前沿上规模相近的多个方案做了等年值总费用和全生命周期停电损失的对冲计算,发现最优方案选择对VOLL取值非常敏感。因此做项目建议时,我会把VOLL取值的口径单独列一章,明确告诉大家结论在什么参数边界内成立。
6. 个人经验总结与扩展思路
6.1 给新手的建议:上手路径和参考顺序
刚接触这类研究的同学,不要一上来就搭完整双目标框架。我的建议分三步走:第一步,先用pandapower跑通一个固定网架在不同负荷水平下的潮流,把交流和直流混合建模的基本操作熟悉到不用看报错信息的程度;第二步,在固定网架上做可靠性评估,先用公式法算EENS,再写一个简单的序贯蒙特卡洛程序验证一遍;第三步,把优化算法加进来,从加权单目标开始,跑通了再改成NSGA-II。
每一步都要留好测试用例,比如IEEE 33节点改造网架。所有程序模块都准备好后再拼装,拼接时最容易出问题的就是数据格式不匹配,所以最好早早在代码里定义统一的DataFrame结构作为模块间接口。
6.2 后续可扩展的三个技术方向
第一个方向是加入时序运行优化。当前模型里的运行方式偏向固定规则,储能充放电策略往往是经验曲线。如果后续加入基于滚动优化的运行策略嵌入,规划结果会更符合实际,但计算量会大很多。
第二个方向是考虑多维不确定性。光伏出力和负荷预测都有随机性,单靠典型日曲线会低估风险。下一步可以用场景概率方法或者分布鲁棒优化来刻画不确定性,规划结果会更抗风险。
第三个方向是结合数字孪生做动态更新。规划做完后,实际运行数据会持续累积,利用故障率更新算法和负荷增长率预测,让规划模型可以定期重算。这一点在实际工程中的价值最大,也是我最近在做的事情。
做这套程序最大的体会是,规划结果的可靠程度其实由底层数据决定。代码写得多漂亮,如果负荷曲线、故障率参数、单位造价这些基础数据没夯实,算出来也是精致的错误。反而是那些基础数据扎实、模型适当简化的方案,在工程评审里站得最稳。做这个方向的朋友,建议把精力多分一点到数据清洗和参数校核上,回报往往比多调优化算更大。