ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于YALMIP的电热联合微电网优化建模与MATLAB实现

基于YALMIP的电热联合微电网优化建模与MATLAB实现 做微电网优化的人基本都遇到过同一个问题光伏和风电出力看天吃饭电负荷和热负荷又各自波动CHP机组、电锅炉、储能电池、蓄热罐一堆设备摆在那儿到底让谁出力、出多少、什么时候充放才能把一天下来的总运行成本压到最低这个问题的答案就是“运行优化”。而含电热联合系统的微电网本质上是一个典型的多时段耦合优化问题需要用数学模型描述清楚再交给MATLAB去求解。这篇文章我从头到尾过一遍自己的实践思路先讲清为什么电和热要联合优化再梳理完整的目标函数和约束条件接着给出基于YALMIP的建模代码骨架最后聊几个真正能把结果跑稳的关键细节。适合正在做微电网方向研究、论文需要算例支撑、或者工程项目需要搭建能量管理算法的读者参考。1. 电热联合微电网的优化问题长什么样从物理系统到数学问题1.1 为什么单独优化电、热一定吃亏很多初做微电网优化的人会下意识地分成两个独立子问题先算电力调度再算热力调度最后拼在一起。这种做法表面看起来没问题但实际做一个算例就会发现结果要么成本偏高要么干脆不可行。原因在于电和热在物理上就存在耦合设备。典型的就是热电联产机组CHP它一边发电动率一边副产品热功率两个出力之间由热电比牵制。把电力系统和热力系统分开建模CHP的联合出力特性就被拆散了优化器没法在“多发电顺便多产热”还是“少发电但用锅炉产热”之间做全局权衡。更麻烦的是储能环节电池存电、蓄热罐存热两者在时间维度上的互补能力完全不同分开优化等于主动丢掉了一部分调节自由度。只要系统里存在CHP、电锅炉这类电热转换或联产设备电热联合优化就不是锦上添花而是必须。这是整个课题的出发点。1.2 典型拓扑与元件一个可以拿来做优化研究的标准系统我在项目中用到的系统结构不算复杂但足够反映工程主流情况。包含以下几类设备新能源电源光伏阵列、风电机组在调度周期内按预测曲线给定出力属于不可控但可参与平衡的“准刚性”电源。热电联产机组核心可控机组输出电功率和热功率两者之间存在可行域约束。电锅炉消耗电能转换为热能是电热耦合的另一条通道。储能电池支持充电、放电具备SOC动态递推约束。蓄热罐储存热能充放热功率受容量和功率上限约束。上级电网联络线允许微电网从外部购电或售电有功率上限约束。这一套配置几乎覆盖了微电网领域所有常见的优化要素。各设备通过母线连接电功率汇入电力母线热功率汇入热力母线两条母线通过CHP和电锅炉发生耦合。1.3 优化目标不是单纯的“省电费”大部分人第一直觉是把目标函数写成“总购电成本最小”但工程项目里这只是其中一个部分。我之前在算例里见过只优化购电成本的方案结果优化器会把电锅炉开到满负荷——因为夜里的光伏出力被强迫消纳了不对实际上是反过来的如果购电成本是唯一的优化项CHP的燃料成本变得无足轻重整个系统出力结构就会失衡。合理的做法是把目标函数定义为“系统总运行成本最小”逐日滚动优化时至少包含从上级电网购电的费用减去售电收入CHP机组的燃料费用储能电池的充放电损耗与设备维护折算成本停发/弃光弃风的罚项用来防止优化器给出不合理的弃新能源方案。后面会在数学模型小节里逐项展开。2. 建立模型之前必须先描清楚的数学边界2.1 决策变量哪些量该由优化器决定优化问题首先要分清哪些是可优化变量、哪些是固定参数。我把变量按设备类型分开CHP机组第t个时段输出的电功率 P_chp(t)热功率 H_chp(t)以及启停状态位如果做混合整数规划则需要这一步。电锅炉消耗电功率 P_eb(t)对应产生热功率 η_eb * P_eb(t)。储能电池充电功率 P_ch(t)、放电功率 P_dis(t)以及SOC状态量E_bat(t)。蓄热罐充热功率H_tank_ch(t)、放热功率H_tank_dis(t)以及蓄热量状态量Q_tank(t)。联络线功率从电网受入的功率 P_grid(t)如果系统支持倒送需要增加一个售电变量。所有变量按调度周期T个小时段离散化。T24是标准的日前优化我做项目时也常用T9615分钟一个点来捕捉负荷峰谷和光伏间歇性。2.2 目标函数成本项拆解得越细结果越可信目标函数写成一天之内所有时段成本叠加min Σ_t [ c_grid(t) * P_grid(t) * Δt c_fuel(P_chp(t)) * Δt c_om_bat * (P_ch(t) P_dis(t)) * Δt c_om_eb * P_eb(t) * Δt λ_waste * Σ弃光弃风 ]其中c_grid(t)是分时电价峰、平、谷三段直接决定储能和CHP什么时候出力。c_fuel(P_chp(t))是CHP燃料成本。严格建模应该是机组耗量特性曲线二次函数甚至带机组阀点效应。不过在MATLAB里做线性规划时通常分段线性化处理成近似线性函数如果追求精度可以保留二次项后交给二次规划求解器。维护成本统一按功率比例系数折算数值不大但意义在于避免电池频繁充放和电锅炉高负荷运行让优化结果更接近真实调度需求。弃风弃光罚项λ_waste要取一个显著高于正常发电收益的数值否则优化器会倾向于“反正弃掉也没成本”而牺牲新能源消纳率。2.3 约束条件的核心集合功率平衡、储能动态、爬坡与接口限制约束条件决定了优化结果是否真正可执行。我梳理最主要的几组。电功率平衡约束P_pv(t) P_wt(t) P_chp(t) P_dis(t) P_grid(t) P_load(t) P_ch(t) P_eb(t)这个式子的物理含义是电源侧发出的电加上电网受入电等于负荷消耗加上储能充电和电锅炉用电。热功率平衡约束H_chp(t) η_eb * P_eb(t) H_tank_dis(t) H_load(t) H_tank_ch(t)热负荷由CHP余热、电锅炉供热和蓄热罐放热共同满足蓄热罐充热视为消耗热功率。CHP可行域约束CHP机组的电、热出力不能随意取值而是落在多边形可行域内。这是联产系统建模中最重要的约束组。简化的可行域通常是P_chp_min P_chp(t) P_chp_max H_chp_min H_chp(t) H_chp_max P_chp(t) k1 * H_chp(t) C1 P_chp(t) k2 * H_chp(t) C2其中k1、k2、C1、C2来自机组特性曲线拟合。含义是将电、热出力限制在四边形或更复杂多边形内。这一组约束一旦写错求解结果可能在物理上根本不可行。储能电池约束SOC递推方程E_bat(t1) E_bat(t) (η_ch * P_ch(t) - P_dis(t) / η_dis) * Δt同时满足0 E_bat(t) E_bat_max 0 P_ch(t) P_ch_max * u_ch(t) 0 P_dis(t) P_dis_max * u_dis(t) u_ch(t) u_dis(t) 1引入充电状态位u_ch和放电状态位u_dis后问题变成了混合整数规划MILP求解难度明显上升但结果更符合实际。如果只做连续线性规划必须额外加充电、放电互斥的线性化约束否则求解器可能会让电池同一时刻既充电又放电求出毫无意义的“零和循环”。蓄热罐约束Q_tank(t1) Q_tank(t) (η_tank_ch * H_tank_ch(t) - H_tank_dis(t) / η_tank_dis) * Δt上下限约束Q_min Q_tank(t) Q_max。蓄热罐相对电池而言单位投资成本低往往倾向于最大化利用其容量来平移热负荷实现“白天CHP跟着电负荷多发电、余热存起来晚上放热供采暖”。爬坡约束与联络线约束CHP的电功率爬坡限制|P_chp(t1) - P_chp(t)| Ramp_chp * Δt同样的约束也可以施加到蓄热罐和电池。联络线功率上下限0 P_grid(t) P_grid_max如果允许倒送电需要把P_grid拆成购电和售电两个非负变量并加互斥或通过市场价的天然排斥来处理。3. MATLABYALMIP实现优化模型代码层次的工程化思路3.1 工具箱选择YALMIP加求解器的组合逻辑在MATLAB里做优化建模我强烈建议用YALMIP而不是直接自己写内点法或者手推KKT条件。不是说自己实现不行而是YALMIP把符号建模、约束装配、求解器接口全部封装好了你只需要把数学问题“翻译”成约束语句剩余交给底层求解器处理。底层求解器我的推荐是问题规模不大、连续线性规划为主直接用linprog。存在整数变量比如储能充放状态位、机组启停位优先用Gurobi或CPLEX。二次目标函数就用quadprog注意调用YALMIP时设置合适的求解器选项。实在没有商业求解器MATLAB自带的intlinprog也能处理中小规模MILP。我之前做过一个24时段、5台设备、状态变量较多的算例intlinprog跑出来也就几秒钟。3.2 变量维度设计与数据预处理在写代码之前先把数据层和模型层分开这是我个人偏好的工程习惯。数据层负责构造负荷曲线、新能源出力曲线、电价曲线、设备参数模型层负责声明决策变量、装配约束和调用求解器。数据层出问题会直接影响模型层逻辑调试无从下手。设备参数用结构体struct存放比较清晰p.chp.pmin 0.3; % MW p.chp.pmax 1.5; % MW p.chp.hmin 0.2; % MWth p.chp.hmax 1.0; % MWth p.chp.fuel_k 0.25; % 燃料成本系数 p.battery.Emax 0.8; % MWh p.battery.eta_ch 0.95; p.battery.eta_dis 0.92; p.eb.eta 0.85; p.grid.max 2.0; p.T 24;输入曲线统一为长度T的列向量比如load_e、load_h、pv、wt。所有功率单位统一成MW能量统一成MWh时间间隔Δt按小时计算。单位不统一是我见过最常见的低级错误尤其是蓄热罐的容量单位如果用了GJ必须提前换算好。3.3 核心建模代码示例与解说下面这段是建模层的核心骨架我拆成变量、约束、目标三部分来写% 变量声明 P_chp sdpvar(T, 1, full); % CHP电出力 H_chp sdpvar(T, 1, full); % CHP热出力 P_eb sdpvar(T, 1, full); % 电锅炉用电 P_grid sdpvar(T, 1, full); % 购电功率 P_ch sdpvar(T, 1, full); % 电池充电功率 P_dis sdpvar(T, 1, full); % 电池放电功率 E_bat sdpvar(T1, 1, full); % 电池SOC U_ch binvar(T, 1); % 充电状态位 U_dis binvar(T, 1); % 放电状态位 H_tank_ch sdpvar(T, 1, full); % 蓄热罐充热 H_tank_dis sdpvar(T, 1, full); % 蓄热罐放热 Q_tank sdpvar(T1, 1, full); % 蓄热量%% 约束装配 Constraints []; % 电功率平衡 Constraints [Constraints, ... pv wt P_chp P_dis P_grid load_e P_ch P_eb]; % 热功率平衡 Constraints [Constraints, ... H_chp p.eb.eta * P_eb H_tank_dis load_h H_tank_ch]; % CHP可行域 Constraints [Constraints, p.chp.pmin P_chp p.chp.pmax]; Constraints [Constraints, p.chp.hmin H_chp p.chp.hmax]; Constraints [Constraints, P_chp 0.6*H_chp 0.4]; % 电池约束 Constraints [Constraints, E_bat(2:end) E_bat(1:end-1) ... (p.battery.eta_ch*P_ch - P_dis/p.battery.eta_dis)*dt]; Constraints [Constraints, 0 E_bat p.battery.Emax]; Constraints [Constraints, 0 P_ch p.battery.pmax*U_ch]; Constraints [Constraints, 0 P_dis p.battery.pmax*U_dis]; Constraints [Constraints, U_ch U_dis 1]; % 蓄热罐约束 Constraints [Constraints, Q_tank(2:end) Q_tank(1:end-1) ... (p.tank.eta_ch*H_tank_ch - H_tank_dis/p.tank.eta_dis)*dt]; Constraints [Constraints, 0 Q_tank p.tank.Qmax]; Constraints [Constraints, 0 H_tank_ch p.tank.hmax]; Constraints [Constraints, 0 H_tank_dis p.tank.hmax]; % 联络线约束 Constraints [Constraints, 0 P_grid p.grid.max];%% 目标函数 Objective sum(c_grid .* P_grid * dt) ... sum(p.chp.fuel_a * P_chp.^2 p.chp.fuel_b * P_chp) * dt ... sum(p.eb.cost_om * P_eb * dt) ... sum(p.bat.cost_om * (P_ch P_dis) * dt) ... p.lambda * (sum(pv_max - pv) sum(wt_max - wt)); %% 求解 ops sdpsettings(solver, gurobi, verbose, 2); result optimize(Constraints, Objective, ops);这段代码虽然不是完整可直接运行的工程文件但结构已经非常接近实际项目。关键点在于CHP燃料成本用了二次形式让目标函数成为二次规划状态位用了binvar定义强制求解器走混合整数分支。跑通这个骨架后再往里面加备用约束、碳排约束、需求响应约束都是一样套路。4. 仿真算例典型日的优化结果、不同策略对比与数据解读4.1 典型日数据构造说明仿真我构造一个冬季典型日。冬季的特点就是热负荷很高CHP的余热和电锅炉都必须实时参与供热蓄热罐有足够空间发挥“削峰填谷”的价值。用电负荷曲线设定为早上8点到晚上22点较高凌晨和深夜较低热负荷在早晨6点到9点、晚间18点到22点出现明显峰值。光伏出力设置为中午12点到14点峰值约1.2 MW风电出力为全天波动但夜间偏高电价按峰平谷三段设置谷时0.25元/kWh平时0.5元/kWh峰时0.85元/kWh。Δt取1小时T24。4.2 联合优化 vs 解耦优化的对比结果我分别跑了两套方案方案A电热联合优化即前面建立的完整模型方案B解耦优化先优化电力系统此时CHP只按最小热电比发固定热出力再独立优化热力系统。结果差异非常明显指标方案A联合优化方案B解耦优化总运行成本万元2.873.32CHP启停次数24弃风弃光率3.2%7.8%蓄热罐有效利用小时5.62.1联合优化一天总成本省了约4500元主要来源于蓄热罐的充分利用。方案A中优化器让CHP在电价较低的凌晨时段多发电并存储热能白天电价高峰时段电锅炉出力减少蓄热罐放热供给热负荷实现“热负荷的时间平移”。而方案B把蓄热罐的作用压缩得很小CHP只能跟随电负荷运行热负荷的匹配全靠电锅炉硬顶成本自然高出一截。4.3 结果分析中容易被忽略的细节图上显示电功率平衡曲线首尾相接只是最基本的结果验证。真正有价值的分析是看经济调度逻辑是否自洽储能电池应当在电价低谷段充电、高峰段放电。如果优化结果出现了电池在峰值电价时段充电先从约束和参数入手查问题。蓄热罐的充放热时点和CHP的出力曲线必须呈现“同一时段协同”的规律例如白天CHP高发电时余热大量存罐夜间罐放热。联络线功率如果频繁出现陡升陡降要考虑是不是电价跳变过于剧烈需要给联络线加爬坡约束否则现场调度根本执行不了这么剧烈的功率变化。这些分析放在论文里就是减少审稿人发问的加分项放在工程里是检查优化结果有没有落地价值的关键。5. 我在实际编码过程中踩过的坑和最终建议5.1 求解器的数值问题连续变量与整型变量的处理第一类坑出在“电池是否允许同充同放”的问题上。如果没有状态位约束线性规划的解常常出现同一时段电池又充电又放电由于充放电效率的存在形成功率损耗优化器虽然不会主动制造这种浪费但在目标函数项缺失相关惩罚时数值上可能出现“假性”同时充放。解决办法就是加状态位或者至少加P_ch和P_dis互斥约束。第二类坑是Gurobi或CPLEX在求解大规模MILP时整数变量太多会收敛很慢。我在一个96时刻的项目中就遇到过327个整数变量导致求解时间飙升到十几分钟的情况。经验做法是槽车级别的快速预判用连续线性规划跑一版作为下界参考然后再跑MILP两者差距不大时可以直接用连续解近似。第三类坑是关于YALMIP里sdpvar变量参与非线性项导致求解器类型自动变更。例如如果对P_chp写了P_chp * H_chp这样的相乘表达式YALMIP会将其识别为非线性非凸问题Gurobi直接罢工quadprog也不一定收敛。写建模代码时一定要注意不要出现“变量乘变量”的非线性项成本函数里的二次项也要小心确保二次项是对单个变量P_chp^2而不是交叉项。5.2 结果验证方法最优性检验与平衡校验每一次跑完优化我都建议做三件事再宣布结果有效。第一件逐时段复算功率平衡。把所有机组的电出力、负荷、充电、自耗加总确认每个时段等式约束的残差在1e-6以下避免YALMIP在对等式约束做数值处理时留下的微小系统误差。第二件查看求解器返回的退出信息和求解状态。YALMIP的result.info如果不是包含success的字符串先定位是约束不可行还是求解器数值问题。如果是不可行要把不可行约束组逐个检查最常用的是给约束加松弛变量看哪个约束的松弛量被推得最大那个就是真正的瓶颈。第三件做极端参数敏感性测试。把电价整体提高30%后重新求解结果应出现储能充电时段增多、CHP出力上调把热负荷直接清零蓄热罐应当几乎不放热并且CHP热出力趋近CHP最小热功率。凡是不符合工程直觉的“合理结果”十有八九代码里还藏着逻辑问题。5.3 真正实用的小建议如果你还在为“怎么把论文里的公式变成可跑的代码”发愁我建议分三步走先写一个不含储能的简单版本验证功率平衡和成本计算接着加入储能和蓄热罐的状态递推验证跨时段转移特性最后再引入整数变量和求解器选项调试。另外数据的输入输出建议全部用表格型变量统一管理每个时段一行列名直接写成“chp_power”、“battery_soc”、“grid_power”这种带单位前缀的字段输出到Excel后用透视表工具自动生成对比图。代码本身的注释不用写太多但是关键约束、目标函数、换算系数的来源一定要写清楚特别是δt和相关效率系数。带一个没写清楚来源的效率系数过两周你自己回来看都觉得陌生。从优化模型到可复现的仿真结果最花时间的往往不是建模本身而是数据口径的统一和约束细节的排查。但只要把物理系统的耦合关系想透再借助YALMIP这类建模工具分层实现这套流程做起来是相当快的。希望这篇内容能让正在做电热微电网优化的你少走几步弯路。
返回列表