ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

多微网能量互联低碳经济优化调度:MATLAB建模与求解全流程

多微网能量互联低碳经济优化调度:MATLAB建模与求解全流程 先聊个现象现在做微电网研究的同学十个里有八个绕不开“优化调度”这四个字。但多数人刚开始做的都是单微网把分布式电源、储能、负荷丢进一个模型里求一个成本最低的出力方案。单微网跑顺了下一步自然就是“多微网”了也就是把几个微网通过联络线连起来让电能可以在它们之间流动。这时候模型复杂度一下子上去好几个量级因为每个微网内部有自己的电源、储能、负荷微网之间又有交换功率目标还不光是省钱还要看碳排放。我见过太多人在这一步卡住要么不知道怎么建模要么建出模型来MATLAB一跑就报infeasible要么结果收敛了但曲线图难看得没法交差。所以我这次完整做了一遍“面向低碳经济运行目标的多微网能量互联优化调度”用MATLAB实现了整套代码把目标函数、约束条件、求解器配置、结果分析全链路跑通。这篇就当成一次完整的项目复盘把建模思路、代码结构、调参经验和踩坑记录都写清楚希望对正在做多微网调度、综合能源系统优化、低碳经济调度的同学能有实际帮助。1. 多微网互联优化调度在做什么——先把问题的边界画清楚1.1 为什么是微网为什么还要多个互联要搞清多微网调度的意义得先回顾单微网的问题在哪。单微网内部通常有光伏、风电、微型燃气轮机、储能和本地负荷。光伏风电靠天吃饭出力波动大储能只能平移一部分能量燃气轮机虽然可控但会产生碳排放而且燃料成本不低。所以单微网调度本质上就是在电池容量、机组爬坡、功率平衡这些约束围出来的可行域里找一个“买电、卖电、发多少电、储多少能”的组合让总费用或总排放最低。但单个微网能力有限。某个微网光伏大发、负荷又低电多到储能都装不下只能白白弃光隔壁微网正好缺电可它自己的燃气轮机已经满发还要从大电网高价买电。这时候如果两个微网之间有一条联络线问题就简单了——多的电送过去缺的电网就不用买两边都省钱。这就是能量互联最朴素的动机。把范围再放大到三个微网就出现了一些有意思的新问题谁向谁输送功率、输多少、电价怎么定这些都不能靠拍脑袋定得靠一个上层优化统一决策。因为每个微网既可能是送端也可能是受端且如果两个微网同时想从第三个微网购电还会发生竞争。所以从单微网到多微网核心变化不是“数量翻了三倍”而是多了“微网间功率交换”这个自由度和相应的耦合约束模型维度和求解难度是成倍增长的。1.2 “低碳经济运行目标”到底怎么解读项目标题里“低碳经济运行”这个词我看很多论文写法不同翻译也不统一但实质一般是两层意思第一层是“碳排放最小化”。传统调度只看经济成本燃气轮机便宜就多发电但排放高外购电虽然贵一点却可能来自更清洁的电网远方电源。两种选择在费用和碳排放上是有冲突的单纯费用最小化的方案碳排放往往不是最优的。第二层是“引入碳成本之后的经济运行”。这个做法更贴近实际把碳排放通过碳排放交易价格或碳税的方式折算进目标函数让碳排放在经济上“有价格”。这样一来调度优化就不是单纯减排或单纯省钱而是在一个统一的目标函数里做权衡。典型做法是给碳排放增加一个价格参数比如每吨碳多少钱然后把碳排放量乘以这个价格加到总费用里。在代码实现里我建议初学者先把“经济成本最小化”跑通再把“碳排放成本”加进去最后再考虑碳配额、阶梯碳价之类更复杂的机制。底子没打好一上来就搞阶梯碳交易容易崩。1.3 我的系统结构和研究假设我这次的算例是三个微网记为MG1、MG2、MG3结构上做了对称化处理方便验证算法。每个微网内部都包含光伏机组PV出力按典型日曲线给定在调度周期内视为不可调度电源微型燃气轮机MT可控电源有出力上下限和爬坡约束产生碳排放储能系统ESS蓄电池有充放电功率上限、SOC上下限、充放电效率本地负荷Load给定预测曲线当作刚性负荷联络线三个微网两两相连构成环形网络每对微网之间设定最大传输功率调度周期取24小时步长1小时共24个时段。这是一个经典设置既足够展示调度逻辑又不至于让模型规模大到难以求解。实际项目中如果要做日内滚动调度可以把步长改成15分钟但相应的模型规模会涨两倍以上调试难度也上升。2. 数学模型搭建——目标函数和约束条件的完整拆解2.1 目标函数费用最小还是碳排放最小还是两者都要做多目标的时候有两种思路。一种是真正意义上的多目标优化比如用NSGA-II这类进化算法求Pareto前沿但这类方法通常用于离线分析算一次要很久而且拿到一堆非劣解后还要做决策在实际调度里不太常用。另一种是线性加权法把两个目标归一化后加权求和转成单目标优化这也是YALMIPGurobi这类商业求解器最擅长的形式。我这次的写法是含碳惩罚的单目标总成本 购电费用 - 售电收益 燃料费用 碳排放成本其中碳排放成本 碳排放量 × 碳价。用公式写出来就是min F Σ(i,t) [ c_buy_t * P_buy(i,t) - c_sell_t * P_sell(i,t) ] Σ(i,t) [ a_i * P_MT(i,t) b_i ] Σ(i,t) [ β * E_CO2(i,t) ]这里c_buy/c_sell是大电网的分时购售电价P_buy/P_sell是购售电功率P_MT是燃气轮机出力a和b是燃料费用系数β是碳价E_CO2是碳排放量。注意卖电价格通常低于买电价格否则微网可以通过低买高卖套利模型会出现病态解。碳排放量按燃气轮机的输出功率线性折算E_CO2 K_CO2 * P_MT * Δt系数K_CO2取决于机组类型和燃料热值。光伏和储能不能再降这个值但可以通过降低燃气轮机出力来减少排放或者通过从外网购清洁电来替代燃气轮机出力。2.2 约束条件功率平衡、机组出力、储能SOC、联络线功率约束条件里最容易漏的是耦合约束我按类型整理如下首先是微网内部功率平衡约束。每个时段、每个微网内部光伏出力、燃气轮机出力、储能放电功率、购电功率之和要等于负荷、储能充电功率、售电功率、输出到其他微网的功率之和。这个约束决定了整个模型能不能平衡也是最后查看结果时最先要对齐的检查项。其次是微型燃气轮机约束。出力不能超过额定上下限还有爬坡约束相邻时段出力变化量不能超过爬坡率。如果跳过了爬坡约束调度结果会非常激进上一小时满发下一小时停机实际机组根本做不到。然后是储能约束。连续时段之间有SOC递推关系SOC(t1)SOC(t)η_ch*P_ch(t)*Δt - P_dis(t)*Δt/η_dis。同时SOC要维持在上下限内充放电功率也不能越限。这一组约束是整个模型里最容易被写崩的地方很多新手会把SOC写成绝对值约束导致时间耦合被破坏。最后是联络线功率约束。每条联络线上流过的功率是双向可变的但方向不同时往往损耗和费用处理方式相同为了避免非线性项我采用了两个非负变量表示正向和反向功率再用总功率上限约束它们。这是一类非常典型的线性化处理技巧一个双向变量拆成两个单向非负变量。2.3 碳交易机制建模的一种简化处理如果项目只是要求“考虑碳排放成本”最简单的做法是在目标函数里加一个碳排放总量乘碳价。但如果想要更贴近实际可以引入碳配额机制给每个微网分配一个免费碳排放配额实际排放超过配额的部分要去碳市场购买低于配额的部分可以出售获利。在代码里这个机制建模起来非常直接。设配额为Q_alloc实际排放为E_total则需要购买的量 E_total - Q_alloc如果为负表示有多余配额可出售。在MATLAB中用max和min的线性化表达就能写进目标函数注意不能直接写max(E_total-Q_alloc, 0)因为max是有限函数不能直接用在线性规划中。要么引入辅助变量要么用分段线性惩罚。这一块的线性化细节很多论文里一笔带过代码实现时却会卡半天。2.4 多目标归一化与权重系数设置的实操思路把低碳和经济两个目标合成一个目标关键是归一化。直接相加是不行的因为费用是万元量级碳排放是吨量级数值上碳排放可能比费用大几百倍加权后等于没考虑经济性。我采用的做法是分两步走先跑一次纯经济调度记录最优费用F_econ再跑一次纯低碳调度记录最低碳排放E_co2。然后对目标函数做归一化F_norm F / F_econE_norm E / E_co2最终目标为 min α*F_norm (1-α)*E_norm。这个做法的好处是α从0到1扫一遍能画出Pareto前沿展示不同偏好下的调度结果。缺点是等于要跑很多次优化但24时段的三微网模型规模不算大扫20个点也就几分钟。我用这个方式出的图放论文里很好看也方便确认模型行为符合直觉α增大时费用下降碳排放上升反向亦然。3. Matlab代码实现——从零搭建一套可跑的调度框架3.1 代码整体模块划分我写这套代码时坚持“一个脚本只干一件事”的原则十分钟能跑通后面改参数也方便。文件结构大概如下main.m主脚本负责参数初始化、调用求解、调用绘图data_define.m把负荷、光伏、电价、机组参数、储能参数、联络线参数全部集中在一起build_model.m使用YALMIP建模定义决策变量、目标函数和约束条件solve_and_post.m调用求解器解析结果计算各项费用和碳排放输出表格plot_results.m绘制功率平衡曲线、SOC曲线、联络线功率曲线、费用堆叠图相比把所有内容塞进一个脚本里这种模块化写法在调试时就舒服太多了。比如发现SOC有问题只需要改build_model里的储能约束段其他部分完全不用动。3.2 YALMIP求解器配置为什么我选这套组合多微网调度本质上是一个线性规划或混合整数线性规划问题只要你的模型没有非线性项。要实现它选型有很多直接调MATLAB内置的linprog、用CVX、用YALMIP、用MATLAB优化工具箱。我实际对比下来最推荐YALMIPGurobi的组合。原因有三点。第一YALMIP建模语法接近数学表达式容易检查模型是否正确。第二Gurobi求解速度快、数值稳定性好24时段的小规模模型基本秒解。第三YALMIP支持在模型里直接使用binary变量之后如果要加储能充放电状态约束或者机组启停变量不需要改建模框架就能扩展。安装过程提醒一句Gurobi需要联网申请免费学术许可证个人用户也能申请。配置好以后在MATLAB命令行里运行yalmiptest看到求解器列表里有gurobi就说明配置成功了。3.3 关键代码段解析场景生成、目标函数、约束组装场景生成这一步不同论文处理方式不同。我根据实际风电光伏数据的特点采用典型日曲线法。也就是说把一个“典型晴天”的光伏出力标幺曲线乘以装机容量加上一个小幅随机波动就生成了光伏出力序列。风电同理。目标函数在YALMIP里写起来非常直观。以碳排放成本为例% 碳排放成本项 C_co2 carbon_price * sum(sum(K_co2(i) * P_MT(:, i) * delta_t));这里P_MT是24×3的决策变量矩阵行是时段列是微网编号。YALMIP对矩阵变量特别友好同一类约束可以直接用矩阵运算批量写不用写三层for循环。约束组装部分功率平衡约束可以用下面这个写法% 微网内部功率平衡 P_pv P_MT P_dis P_buy - P_load - P_ch - P_sell - P_out 0注意P_out是微网输出到其他微网的功率而P_in是其他微网送到本微网的功率。逐个微网写约束时要特别小心别把P_in和P_out的符号搞错。我在第一次写的时候把符号弄反了结果求解出来每个微网都在疯狂购电然后输出给其他微网费用爆表还不平衡排查了很久才发现是符号问题。3.4 多微网互联协同求解的两条技术路线多微网互联调度的求解方式目前主流的就两种第一种是集中式。把所有微网合并成一个单一模型变量里包含每个微网的内部变量再额外加入联络线功率变量和互联约束。这种方式实现最简单只要模型规模可控求解速度也快。我这次用的就是集中式三个微网每个24个时段决策变量数量在几百个量级Gurobi几乎瞬时求解完成。第二种是分布式。每个微网有自己的局部优化问题通过交换边界信息比如联络线功率或电价来迭代逼近全局最优解典型算法是ADMM。这种方式的好处是保留了每个微网的自治性符合实际运行结构缺点是迭代次数多参数整定麻烦收敛性有时还需要人为调节。如果项目要求“分布式自治协调”的场景才需要上这种路线如果只是要一个结果集中式足够。4. 复现过程中的踩坑记录与常见问题速查4.1 典型问题一求解器报错infeasible这是最令人崩溃的报错几乎每个人都遇到过。我第一次运行时就撞上了YALMIP提示“Problem infeasible”当时第一反应是约束写错了查了半天才发现问题是出在参数上——联络线最大传输功率设得太小而微网之间的功率交换需求大于上限导致整个模型没有可行解。排查思路建议按下面的顺序走检查功率平衡约束的变量符号尤其是P_in/P_out和P_buy/P_sell的方向定义检查购售电不能同时进行的约束是否存在如果没有模型可能会通过同时买卖骗约束检查储能SOC初值和末值约束是否设置了合理范围最后再检查联络线容量和机组出力上限是否过于严苛还有一个很实用的技巧先把所有约束一条一条注释掉跑一次看哪个约束导致infeasible。YALMIP还可以用diagnostics optimize(Constraints, Objective, sdpsettings(verbose,2))看一下诊断信息定位是哪一步不可行。4.2 典型问题二SOC越限结果曲线出现很多断崖代码能跑了但画出来的SOC曲线像锯齿一样一会儿冲到0.9一会儿掉到0.2这种结果理论上没有违反约束但实际是“数值可行而物理不可行”——说明储能充放电对应关系没写好。最常见的原因是充放电变量都为非负但模型为了“同时省事”在一个时段内既充电又放电利用效率差来套利。解决方法是加一个二进制变量约束P_ch * P_dis 0或者用大M法线性化让它们在任意时段最多只有一个大于0。我自查的时候发现设置充放电效率为0.95和0.95时哪怕不加互斥约束模型也可能因为目标函数设置出现充电和放电同时发生而数值上成本为负导致套利。加互斥约束后曲线立刻平滑多了。4.3 典型问题三收敛速度极慢大场景根本算不动做24时段、三个微网时基本秒解但当你把步长改成15分钟、微网数加到5个时集中式的变量数量会翻几倍计算时间可能从几十秒涨到几十分钟。我踩过这个坑两个建议第一优先检查有没有引入不必要的整数变量。比如储能互斥约束用大M线性化可以改为引入一个连续辅助变量或合理利用分段约束尽可能避免同步引入大量二进制变量。Gurobi对整数变量很敏感变量一多速度骤降。第二检查是否存在冗余约束。很多论文里会同时加上限约束又加平衡约束导致求解器做大量无用计算。我实际测试下来把重复的上下限约束删掉三分之一求解时间下降了约40%。4.4 调参心得权重系数、罚因子、迭代精度的经验值调参这块我总结了几个可以直接参考的经验值碳价的设置如果每吨碳价格设为50-80元调度结果中的燃气轮机出力会明显降低如果设为200元以上多数情况下燃气轮机基本不出力全靠网购电这就不符合实际工程逻辑了。做敏感分析时建议从0到200元每档50元扫过去。权重系数α如果α设在0.6-0.8之间经济性占主导但并不忽略低碳目标结果会比较合理。α小于0.5时你会发现碳排放显著降低但费用增加很多适合展示碳中和场景偏好。储能SOC初值设成0.2还是0.5会影响第一个调度时段的购电决策。如果初值设得太低模型就会倾向于第一个时段大量充电导致购电峰附近负荷暴增这是我调参时容易忽略的一个细节。5. 这套代码能怎么扩展——我的后续改进经验5.1 从确定性到随机性场景法与鲁棒调度我在第一版代码里用的都是确定性预测数据光伏出力、负荷都是给定曲线。实际运行中预测误差不可避免所以后面我把模型升级成了场景法通过蒙特卡洛抽样生成大量风光出力场景再通过聚类把场景数削减到典型场景集形成“两阶段随机优化”问题。这里有个需要注意的点随机优化模型的目标函数是所有场景下费用的期望值因此变量里多了一个“第二阶段的调整变量”比如储能充放电功率和购售电功率在每个场景下分别决策。我一开始没注意直接在目标函数里把场景的概率加权平均套到原模型里结果解出来是错的。后来才理解应该在每个场景下构建独立的功率平衡约束只在第一阶段保留燃气轮机出力等“决策变量”的场景无关约束。5.2 从集中式到分布式ADMM完全分布式的改造如果项目要求多微网各自独立决策自己保留内部信息的隐私就要上分布式优化。我在后续版本里做了ADMM改造基本思想是每个微网有自己的局部目标函数联络线功率作为耦合变量通过在迭代中交替更新各个微网的联络线功率和拉格朗日乘子逐步逼近全局最优解。ADMM调参最痛苦的地方是罚参数ρ的选择。我实测下来ρ取得太小收敛速度慢还振荡取得太大又容易产生锯齿效应导致迭代曲线来回抖。我的建议是从1开始尝试以2倍步长递增观察对偶残差和原始残差的比值变化来调整。这样改造后模型可以实现在不暴露每个微网内部的负荷、电池等私有数据的情况下仍然得到与集中式非常接近的调度结果适合做接续论文。5.3 数据驱动与强化学习方向的思路最后提一个目前学术界比较火的方向不建精确模型直接用强化学习来做多微网调度。我在空闲时间试过用MATLAB工具箱里的Reinforcement Learning Toolbox做一个小规模的DQN和DDPG实验用来训练一个“调度策略”而不是“调度方案”。这一步的难点在于状态空间的定义和奖励函数的设计。我把每个时段的净负荷、SOC、电价作为状态把输出功率、储能充放电量作为动作奖励函数则采用了期望费用和碳排放的加权负值。实验发现在简单的三微网场景下训练收敛后得到的策略虽然和数学优化的最优解还有差距但已经具有很好的实时决策能力对在线调度场景有价值。不过现阶段我仍建议以数学优化为主、强化学习为辅。数学优化的结果至少是有保证的最优解强化学习的结果缺乏理论底线尤其是在约束多且严格时动作略微越界可能导致巨大的连锁问题。5.4 最后几点个人体会做了这轮多微网低碳调度项目我最深的感受是多微网优化调度表面上是个“建模求解”的数学题实际上是个系统工程题。模型搭建要能准确体现能量互联的价值目标函数要平衡经济性和碳排放MATLAB里哪怕只是调整一个符号、一个权重结果可能完全变样。千万不要一上来就追求复杂的碳交易机制或分布式算法先把三微网集中式调度做扎实等结果曲线平稳、逻辑可信再逐步加不确定性、加分布式、加数据驱动方法这条路比一开始就硬啃最复杂版本要顺得多。最后再分享一个检查结果的实用技巧每次跑完优化先不看总费用而是先画出三个微网的功率平衡曲线看看每个时段是否满足“发电购电放电”等于“负荷充电输电”。如果这条平衡线闭合再去核对SOC的初末值约束最后才谈费用和碳排放数字。这样从物理层到经济层逐层检查能帮你迅速定位建模错误也会让最终结果经得起追问和复现。
返回列表