搞交直流混合微网优化的人,大多绕不开一个问题:风光出力不是定值,怎么拿一个确定性的模型去做调度?我之前做仿真的时候也在这上面折腾了很久。后来把拉丁超立方抽样、多场景缩减和粒子群算法串起来,才算把“随机性”这关真正迈过去。这篇就完整分享一下这个基于MATLAB的交直流混合微网程序的设计思路、每一步的实操要点,以及我踩过的坑。不管你是刚接触微网优化,还是想把手头确定性模型改成场景规划,这篇都能给你一个能直接参考的技术路线。
1. 为什么交直流混合微网值得建模:从单场景到随机规划的跃迁
1.1 交直流混合微网的核心架构与建模难点
交直流混合微网不是把交流系统、直流系统简单拼在一起,它同时包含交流母线和直流母线,两者之间通过电压源型换流器(VSC)连接。交流侧可以挂常规负荷、微型燃气轮机、交流风电;直流侧可以直接接入光伏、储能电池和部分直流负荷。这样做最大的好处是减少了DC-AC-DC反复换流带来的损耗,光伏和储能直流接入可以省一级逆变器,系统效率更高,控制灵活性也更好。
但这个结构给仿真程序带来不少麻烦。传统交流微网用常规潮流计算就行,这里需要处理交直流耦合。直流母线电压、交流母线电压幅值和频率、换流器传输功率、无功补偿都要同时满足约束。有时候交流侧频率波动会通过换流器传到直流侧,导致直流电压闪变。程序里如果只各自独立建模,忽略耦合关系,算出来的运行方案很可能在动态场景下根本执行不了。
我做这个程序时,思路是先确定母线和设备节点编号,把交流部分、直流部分分别列写功率平衡方程,再用换流器方程把两侧耦合起来。每台VSC需要设定传输功率的上下限,以及功率因数范围。这些细节看似繁琐,但直接影响后续优化模型能否得到合理结果。
1.2 风光随机性到底有多影响调度结果
光伏出力和风速都受天气影响,不是一个固定数值。拿光伏来说,云层遮挡几分钟就能让出力下降50%,而风电更是“看天吃饭”,爬坡率和波动幅度都很大。如果调度模型里把光伏、风电当固定值处理,那么算出来的储能有电时段、燃气轮机启停方案,在真实场景下往往会失效。
举个例子:某天的预测光照峰值在12点,实际在10点半就达到峰值。确定性模型会安排储能尽量中午充电,实际则应该上午就充满。结果可能是光伏弃光率增加,燃气轮机被迫多发电,成本大幅上升。更严重的,如果调度方案没有给足够备用,波动来临时换流器可能过载,直流母线电压越限。要避免这种情况,就必须把不确定性纳入模型,而不是等发现偏差后再去改结果。
1.3 为什么不能一步到位用确定性优化:随机规划的思路
处理随机性的主流方法之一就是场景法。它的核心是用一系列可能出现的风光出力曲线(即场景)来代表未来的不确定性,并给每个场景赋予一个概率,优化目标变成这些场景下的期望成本最小。这样得到的决策不是针对某个特定场景最优,而是在所有可能情况下整体最优。
场景法的关键就落在两件事:第一,怎么生成足够逼近真实概率分布的初始场景;第二,场景太多会造成优化模型规模爆炸,怎么在不明显失真的前提下削减场景数量。拉丁超立方抽样解决前者,同步回代削减或聚类算法解决后者。生成若干个代表性场景之后,再和粒子群算法结合,对决策变量进行寻优。
这种“抽样-缩减-寻优”的路线,在国内外微电网规划、调度文献里已经很成熟。我用下来觉得它在MATLAB里实现并不算复杂,但每一步都有不少容易忽略的细节,下面拆开讲。
2. 关键技术拆解:拉丁超立方抽样与场景缩减如何工作
2.1 拉丁超立方抽样的原理与实现要点
蒙特卡洛抽样虽然简单,但要用大量样本才能保证统计精度。拉丁超立方抽样(Latin Hypercube Sampling, LHS)是一种分层抽样方法,它先把每个输入变量的概率分布均分成若干等分区间,在每个区间里随机抽取一个值,然后把各变量的样本随机组合。这样只要较少的样本数,就能比较均匀地覆盖整个分布空间,样本方差远小于普通随机抽样。
在MATLAB里用LHS非常方便,你可以直接用自带的lhsdesign函数生成一个N行d列的矩阵,矩阵元素都在0到1之间,并且每一列都有分层特征。然后把这个矩阵当作累计概率值,通过逆变换法转换成实际分布样本。
以风速为例,风速通常用两参数Weibull分布描述,逆变换函数是:
% 生成200个服从Weibull分布的风速样本 N = 200; k = 2.0; % 形状参数 c = 8.5; % 尺度参数 u = lhsdesign(N, 1); % 拉丁超立方抽样,生成0~1均匀分布的样本 wind_speed = wblinv(u, c, k); % 用逆CDF变换得到风速这段代码看上去很简短,但有两个容易踩的坑。第一个,lhsdesign返回的样本不是直接用的分布值,一定要经过逆CDF变换;第二个,默认lhsdesign会对相关性做随机化,如果你需要多个变量间保持一定相关性,要用拉丁超立方抽样结合Cholesky分解或者Copula函数。对于风光联合场景,常见做法是分别仿真,再用相关系数矩阵旋转样本,否则会出现风电大出力时光伏也大出力这种不合理组合。
2.2 场景缩减方法:从几百个场景到少数典型场景
初始场景动辄几百上千个,每个场景都要参与功率平衡计算,优化维度和计算时间都会被拉高。场景缩减的目标是保留概率最大的典型场景,同时尽量让缩减后的概率分布和原始分布接近。
最常用的缩减方法是同步回代削减法(Simultaneous Backward Reduction)。它通过不断合并距离最近的两个场景,把被删场景的概率加到保留场景上,直到场景数满足预设值。场景间距离一般用欧氏距离,也可以加权计算。步骤大致是:
- 计算所有场景两两之间的距离;
- 找到距离最近的一对场景;
- 删除其中一个场景,将其概率加到另一个场景上;
- 重复步骤2-3,直到剩余场景数量达到要求。
除了同步回代,还有基于k-means聚类的削减方式,把场景聚类成若干类,用聚类中心作为代表场景。我的经验是:场景数量不多时,同步回代更稳定,不会像k-means那样受初始聚类中心影响。但同步回代对多变量时间序列实施时,计算距离矩阵会比较慢,所以可以先压缩成若干个时间点,或者用轮廓系数决定缩减后数量。
MATLAB里实现同步回代,核心循环可以用矩阵运算来加速,不要每个场景都套一层for循环。我一般把场景矩阵组织成三维数组,维度是“场景数×时段数×变量数”,然后对时段、变量做加权欧氏距离。这样整体程序速度会快很多。
2.3 光伏、风电与负荷的多维场景生成
风光场景不能只看一条曲线,还得加入负荷和电价的变化。我习惯的做法是:先获得预测曲线,然后在预测值上叠加随机误差。光伏的随机误差常用Beta分布或正态分布近似,风电和负荷误差也可以用正态分布,但要注意误差范围不能太大,否则会出现负出力这种离谱数据,必须在抽样后截断。
多维场景生成后,要注意变量之间的时序相关性。比如光伏出力有白天高、晚上低的明显日特性,傍晚风速往往增强,切负荷高峰和光伏跌落时段重合。如果直接把每个时段独立抽样,会得到很多物理上不可能出现的场景。建议使用协方差矩阵或Copula来描述变量相互关系,这一步虽然会增加代码量,但能显著提高场景可靠性。
缩减之前,要对所有场景做范式化处理,否则风速数值大、光伏数值小,距离计算会被大数值变量主导。我一般变量归一化到0-1之间,缩减完再反变换回原始量纲,这样场景削减结果更合理。
3. 粒子群算法:用于交直流混合微网优化的核心引擎
3.1 粒子群算法的数学基础与参数选择
粒子群优化(PSO)模拟鸟群觅食行为,每个粒子代表一个候选解,在解空间中以一定速度移动,速度由惯性项、个体认知项和社会认知项共同决定。位置和速度更新经典公式为:
v(i) = w * v(i) + c1 * rand * (pbest(i) - x(i)) + c2 * rand * (gbest - x(i)) x(i) = x(i) + v(i)这里的 w 是惯性权重,它控制粒子对先前速度的记忆。w 较大时全局搜索能力强,较小时局部开发能力强。我常用的策略是线性递减,比如从0.9降到0.4,前期快速探索,后期精细收敛。学习因子 c1 和 c2 一般取2左右,表示粒子的自身经验和社会经验同等重要。种群规模取50到100,最大迭代次数取100到500,具体要看决策变量数量。
虽然PSO参数不敏感,但还是有几点要注意。速度 v 一定要限幅,不然粒子会飞出去,出现决策变量越界。位置也要做边界处理,我一般用反射边界或者吸收边界,让粒子不离开可行域。对于微网优化这种含大量等式约束的问题,粒子很容易停在边界上,所以初始化时最好让粒子在可行区间内均匀分布,不要全用随机数。
3.2 适应度函数与约束处理的工程化设计
在交直流混合微网调度程序中,适应度函数通常包含储能老化成本、燃气轮机燃料成本、从主网购电成本、弃风弃光惩罚成本等。多场景下,目标函数是各个场景成本乘以对应概率后再求和。用公式表达就是:
F = sum(prob_s * Cost_s)其中 Cost_s 是第 s 个场景下系统运行总成本。每个场景都要先校验功率平衡,再计算经济成本。如果不满足功率平衡,可以用很大罚函数值代替,这样粒子群会自动往可行方向搜索。
约束处理是PSO优化成败的关键。我先列一下这个程序通常需要满足的约束:
- 交流侧有功、无功功率平衡;
- 直流侧有功功率平衡,直流母线电压允许范围内;
- 换流器传输功率不超过其容量;
- 储能电池SOC上下限和充放电功率约束;
- 燃气轮机出力上下限、爬坡约束;
- 光伏、风电实际出力不能超过可用出力;
- 与主网交互功率受联络线容量限制。
这些约束如果全部用硬性罚函数,罚因子大小难调,罚太大影响收敛,罚太小会有很多不可行粒子存活。我建议把等式约束用“松弛+弱罚”方式处理,比如功率不平衡量超过容忍度时,按超出量的平方加惩罚;不等式约束尽量落到决策变量边界上,比如储能SOC直接把粒子位置映射到可行区间。
3.3 粒子群算法与场景法如何耦合求解
耦合方式不复杂。粒子群中每个粒子的位置,就是一组完整的调度决策变量,例如24小时的燃气轮机出力、储能充放电功率、换流器传输功率、与主网交互功率等。每评估一次粒子的适应度,就把它代表的决策变量带入每个缩减后的场景,计算该场景下的功率平衡和成本,再按场景概率加权求和。
这样做的直观理解是:最优的调度方案不只在某一种风光出力下好,而是在所有缩减场景下总体期望成本最低。比如如果有三个缩减场景,一个高风电场景、一个低风电场景、一个中等风电场景,粒子给出的储能策略会在高风电时多存储、低风电时多放电,这正是随机优化的意义。相比确定性优化,这种方案天然具备鲁棒性。
实现时为了降低计算量,可以把场景缩减后数量控制在5到15个。每个粒子评估时遍历这些场景,虽然内部有循环,但场景数量不大,计算依然很快。如果场景数太多,可以考虑并行计算或者向量化矩阵操作,后面我会专门说怎么加速。
4. 程序整体架构与实操步骤:从数据到结果
4.1 程序模块划分与输入数据格式
一个可复现的交直流混合微网MATLAB程序,最好分成几个独立模块。我的习惯是这样做:
- 主运行脚本
main.m:设置全局参数,依次调用场景生成、场景缩减、粒子群优化和结果输出; - 参数初始化模块
case_data.m:定义微网拓扑、设备参数、预测数据、电价曲线; - 场景生成模块
scenario_gen.m:用拉丁超立方抽样生成初始风光场景; - 场景缩减模块
scenario_reduce.m:用同步回代削减得到典型场景及概率; - 粒子群主程序
pso_optimize.m:初始化粒子群、迭代寻优; - 适应度评估函数
objective.m:输入决策变量和场景数据,返回期望成本; - 约束校验函数
constraints.m:检查各项约束并返回罚函数值。
数据格式我建议统一用结构体数组或者表格。微网数据里需要包含:各时段负荷预测、光伏容量系数预测、风速预测、分时电价、燃气轮机参数、储能参数、换流器参数。特别是光伏和风电,初始预测值是以容量为基数的标幺值,还是实际功率,一定要在程序开头注释清楚。我遇到过很多程序把单位混了,结果算出来的弃电量、购电成本完全对不上。
4.2 典型算例结果解读与实际意义
跑通程序后,通常输出最优调度方案、各场景成本、收敛曲线、SOC曲线和换流器功率曲线。我拿一个典型配置举例:系统包含100kW光伏、80kW风电、100kW/200kWh储能、60kW燃气轮机,可与主网交互功率上限50kW。削减后场景数量设为6个,粒子群种群80,迭代200次。
运行结果一般会出现这样的特征:在光伏出力高的场景中,储能充电量增大,燃气轮机出力下降,与主网购电量减少;在风电高、光伏低场景中,储能放电时段后移,换流器潮流反向。查看收敛曲线,前面40到60代成本快速下降,之后趋于平稳。这表示PSO已经找到了一个较稳定的最优区域。
通过这些结果,不仅能得到经济性最优的调度计划,还能分析系统在不同不确定性场景下的运行风险。比如某个场景出现极端低风低光时,如果燃气轮机爬坡能力不足,则会频繁越限,说明系统旋转备用不足。这种分析是确定性优化给不出来的,也是这个程序最核心的价值。
4.3 参数设置与调优建议
参数设置很大程度上影响结果质量。下面这张表是我多次测试后觉得比较可靠的经验值:
| 参数项 | 建议范围 | 说明 |
|---|---|---|
| 初始场景数 | 200~500 | 太少场景代表性不足,太多削减耗时 |
| 削减后场景数 | 5~15 | 一般取10以内,兼顾速度与精度 |
| 粒子群种群数 | 50~100 | 决策变量多时可取更大 |
| 最大迭代次数 | 100~300 | 看收敛曲线调整,不必固定 |
| 惯性权重w | 0.9线性降至0.4 | 前期搜索能力强,后期收敛稳 |
| c1、c2 | 1.5~2.0 | 一般取2,也可设自适应 |
| 速度限幅因子 | 0.1~0.5倍变量范围 | 防粒子飞散 |
| 罚因子 | 初始100,随迭代逐步增大 | 有效引导粒子进入可行域 |
这些参数不是死的。比如罚因子如果固定不变,前期粒子可能大量不可行,后期可能因为罚函数太强而难以探索。我采用动态罚因子,让不可行比例高的阶段罚得轻一点,经过一定迭代后加重惩罚,收敛效果更好。
5. 实际运行中的常见问题与避坑指南
5.1 场景缩减后概率分布失真问题
有次我把500个场景缩减到5个,结果缩减后的场景里没有出现极端低风速情况,导致最优调度方案对恶劣天气几乎没有预留储能。后来检查发现是同步回代削减中,距离度量对高维时间序列产生了“平均化”效应,极端场景因为和周围场景距离较远,反而被优先保留的概率不大。
解决方法是:在缩减前对场景做去趋势化,或者对极端场景施加一定的保留权重。更简单的方式是缩减后对比原始场景集和缩减场景集的均值、方差和K-L散度。如果差别超过可接受范围,就增加缩减后场景数量,或者更换削减方法。我后来把削减后场景数从5改成8,预算不变,结果却稳定很多。
5.2 粒子群算法陷入局部最优怎么办
PSO最大的问题是容易早熟收敛,尤其在目标函数有多个局部最小值时。微网模型的约束多、决策变量维度高,很容易出现粒子聚集在一个局部最优点附近,迭代曲线长期不动。
我常用的处理手段有三个。第一是多次独立运行PSO,比如跑10次,每次用不同随机数种子,取最优结果作为最终方案;第二是惯性权重自适应,根据种群多样性动态调整,如果粒子多样性下降,就增大w或者重新随机初始化部分粒子;第三是引入变异算子,对每代中最优粒子以外的粒子以小概率进行扰动,类似遗传算法变异,帮助跳出局部最优。
如果有人想更省事,可以在PSO之后接一个局部搜索,比如用fmincon对当前最优解做二次精调,但要注意把离散变量处理掉。
5.3 程序运行时间过长与加速技巧
场景多、粒子多、迭代多,运行时间很容易指数增长。我在早期版本里,评估200个粒子、200个场景、24时段,跑一次要十几分钟。后来做了三个优化,速度提升了十倍以上。
第一个是用矩阵运算替代循环。比如所有场景的功率平衡计算可以一次性用矩阵乘法完成,不需要在场景层用for迭代。第二个是用MATLAB并行计算池parfor并行评估粒子适应度,因为每个粒子之间相互独立。第三个是减少场景数,前面说过,初始场景用300个,削减到8个,基本不影响结果精度,但运行时间大幅下降。
另外,如果燃气轮机和储能的模型比较复杂,可以把数值积分部分提前写成解析式,减少每次调用目标函数时的重复计算。这些细节虽然不起眼,但叠加起来效果非常明显。
最后再说一点个人体会
这个交直流混合微网MATLAB程序,我前前后后改了很多版,最大的教训是:不要指望一次把场景、缩减、优化全写好,直接跑通,而是要把每个模块单独验证。先验证拉丁超立方抽样生成的曲线和原始分布是否一致,再验证缩减后的场景是不是保留了关键波动特征,最后才进入PSO优化阶段。单独模块都可靠了,整体结果才有说服力。
调试PSO时,我还有个很土但很有效的习惯:把前几代的粒子位置画出来,和约束边界一起看。这样能直观发现粒子是不是老是往同一个方向飞,或者被罚函数压到边界附近无法动弹。有时候问题不在算法本身,而在目标函数里某个单位写错了,画出来一眼就能定位。
如果你也在做类似的微网随机优化,建议先拿一个简单算例把这个流程跑通,再逐步加复杂的换流器控制和储能寿命模型。这样既能保证程序可靠,也能在后续写论文、做方案时积累更多可信的对比结果。