一个做配网规划的朋友跟我说,他们在做分布式光伏接入方案时,最头疼的不是装机容量,而是“接在哪、接多大、能不能扛住故障”。这正是混合配电系统规划的核心。所谓混合配电系统,就是传统单电源辐射网里融入了分布式光伏、风电、储能等有源设备;而可靠性评估则是判断这套混合系统在设备故障时还能不能稳住、会不会大面积失电的关键手段。这个项目就是用Python,把经济和可靠性两个目标一起放进优化框架里,搜索分布式电源的最优接入位置和容量,最终输出兼顾投资成本和供电可靠性的规划方案。对电气专业做配电网方向的学生、设计院做可研的工程师,这套代码都能直接用来跑算例、出曲线、写分析结论。
项目本身不算特别复杂,但链路很长:目标建模、潮流计算、可靠性评估、智能优化算法,一环套一环。任何一个环节的参数给错了,整体结果就离谱。下面我把整个项目的思路、数学模型、求解算法、可靠性评估细节、算例结果和调试经验一次说清楚。
1. 项目要解决的核心问题与整体思路
1.1 混合配电系统带来了什么新问题
传统配电网是单向供电、无源网络,规划人员只需要确定变电站容量、线路型号、供电半径,基本上用“N-1校验+电压降校核”就能完成方案比选。但分布式电源接入后,系统变成了“多电源、双向潮流”的状态。光伏中午大发引起电压升高,风电夜间波动导致频率支撑变弱,储能充放电又在改变负荷曲线。这些问题单靠加大导线截面是解决不了的,必须从电源布点这个源头上去做优化。
更麻烦的是,分布式电源本身也是故障单元。逆变器故障、箱变检修、风机停机,任何一个环节出问题,都有可能导致下游负荷失电。所以“混合配电系统”的规划,不能只看DG接入后的静态潮流,还要看系统在线路或设备故障时能不能通过DG孤岛运行、联络线转供等方式保住关键负荷。这个诉求直接引出了项目里的第二块核心:可靠性评估。
1.2 经济性与可靠性为什么是“拧着”的目标
经济目标很好理解:总投资、运维费、网损费、购电费,加起来越小越好。但可靠性目标和经济目标天然存在矛盾。多加一条联络线、多配一组储能、多装一台变压器,可靠性一定提升,但投资也一定增加。反过来,如果只追求经济最优,把DG容量全部堆在电价最高或线损最严重的末端节点,可靠性评估时你可能会发现,一台主变故障就能让一大片负荷失电。
项目里把这两个目标放在同一个目标函数下。可靠性的量化指标我用的是EENS,也就是系统全年期望缺供电量,单位是MWh/年。这个指标把“停电概率”和“停电损失负荷”乘在一起,单位是电量,正好可以和年综合费用的“元/年”通过电价做归一化,放在同一个多目标框架里非常自然。
1.3 技术路线:为什么选择双层优化模型
这个项目采用双层模型,思路很直观:
| 层级 | 决策变量 | 求解方法 | 返回给上层的信息 |
|---|---|---|---|
| 上层优化 | DG接入节点、DG容量、储能配置 | 遗传算法/粒子群算法 | 目标函数值、约束越限惩罚量 |
| 下层评估 | 潮流状态、故障停电范围 | 前推回代潮流 + 蒙特卡洛/故障枚举 | 网损、最低电压、EENS、SAIFI |
上层负责“找方案”,下层负责“算指标”。每次上层生成一组DG接入方案,下层就做一遍潮流计算和可靠性评估,把结果返回给上层作为适应度。两层迭代循环,直到优化算法收敛。这样做的好处是把非线性很强的综合规划问题拆成了两个相对清晰的子问题——一个是组合优化,一个是状态评估,调参和Debug都方便。我跑下来最大的感受是:如果你把“可靠性和经济性”揉在一个单层模型里硬解,收敛性会很差;分层之后,每一层都有明确输入输出,出了问题能很快定位。
2. 数学模型构建:目标函数、约束与变量
2.1 经济性目标:年综合费用怎么算
年综合费用由四部分组成:投资等年值、运维成本、网损费用、向上级电网购电费用。表达式可以写成:
[ C_{total} = C_{inv} + C_{om} + C_{loss} + C_{buy} ]
其中投资这一块需要做“等年值折算”,就是把一次性投入分摊到运行年限的每一年。这和买房按揭是一个道理,一套房200万、按揭20年,每个月要还月供,而不是第一年直接付200万。等年值系数公式是:
[ CRF = \frac{r(1+r)^n}{(1+r)^n - 1} ]
当折现率r=8%、运行年限n=20年时,CRF算出来约等于0.10185。也就是说,一笔1000万的初始投资,折算到每年大约是101.85万元的等年值成本。这个系数我在代码里是单独写了个函数,避免每个算例都重算一遍。
DG的运维成本按发电量计费,光伏每kWh给0.05元,风机每kWh给0.06元,储能按充放电量0.02元/kWh。网损费用用典型日负荷下的潮流结果估算,取“年损耗小时数”折算。注意这里有个细节:DG接入位置不同,网损差异很大,尤其是末端节点接光伏,重载线路上的网损下降非常明显,这也是优化算法能真正发挥作用的地方。
2.2 可靠性目标:从SAIFI到EENS
可靠性评估不只是算一个指标,常用的有这些:
| 指标 | 含义 | 单位 |
|---|---|---|
| SAIFI | 用户年平均停电次数 | 次/(户·年) |
| SAIDI | 用户年平均停电持续时间 | 小时/(户·年) |
| ENS | 系统年缺供电量 | kWh/年 |
| EENS | 期望缺供电量(含概率意义) | kWh/年或MWh/年 |
项目里的优化目标用的是EENS。它的计算思路是:枚举每条线路和主变发生故障的场景,计算该场景的发生概率、故障修复时间、受影响负荷大小,然后累加:
[ EENS = \sum_{f \in F} P(f) \times r_f \times P_{load,outage}(f) ]
其中P(f)是故障场景f的年平均发生概率,r_f是平均修复时间,(P_{load,outage})是该场景下失电的负荷功率。如果系统有联络线路,部分负荷可以通过转供恢复供电,那么在计算失电负荷时要扣掉转供成功的部分。DG能否孤岛运行也直接影响这个指标——如果能孤岛,那故障情况下DG覆盖范围内的负荷可以继续供电,EENS明显降低。
2.3 约束条件:怎么设置才不“纸上谈兵”
优化模型里的约束条件必须贴合工程实际,否则结果没法落地。我在模型里加了这几类约束:
- 潮流约束:系统必须满足有功和无功功率平衡,潮流方程要收敛。
- 节点电压约束:正常情况下各节点电压保持在0.95~1.05倍额定电压,也就是±5%的合格范围。DG接入过多导致电压越上限是常见问题,我会在目标函数里加惩罚项。
- 支路电流约束:每条线路的电流不超过其长期允许载流量。
- DG容量约束:单个节点的DG接入容量不超过该节点峰值负荷的一定比例,整个系统的DG总有功容量不超过总负荷的40%,防止渗透率过高带来的稳定性问题。
- 储能SOC约束:储能荷电状态保持在10%~90%之间,避免过充过放。
这些约束不是全部写死,而是可以在配置文件中调整。做实际项目时,约束条件要根据当地的并网导则和电网公司的要求来改,比如某些地区要求渗透率不超过25%,那就在config里改一个参数就行。这种参数化的设计,是代码能复用到不同算例的关键。
3. 求解算法选型:为什么用智能优化算法
3.1 问题复杂度决定算法选择
这个规划问题本质上是一个混合整数非线性优化问题。DG接在哪是整数变量(节点编号),接入容量是连续变量,潮流方程是非线性的,可靠性评估又是一个组合爆炸的枚举过程。对于33节点系统,候选节点十几个,容量等级上百种,组合空间已经是百万量级;如果扩展到69节点、123节点,穷举根本不可行。
理论上可以用混合整数二阶锥规划等解析方法,但对辐射状配电网的“N-1可靠性约束”建模非常痛苦。工程上大家更习惯用遗传算法、粒子群这类智能优化算法,虽然不是数学意义上的全局最优,但胜在建模灵活,改约束、加惩罚项都很方便,而且经过合理调参后结果通常是接近最优的。用Python生态实现,numpy做矩阵运算、pandas管理数据、matplotlib出图,全部开源,不用商业求解器。
3.2 粒子群和遗传算法怎么配合
项目里我同时实现了粒子群算法和遗传算法,方便对比结果:
| 对比项 | 粒子群算法 | 遗传算法 |
|---|---|---|
| 编码方式 | 连续实数编码 | 二进制/整数编码 |
| 种群大小 | 50 | 100 |
| 迭代次数 | 100 | 200 |
| 核心参数 | 惯性权重0.8衰减到0.4,c1=c2=2.0 | 交叉概率0.8,变异概率0.1 |
| 优点 | 收敛快、实现简单 | 全局搜索能力强,适合离散变量 |
| 缺点 | 容易早熟,后期收敛慢 | 参数敏感,计算量大 |
DG接入节点是离散的,用遗传算法编码更自然;DG容量是连续的,粒子群更好用。我实际的工程方案是:遗传算法负责优选“节点组合”,每个结点上再嵌套粒子群优化连续容量。当然,嵌套结构写起来更复杂,初学者可以先用统一的“离散化容量等级”方案,把容量划分成100kW、300kW、500kW、800kW等几个档位,这样遗传算法一套就能解决。
3.3 适应度函数在Python里怎么写
适应度函数的输出直接决定优化方向,代码结构大致是:
def fitness(solution): # 1. 解码:从染色体/粒子向量解析出DG接入节点和容量 nodes, caps = decode(solution) # 2. 构建潮流模型,计算节点注入功率 V, P_loss = run_powerflow(nodes, caps) # 3. 约束校验:电压、支路电流、渗透率 penalty = 0.0 if np.min(np.abs(V)) < 0.95: penalty += 1e5 * (0.95 - np.min(np.abs(V))) if P_loss / total_load > 0.1: penalty += 1e4 * (P_loss / total_load - 0.1) # 4. 可靠性评估(故障枚举或蒙特卡洛) EENS = evaluate_reliability(nodes, caps) # 5. 双目标加权,加惩罚 cost_total = annual_cost(nodes, caps, P_loss) return w * cost_total / C_base + (1 - w) * EENS / EENS_base + penalty注意两个细节。第一,经济量和缺供电量的量纲不同,必须先归一化,否则权重w完全失真,比如成本是百万量级而EENS是几十MWh,不归一化的话EENS在目标函数里直接被淹没。第二,惩罚项系数不能拍脑袋,太小约束不起作用,太大会让优化算法把大量计算浪费在无效方案上。我一般从1e3起步,跑通后根据越限程度再调。
用pandas存负荷和线路参数时,我习惯用DataFrame存原始数据,提取时用to_numpy()转成numpy数组,float64一步到位。处理线路首末端节点索引时经常要数组切片操作,比如line_from = line_data['from_bus'].to_numpy() - 1(节点编号从1开始转成0索引),这类细节出了问题很难排查,锯断血泪教训是最好一开始就统一索引风格。
4. 可靠性评估的工程实现
4.1 解析故障枚举还是蒙特卡洛模拟
可靠性评估有两种主流做法:解析法和模拟法。解析法就是把所有可能的故障场景枚举出来,计算每个场景的概率和后果。配电网规模不大,线路几十条、配变几十台,枚举所有单重故障是可行的。模拟法(序贯蒙特卡洛)则用随机数模拟设备“运行-故障-修复”的过程,每次抽样统计停电事件。
我建议在规划优化阶段用解析枚举法。原因很简单:可靠性评估在优化算法内部被反复调用,每次都是几十上百次,蒙特卡洛模拟需要抽几千个随机数才能稳定,计算量大到不可接受。解析法只要把所有线路遍历一遍,很快就能得到EENS的估计。等优化完成后,再用蒙特卡洛做一次详细的验证评估,两者互相印证。
4.2 设备停运模型与失负荷判断
设备的停运参数根据工程统计数据设定:
| 设备类型 | 故障率 | 平均修复时间 |
|---|---|---|
| 10kV架空线路 | 0.06次/(km·年) | 5小时 |
| 配电变压器 | 0.015次/(年·台) | 10小时 |
| 分布式电源 | 0.02次/(年·台) | 20小时 |
比如说一条5公里长的线路,年故障率就是0.3次/年,每次故障平均5小时。那么这台设备导致的年停电期望时间就是0.3×5=1.5小时/年。EENS再乘以该场景下失电的负荷功率。
故障场景发生后,失负荷判断是可靠性评估的核心逻辑。一条线路故障后,先通过分段开关将故障隔离,然后判断故障点下游区域是否可以通过联络线路转供电,或者在DG容量充足的情况下孤岛运行。如果既不能转供也不能孤岛,那这部分负荷就要等到故障修复后才恢复。这部分我用邻接矩阵加深度优先搜索遍历来实现——先把配电网拓扑构造成稀疏邻接矩阵,故障隔离时把故障边移除,再搜索哪些节点与根节点失去连通。
4.3 Python里的评估流程与代码骨架
可靠性评估的代码结构可以精简成这样:
def evaluate_reliability(nodes, caps): total_EENS = 0.0 # 故障枚举:每条线路、每台主变算一个场景 for fault_device in all_faultable_devices: p_fault = fault_device.lambda_rate * fault_device.repair_hours / 8760 outage_power = find_outage_load(fault_device) # 扣掉联络转供和DG孤岛恢复的部分 restored = compute_restored(fault_device, nodes, caps) outage_power -= restored if outage_power > 0: ens = p_fault * outage_power * fault_device.repair_hours total_EENS += ens return total_EENS需要注意,在优化迭代过程中,每一代都要评估几十个方案,每个方案又要枚举几十次故障。所以这个函数必须是高效的。我优化后的思路是提前把配电网拓扑、线路长度、负荷分布这些不变的数据固化下来,故障枚举时只更新“有DG接入的节点”,这样故障场景的判断可以大量复用缓存结果,速度能提升好几倍。
在蒙特卡洛最后验证阶段,随机数种子要固定。我用np.random.seed(42),这样每次跑结果都一样,方便复现。否则你写论文时同一组参数跑两次结果不同,审稿人第一个问题就是“结果是否可复现”,会很被动。
5. 算例测试:以IEEE 33节点系统为例
5.1 算例基本参数
IEEE 33节点系统是配电网规划的经典测试系统,基准电压12.66kV,节点1接上级变电站,系统总负荷约3715kW加2300kvar。网络有33个节点、32条支路,加上5条联络开关支路(正常运行时分段开关闭合、联络开关打开)。
项目里我把负荷数据和线路参数放在两个CSV文件中,用pandas读取。候选DG接入节点不是所有节点都行,根据工程上“避免在联络节点和重要用户节点接入”的原则,我选了6、9、12、15、18、21这几个位置作为候选。
DG参数设置如下:
| DG类型 | 单位投资成本 | 运维成本 | 单点容量范围 |
|---|---|---|---|
| 光伏 | 8000元/kW | 0.05元/kWh | 100~1500kW |
| 风电 | 9500元/kW | 0.06元/kWh | 100~1200kW |
| 储能 | 2500元/kWh | 0.02元/kWh | 200~2000kWh |
5.2 前推回代法潮流计算
潮流计算是整个评估的底层。对于辐射状配电网,前推回代法是最经典的算法,原理很简单:先假设全系统电压为额定值,由末端向首端逐段计算支路电流和功率,这叫“回代”;然后从首端向末端逐段更新节点电压,这叫“前推”。反复迭代,直到两次电压差最大值小于1e-6。
def radial_powerflow(load_p, load_q, dg_p, dg_q, line_data, node_order): n = len(load_p) V = np.ones(n, dtype=complex) for iteration in range(100): V_old = V.copy() S_node = (load_p - dg_p) + 1j * (load_q - dg_q) I_branch = np.zeros(len(line_data), dtype=complex) # 回代:按从末梢到根的顺序计算支路电流 for line_idx in reversed(node_order): child = line_data['to_node'][line_idx] P = S_node[child].real Q = S_node[child].imag I = np.conj(complex(P, Q) / V[child]) I_branch[line_idx] = I parent = line_data['from_node'][line_idx] S_node[parent] += complex(P, Q) + abs(I)**2 * line_data['Z'][line_idx] # 前推:按从根到末梢的顺序更新电压 for line_idx in node_order: parent = line_data['from_node'][line_idx] child = line_data['to_node'][line_idx] V[child] = V[parent] - I_branch[line_idx] * line_data['Z'][line_idx] if np.max(np.abs(V - V_old)) < 1e-6: break return V这里最需要注意的就是“遍历顺序”。前推回代法要求严格按照树的父子关系推进。我先用深度优先搜索从根节点1开始生成一个拓扑遍历数组,保证任何时候计算某个节点时它的父节点电压已经被更新过。不按这个顺序算,程序不报错,但结果一定是错的。
DG接入后,候选中光伏和风电都按恒功率因数(PQ节点)建模,功率因数取0.95。储能可以根据运行策略在充电和放电之间切换,以负荷曲线为基础设定了削峰填谷策略。
5.3 优化结果对比
我跑了三组方案作为对比:无DG原始方案、单目标只优化经济性、双目标兼顾经济与可靠性。结果如下:
| 规划方案 | 年综合费用(万元) | EENS(MWh/年) | 最低节点电压(p.u.) |
|---|---|---|---|
| 无DG原始方案 | 386.5 | 32.4 | 0.9406 |
| 只优化经济目标 | 327.8 | 24.6 | 0.9571 |
| 双目标折中方案 | 341.2 | 15.3 | 0.9683 |
从结果能明显看出:只优化经济,年综合费用确实最低,比无DG方案省了约58.7万元/年,但可靠性指标改善有限,EENS只降了24%。双目标折中方案虽然年综合费用比单目标多了13.4万元,但EENS降到了15.3MWh/年,比单目标方案再降38%,比原始方案降了53%。同时最低电压从0.9406提升到0.9683,电压质量明显改善。工程上多花13万元换取每年少停约9000kWh电,这个性价比在很多用电敏感区域是非常划算的。
5.4 帕累托前沿怎么用
双目标优化的结果不是独一个点,而是一条帕累托前沿。我用线性加权法,把权重系数w从0按0.05的步长取到1,得到一系列非支配解。画图时用matplotlib的scatter绘制年综合费用和EENS的散点,横轴是EENS,纵轴是年综合费用。
画图时有个小坑:如果不做任何处理,横坐标刻度会自动分配,可能特别密集或者重叠。我在代码里用locator_params更精细控制坐标轴:
plt.scatter(eens_list, cost_list, c=dg_capacity_list, cmap='coolwarm', s=60) plt.title('Pareto Front of Economy and Reliability') plt.xlabel('EENS (MWh/year)') plt.ylabel('Annual Total Cost (10^4 CNY)') plt.gca().xaxis.set_major_locator(MaxNLocator(nbins=8)) plt.xticks(rotation=45) plt.tight_layout() plt.savefig('pareto_front.png', dpi=300)最终选哪个解,取决于决策者的偏好。比如电力公司更看重供电可靠性,那就选eens小的解;如果投资收益要求高,就选成本低的解。这种“先画出前沿,再让人拍板”的做法,比直接给一个最优解更容易被工程评审接受。
6. 常见问题与避坑指南
6.1 前推回代法不收敛怎么办
这个我在跑69节点系统时遇到过好几次,基本上就三种原因:
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 迭代100次不收敛 | 遍历顺序生成错误 | 用DFS/BFS重新生成节点顺序,检查根节点编号 |
| 电压出现负值或NaN | DG容量过大导致潮流无解 | 减小DG容量上限或加大惩罚系数 |
| 收敛但结果与商用软件偏差大 | 阻抗单位换算错误 | 确认Z是用欧姆而不是标幺值,检查功率单位统一性 |
记忆最深刻的一次是把线路阻抗单位搞错了,导线参数表里给的是Ω/km,乘线路长度时忘了换算,算出来的网损直接翻倍,优化算法疯狂把DG往末端怼。后来我在代码里加了单位断言,凡是阻抗值超过10欧姆的一律报警,这种低级错误才算彻底堵住。
6.2 蒙特卡洛模拟的方差和样本量
可靠性评估里如果用的是序贯蒙特卡洛,抽样年数太短,EENS的方差会非常大。我实测过,抽样500年年和1000年,结果能差20%以上;1000年和5000年,差5%以内。
所以我的建议是:在优化迭代内部用解析枚举法,速度快且稳定;只有最终方案验证才用蒙特卡洛抽几千个场景,并且固定随机种子,这样既保速度又保精度。还有一种办法是方差缩减技术,用拉丁超立方抽样替代纯随机抽样,在不增加样本量的情况下明显减小方差。项目里我把LHS抽样做成了一个可选项,有需要时可以直接打开。
6.3 Python环境和工具链的工程问题
这个项目依赖的库不多:numpy、pandas、matplotlib。安装方法很简单:
pip install numpy pandas matplotlib如果电脑上同时有多个Python版本,一定先激活虚拟环境再装库,否则库装到了别的环境里,import时报ModuleNotFoundError。我在vscode里配置过很多次Python环境,心得是:在项目根目录创建一个.venv虚拟环境,然后在vscode右下角把解释器切到虚拟环境路径,这样依赖隔离,换一台电脑用一个requirements.txt就能重建开发环境。
python -m venv .venv .venv/Scripts/activate # Windows source .venv/bin/activate # Linux/Mac pip install -r requirements.txt另外提醒一句,numpy版本和Python版本有对应关系。比如Python 3.8只能用numpy 1.24.x及以下,直接pip install numpy的话可能装上太新的版本导致兼容性问题。如果你遇到“module compiled with a newer Python”这类报错,大概率是版本问题,用指定版本号重装即可。
6.4 优化过程中的性能优化
还有一个常见的问题是“算法跑不动”。种群数50、迭代100代,每代要评估50个方案,每个方案要做几十次故障场景的潮流计算,算下来是十万次以上的潮流计算,纯Python循环确实慢。
我做了几项优化:
- 矢量化和预计算:把不需要每代更新的数据(线路阻抗、网络拓扑顺序)提前算好,避免重复构建。
- numba加速:在潮流函数前加@njit装饰器,把函数转成机器码,运行速度比纯Python快几十倍。
- 多进程并行:粒子群评估种群时,每个粒子的适应度是独立计算的,用multiprocessing.Pool并行评估,8个核能压榨到接近满负荷。
from multiprocessing import Pool def evaluate_population(population): with Pool(processes=8) as pool: fitness_values = pool.map(fitness, population) return fitness_values实测下来,33节点、50个粒子、100次迭代,加了这三板斧后,整体耗时从四十多分钟降到了三四分钟。这才真正让双目标优化的反复实验成为可能。
7. 代码结构设计与后续扩展方向
7.1 工程目录怎么组织
一个能长期使用的规划项目,代码目录必须清晰。我是这么组织的:
project/ ├── data/ │ ├── ieee33_load.csv │ ├── ieee33_line.csv │ └── dg_config.json ├── core/ │ ├── powerflow.py │ ├── reliability.py │ ├── optimization.py │ └── main.py ├── result/ │ ├── pareto_front.png │ ├── best_solution.csv │ └── output_log.txt └── requirements.txtdata目录存算例数据,core目录存业务逻辑,result目录存输出结果和图表。main.py是入口,负责把数据、潮流、可靠性、优化四个模块串起来,并且把所有关键中间结果打印到日志文件里。
7.2 两个值得反复说的实现细节
第一个是节点编号问题。IEEE 33节点的原始数据里,节点编号从1开始,但Python数组索引从0开始。我在读数据后做了一次统一的-1处理,后续所有函数都基于0索引运算。如果你某个环节忘了减1,程序不一定会报错,但算出来的拓扑关系就是错乱的。解决的办法是在程序启动时做拓扑自检,计算所有支路的首端节点是否在节点集合内,不在就立刻报错。
第二个是随机种子问题。优化算法本身是随机的,如果不固定随机种子,每次运行出的帕累托前沿都不完全一样。做科研、写报告都需要可复现性,所以main.py里我设置了全局随机种子,并且把每次迭代的随机种子也固定下来。你在复现这个项目时不要改动种子,不然出来的图和我的对不上。
7.3 这个项目还能怎么扩展
现在这个版本做的是静态双目标规划,后续扩展空间还很大:
- 多目标优化算法升级:把线性加权法换成NSGA-II,可以一次得到更完整的帕累托前沿。
- 时序运行模拟:把单典型日扩展成8760小时连续仿真,储能策略、光伏随天气波动、电动汽车负荷都能纳入。
- 弹性评估:除了可靠性,还可以评估系统在极端自然灾害(台风、冰灾)下的韧性和恢复过程,这是目前非常热门的方向。
- 真实配电网接入:把IEEE标准算例换成实际网格的GIS/CIM模型,拓扑更复杂,但代码框架不用推倒重做。
这些扩展方向,我在代码里都预留了接口,比如可靠性评估现在返回的是EENS默认值,但已经支持多指标扩展返回SAIFI、SAIDI,后续要加指标只是改一个函数的事。
跑通这套代码,我自己最大的体会是:配电网规划的技术门槛并不全在算法多先进,而在模型严谨和细节经得起推敲。双层优化模型本身很简单,难的是把潮流计算、故障枚举、目标函数三套逻辑耦合在一起之后,每个参数都有迹可循,每次异常结果都能定位到具体环节。做这类项目,我建议你先跑通最小系统,确认每个模块输出合理,再逐步增加DG配置、联络开关、储能策略这些复杂度。等拥有一份稳定可复现的结果之后,回过头来调权重系数、看帕累托前沿,你一定会发现工程决策里的取舍比数学公式有意思得多。