
最近一直在折腾一个很有意思的题目含可再生能源的配电网最佳空调负荷优化控制。搞了一段时间Matlab仿真从建模到求解再到调参踩了不少坑也积累了一些经验。这个方向现在确实很火一方面是可再生能源装机比例越来越高配电网的调峰压力肉眼可见地变大另一方面空调负荷又是夏季尖峰负荷的“大户”如果能把空调负荷的灵活性用起来对配电网来说等于多了一块可调资源。这篇就把整个项目从思路、建模、代码实现到仿真结果分析的完整过程捋一遍顺便把我在实际调试中遇到的问题和解决方案也一并写出来希望对正在做相关课题或者入门的同学有帮助。如果你是做电力系统优化调度、需求响应或者可再生能源消纳方向的研究生又或者你是配电网规划运行方向的工程师想了解一下空调负荷聚合参与调峰到底怎么在Matlab里落地那这篇文章可以直接当一份实践笔记来用。全文不会堆概念重点放在模型怎么建、代码怎么写、结果怎么分析这些实际操作层面。1. 项目到底在解决什么问题1.1 可再生能源并网后配电网的困境以前配电网的负荷曲线相对可控峰谷差虽然存在但通过传统的调度手段基本能压住。现在情况变了大量分布式光伏和风电接进来之后配电网的净负荷曲线负荷减去可再生能源出力变得非常“调皮”。举一个最直观的例子夏天中午光伏出力最大而这时候商业和居民用电负荷相对较低可能出现反调峰现象也就是光伏出力高峰和负荷低谷重叠导致午间净负荷很小甚至出现倒送到了傍晚光伏出力迅速下降空调负荷又进入晚高峰净负荷曲线陡增形成“鸭子曲线”的尾巴。这种净负荷波动对配电变压器的运行、电压控制以及上级电网的功率平衡都提出了很高的要求。传统应对方式是靠火电调峰、储能充放但配电网层面的资源有限响应速度也往往跟不上。这时候空调负荷的价值就体现出来了。空调本身具有热惯性房间温度在设定值附近波动一点人体几乎感知不到但空调压缩机的工作状态可以短暂调整。把大量空调负荷聚合起来在不影响用户舒适度的前提下让一部分空调在净负荷高峰时少用电在净负荷低谷时多用电就能有效削峰填谷。我做的这个项目的核心就是在配电网层面设计一个优化控制器考虑可再生能源出力的不确定性以及配电网的潮流约束给出每台每组空调的最优设定温度或者启停策略最终实现配电网运行经济性最优和用户舒适度损失最小的双目标。1.2 空调负荷为什么是一块“优质”的柔性资源很多人会问为什么非盯着空调负荷其他负荷行不行当然行但空调有它独特的优势。首先空调负荷占比高。夏季尖峰时段城市配电网中空调负荷可以占到总负荷的30%到50%这个量级对配电网运行的影响是举足轻重的。控制1%的空调负荷可能就相当于控制了一整个小型储能电站的功率。其次空调负荷具有天然的热储能属性。房间的墙体、家具、空气都有热容量制冷机关停10到15分钟室温上升通常不会超过1到2摄氏度。用户对短时间内的温度波动很不敏感这就给负荷控制提供了时间窗口。第三空调数量多、分布广单台功率一般在1到5千瓦但聚合起来总量惊人而且通过分户微网关或者智能插座就能实现远程控制通信和控制成本相对低廉。但空调负荷也不是随便想怎么控就怎么控。它涉及用户的舒适度控得太狠用户投诉控制信号下发太频繁压缩机会损坏空调的功率和房间温度之间存在非线性关系模型建不好控制效果会很差。所以问题的本质就是一个多约束、多目标、非线性优化问题这也是这个项目在技术上的真正难点。1.3 项目的研究目标和技术路线这个项目我给自己定了一个清晰的目标在Matlab环境下搭建一个完整仿真平台包含配电网模型、可再生能源出力模型、空调负荷模型和优化控制模型然后通过合适的优化算法求解得到空调负荷的优化调度策略验证其在削峰填谷、提高可再生能源消纳方面的效果。技术路线分四步。第一步建立配电网的潮流计算模型我选择了适合Matlab实现的牛顿-拉夫逊法跑IEEE 33节点系统作为基础算例。第二步建立空调负荷的ETP等效热参数模型用微分方程描述房间温度变化和空调功率之间的关系。第三步把可再生能源出力风电、光伏典型出力曲线作为已知输入并考虑预测误差的波动场景。第四步构建优化模型目标函数包含配电网购电成本、网损成本、空调负荷调节引起的用户舒适度损失约束包含潮流约束、节点电压约束、支路容量约束、空调功率约束和用户设定温度范围约束。优化求解方面我先用了Yalmip工具箱建模调用Cplex求解器处理混合整数线性规划的问题后来为了对比又写了基于粒子群算法的求解版本两者结果对照分析。下面我把每个环节的关键细节展开讲。2. 空调负荷优化控制的建模过程2.1 空调负荷的ETP等效热参数模型空调负荷建模不能一台一台地详细建模因为配电网中动辄几万台空调逐台建模的计算量是无法接受的。工程上最常用的做法是用等效热参数模型Equivalent Thermal ParametersETP来近似描述房间温度动态。ETP模型的核心思想是把房间看作一个热容节点把空调看作一个可控的冷源或者热源墙体等围护结构等效为一个热阻。这样房间温度的变化就可以用一个一阶微分方程来描述C · dT_in/dt (T_out - T_in) / R Q_ac其中T_in是室内温度T_out是室外温度R是建筑等效热阻C是建筑等效热容Q_ac是空调制冷功率正值表示制冷去掉为负的热量。把公式离散化变成差分方程T_in(k1) T_in(k) · e^(-Δt/(R·C)) (T_out(k) - Q_ac(k) · R) · (1 - e^(-Δt/(R·C)))这个式子看起来简单但实际使用中有几个坑需要注意。R和C的取值对模型精度影响巨大不同建筑结构的RC参数差异很大通常需要通过实测数据辨识。在仿真中我参考了文献中典型的商用建筑和居民建筑的RC参数范围并对参数进行了灵敏度分析发现C值偏大建筑保温好时空调负荷可中断的时间越长而R值偏小隔热差时温度恢复速度极快。这就意味着优化控制器给出的策略必须考虑到不同建筑类型的差异一刀切控制会有问题。2.2 空调功率与用户舒适度的关系空调的功率模型我采用的是简化模型单台定频空调工作时功率基本恒定制冷量也基本恒定但可以通过启停控制改变平均功率变频空调功率可以在一定范围内连续调节但建模更复杂。在ETP模型框架下空调的制冷功率Q_ac在制冷模式下可以用以下关系表示Q_ac COP · P_ac其中COP是空调能效比P_ac是空调消耗的有功功率。COP的取值范围一般在2.5到4.5之间我在仿真中取了3.5。用户舒适度损失我用温度偏离设定值的惩罚函数来衡量。最常见的方式是设置一个死区温度在设定值加减0.5摄氏度以内不罚超出部分按平方惩罚J_comf Σ α · max(0, |T_set - T_in| - ΔT_dead)^2这里α是用户舒适度权重系数ΔT_dead是死区半宽。选择平方惩罚而不是线性惩罚是因为温度偏差越大用户的不适感增长是加速的。这个惩罚函数最终会进入优化目标与配电网运行成本进行博弈。权重系数α的取值直接决定了控制策略偏向电网还是偏向用户我在实验中用不同α做了对比后面会详细说结果。2.3 配电网潮流约束与网络模型配电网层面的约束不能省略。空调负荷分布在不同的节点上如果只做负荷总量控制很可能出现某些节点电压越限同时另一些节点功率冗余的情况。我采用的方法是标准的配电网潮流模型。对IEEE 33节点系统用牛顿-拉夫逊法计算潮流得到各节点电压幅值和相角。在优化模型中潮流约束不是硬约束直接嵌入而是采用一种两步迭代的解法外层优化给出空调负荷调整量内层潮流计算校验电压和容量约束如果不满足约束就把违反约束的信息以罚函数方式返回给外层迭代直到收敛。这个方法在工程上很常用比直接把非线性潮流方程放进优化模型要好处理得多。虽然严格的凸优化建模更漂亮但对初学者来说迭代法的代码实现难度低很多而且效果并不差。如果硬要把潮流方程直接嵌入优化模型通常需要对潮流方程进行线性化处理比如用DistFlow模型近似这在Yalmip里也能做但公式推导和调试工作量会上一个台阶。2.4 目标函数与约束体系的完整表述整个优化模型我在代码里整理成了下面这个形式目标函数 min J J_grid J_loss λ · J_comfJ_grid是配电网从上级电网购电的费用J_loss是配电网网损费用J_comf是用户舒适度惩罚项λ是权重系数。如果使用峰谷分时电价J_grid可以直接取各个时段电价乘以购电量净负荷。这样就把电网经济性和用户舒适度统一在一个目标里。约束条件包括空调功率上下限约束0 ≤ P_ac,i(k) ≤ P_ac,i,max室内温度允许范围约束T_min ≤ T_in,k ≤ T_max节点电压约束U_min ≤ U_i(k) ≤ U_max支路功率容量约束|S_ij(k)| ≤ S_ij,max可再生能源出力约束0 ≤ P_res,i(k) ≤ P_res,i,forecast(k)其中可再生能源出力在这个模型里有两种处理方式第一种是确定性处理把预测出力直接作为已知量第二种是场景法生成多个预测误差场景然后取期望。我先做了确定性版本后来又加了3个误差场景做鲁棒性对比。代码架构上最好一开始就把场景循环的接口留出来否则后面改起来很痛苦。我一开始就是顺序迭代后来想加场景分析翻代码翻得头晕重构了两次才理顺。这一点提醒大家做科研性质的仿真框架接口设计一定要把场景并行的思路考虑进去哪怕你当前不打算做随机规划也要留出扩展位。3. Matlab仿真平台搭建与核心代码逻辑3.1 仿真平台的模块划分整个Matlab项目我分成了四个模块每个模块一个文件夹方便维护data目录存放负荷数据、光伏出力数据、风电出力数据、配电网网架参数、空调参数。model目录存放ETP模型函数、潮流计算函数、目标函数计算函数。optimizer目录存放Yalmip/Cplex求解脚本和粒子群算法求解脚本。result目录存放仿真结果图表和导出数据。这种模块化的好处到后期非常明显。因为优化问题的目标函数和约束不是一次写对的我改了很多版如果全写在一个脚本里改一处就得跑一遍全流程浪费时间还容易把好的版本改坏。分开模块后模型的改动只影响单机部分优化层不动测试起来很方便。3.2 基于Yalmip和Cplex的优化求解给不熟悉的同学简单说一下Yalmip是Matlab里的一个建模工具箱它最大的价值在于把优化模型的编写变得非常接近数学表达写完之后可以用统一的接口调用多种求解器Cplex就是其中一种处理混合整数线性规划问题效率非常高。在这个项目中我把空调的启停控制建模为0-1变量所以问题天然是一个混合整数规划。目标函数如果只保留购电成本、网损成本网损用线性近似和线性舒适度惩罚整个问题就是MILPYalmipCplex是可以直接处理的。核心代码逻辑大致是这样%% 定义决策变量 % P_ac: 空调功率连续变量, dim n_air × T % Z_ac: 空调启停0-1变量, dim n_air × T P_ac sdpvar(n_air, T, full); Z_ac binvar(n_air, T, full); %% 温度动态约束ETP离散化 % T_in(k1) T_in(k)*exp(-dt/RC) ... % (T_out(k) - COP*P_ac(k)*R) * (1 - exp(-dt/RC)) for k 1:T-1 for i 1:n_air constraints [constraints, ... T_in(i,k1) T_in(i,k)*A(i) ... (T_out(i,k) - COP(i)*P_ac(i,k)*R(i)) * (1-A(i))]; end end %% 功率与启停变量耦合约束 constraints [constraints, P_ac Z_ac .* repmat(P_max, 1, T)]; constraints [constraints, P_ac 0]; %% 目标函数 objective sum(sum(price .* P_grid)) ... lambda * sum(sum((max(0, abs(T_set-T_in)-delta).^2))); %% 求解 ops sdpsettings(solver, cplex, verbose, 1); optimize(constraints, objective, ops);这段代码是简化版本实际工程中P_grid需要靠节点注入功率约束和潮流方程连接起来这一步是最容易出bug的地方。我的做法是先用已知的不可控负荷和可再生能源出力计算节点净注入功率再把空调负荷的调整量作为附加注入加入对应节点然后用DistFlow线性潮流方程建立节点功率平衡。注意DistFlow在这里不能省略电阻项因为空调优化要评估网损电阻项直接关系到网损费用的计算精度。实际跑起来后我发现一个现象Cplex的求解速度确实快33节点、100台空调、24个时段整数变量2400个求解时间基本在2到3秒以内这一点对做多场景模拟非常友好。如果是更大的系统建议加求解时间上限或者用启发式算法先给一个较好的初始解再交给Cplex作MIP起点。3.3 粒子群算法版本的实现思路写粒子群算法版本是为了做对比验证因为很多审稿人或者导师会质疑单一求解器结果的可靠性两个独立算法得到近似一致的结果说服力会强很多。粒子群算法的思路是把每个粒子定义为一套空调设定温度的调整方案即一个n_air × T的矩阵然后通过迭代更新粒子的位置和速度来寻找最优方案。粒子群算法做这个问题的挑战在于约束处理尤其是温度动态约束和节点电压约束。我在实现中采用的是罚函数法处理违反约束的情况对电压越限按越限量平方处罚加进适应度函数。%% 粒子位置初始化 % 每个粒子的位置 x 是空调设定温度偏移量范围 [-2, 2] 摄氏度 x lb rand(pop_size, dim) .* (ub - lb); v zeros(pop_size, dim); %% 迭代循环 for iter 1:max_iter for p 1:pop_size % 计算适应度先更新空调功率和温度再计算潮流 fitness(p) calc_fitness(x(p,:), data); end % 更新个体最优和全局最优 [best_fitness, best_idx] min(fitness); gbest x(best_idx,:); % 更新速度与位置 v w*v c1*rand(pop_size, dim).*(pbest - x) ... c2*rand(pop_size, dim).*(gbest - x); x x v; end粒子群参数的选择我花了不少时间调。惯性权重w从0.9线性递减到0.4加速度系数c1取1.5c2取1.5种群规模80最大迭代次数500。这些参数不是随手拍的我做了几组对比实验w过大时前期搜索范围广但后期收敛慢w过小了又容易陷入局部最优。最终取值是多次试验后的折中。粒子群算法一个明显的缺点是每次适应度计算都要跑一遍潮流迭代500次、80个粒子就是40000次潮流计算单次潮流即使很快0.05秒总耗时也要2000秒以上接近半小时。我在做参数敏感性分析的时候把这种情况简化了对空调负荷调整量较大的场景才重算潮流调整量小的场景直接用灵敏度系数近似电压变化速度提升明显代价是精度略有下降。这个方法值得推荐给着急出结果的同学但如果是写正式的学术论文建议还是不要用近似省下来的时间不值得防御审稿人质疑。3.4 结果可视化与数据导出Matlab里做结果可视化我主要用了几个图优化前后总负荷曲线对比图柱状图折线图叠加空调总功率时序图各节点电压幅值热力图用户室内温度变化曲线光伏出力和弃光率对比这里有一个经验图一定要在仿真过程中用saveas或者exportgraphics及时导出不要在全部仿真跑完之后再统一画图。因为空调优化问题一跑就是几十分钟中间某一步结果异常可以立刻看到并中止调试能省下大量时间。结果数据我统一保存成结构体mat文件再写一个单独的分析脚本读取画图和分析分离。否则每次调整参数都要重新从头跑一遍仿真效率极低。4. 算例设计与结果分析4.1 算例参数设置配电网算例我采用IEEE 33节点系统基准电压12.66千伏基准功率10兆伏安。系统总负荷我按夏季典型场景设定为3715千瓦加2300千乏一共15台空调负荷分布在负荷较重的节点上每台空调的额定功率取3千瓦房间等效热阻0.12摄氏度/千瓦等效热容3.3千瓦时/摄氏度。可再生能源方面配电网接入了一个2000千瓦的光伏电站和一个1500千瓦的风电场。光伏出力曲线用夏季晴天的典型形状峰值出现在中午12点到14点风电出力取夜间较大、白天较小的典型反调峰模式。这两个出力的叠加效果就是净负荷曲线的形状比较极端午间净负荷很低、晚高峰净负荷很高非常适合用来检验空调负荷优化控制的效果。电价采用典型的分时电价峰时8点到22点0.95元/千瓦时谷时22点到次日8点0.35元/千瓦时。这个设置对优化控制策略有直接的引导作用空调负荷会在谷时段多制冷蓄冷峰时段少制冷释放弹性。4.2 无优化与优化策略的仿真对比先看没有空调优化控制的基准场景也就是空调自由运行、温度设定值固定24摄氏度不变。这时候系统净负荷曲线的形状基本由不可控负荷和可再生能源决定午间净负荷最低点在3200千瓦左右晚间最高点接近5600千瓦。计算得到一天的购电成本约4.35万元。再看优化控制结果。空调温度设定值允许在22到26摄氏度之间浮动舒适度权重系数λ取20。优化后的净负荷曲线明显被削峰填谷了。晚间高峰时段部分空调设定温度上调1到2摄氏度空调总功率最多下降了28%左右净负荷峰值降到了4950千瓦附近降幅约11.6%。午间低谷时段空调设定温度下调相当于提前给房间降温把部分白天用电转移到光伏出力大、电价低的时段午间净负荷抬高到了3600千瓦弃光风险明显下降。购电成本从4.35万元降到了3.98万元下降了8.5%左右。用户舒适度损失折算下来平均每户室内温度偏差约0.8摄氏度这个幅度对大多数人来说基本感知不到但电网侧获得了实实在在的好处。这个权衡结果说明空调负荷优化控制的性价比非常高。网损方面优化后系统总网损从152.4千瓦时降到了139.1千瓦时降幅8.7%。原因也比较好理解负荷曲线被抹平之后高峰期支路电流减小线路上的有功损耗自然降低。这个结果对配电网运维来说是一个有价值的附加收益。4.3 不同权重系数下的结果对比舒适度权重系数λ的取值直接决定了策略倾向。我做了一组扫描实验λ分别取1、10、20、50、100观察净负荷峰值削减率和平均温度偏差的变化。λ1时优化算法几乎不在乎用户舒适度净负荷峰值削减率达到22%但平均温度偏差高达2.6摄氏度用户可能会明显感到不适这在实际中是不可接受的。λ100时反过来平均温度偏差只有0.2摄氏度但净负荷峰值削减率只有3%左右基本等于没有调节能力。λ20到50之间是比较合理的平衡区峰值削减率10%到15%平均温度偏差控制在0.5到0.9摄氏度。这个规律很重要做项目展示或者写报告的时候一定要把这条敏感性曲线画出来它比单个优化结果更能说明问题也能让你在答辩或者讨论时更有底气。实际落地的控制策略也可以借鉴这个思路设定一个温度舒适度底线在底线之上做经济性优化。4.4 可再生能源渗透率与调节效果的关系我用同一个仿真平台测试了可再生能源渗透率从10%提升到50%的情形。渗透率越高净负荷的峰谷差越大空调负荷优化控制的收益空间也越大。渗透率10%时优化后的购电成本只能降低3%左右渗透率30%时成本降低7.8%渗透率50%时成本降低接近12%。这个结果强烈说明一个问题可再生能源占比越高配电网对空调负荷这类柔性资源的需求就越迫切。在做项目汇报时把这个图放进去非常直观。5. 常见问题与调试经验实录5.1 Yalmip安装和求解器调用踩坑Yalmip本身是个工具箱安装不难难的是最后调用Cplex求解器时各种不兼容。我最初在R2022b版本上装的是Cplex 12.10结果一跑就报“Unable to locate or start CPLEX executable”之类的错误。查了一圈发现问题主要是路径里没把Cplex的Matlab接口文件夹加上而不仅仅是主程序路径。解决办法在MATLAB根目录上右键设置路径把cplex安装目录下的...\cplex\matlab\x64_win64注意按自己的平台选择加进去然后运行yalmiptest测试安装状态。如果测试显示cplex求解器被识别但实际求解时还是报错十有八九是版本兼容性Cplex 12.10对R2022b以上的版本支持不好换用Cplex 12.9或者更新版本能解决。还有一个细节如果用的破解版或者第三方下载的Cplexlicense初始化偶尔会失败报错信息往往不明确。这时候打开cplex的install目录用install_mex命令手动安装Matlab接口再检查环境变量CPLEX_LICENSE_FILE是否指向了正确的license路径。我在这个环节浪费了整整一个下午最后发现是license文件的路径带了中文目录导致读不出来改到纯英文路径后一切正常。5.2 ETP模型参数不准确导致优化结果失真空调负荷的RC参数如果不准确优化算法给出的控制策略在实际中会完全失效。我刚开始随机给所有空调设了统一的RC参数结果仿真结果非常乐观峰值削减率达到25%。后来我把参数替换成三组不同建筑类型的混合参数商用楼、普通居民楼、老旧住宅结果峰值削减率掉到了12%。原因很简单统一参数使得所有空调的动态响应完全同步优化控制可以精准地同时削减功率但实际中建筑热惯性差异大响应速度不同同时削减的效果会被错开等于变相削弱了控制精度。经验建模时一定不能图省事用单一RC参数至少把负荷分成三类以上每类的百分比尽量贴合实际统计数据。参数敏感性分析也要做如果你发现结果对RC参数极其敏感说明模型本身有脆弱性写论文这类结果很容易被质疑。5.3 粒子群算法求解不稳定怎么办粒子群算法我跑了多次发现结果不太稳定有时收敛到好的解有时收敛到差的解。原因之一是没有做足够的重复试验PSO本质是随机算法单次运行结果不能说明问题。我的处理办法是每次仿真跑20次取适应度最好的解作为最终结果同时记录均值和标准差作为鲁棒性指标。一个额外的发现是种群规模和迭代次数增加到一定程度后结果改善非常有限但计算时间成倍增长。对于这个规模的问题100个粒子、500次迭代基本就是性价比的拐点再大只是浪费时间。另外约束处理上如果用罚函数法罚系数太小会导致解越限太大会让目标函数曲面出现悬崖搜索方向混乱。我建议罚系数别设成常数可以设计成随迭代次数逐渐增大前期允许探索越限空间后期强制收敛到可行域效果比固定系数好很多。5.4 求解速度慢时的排查思路如果Cplex求解MILP时间过长先别急着换算法按这几步排查第一步检查模型中是不是有冗余的大M约束引入了过大的数值尺度问题导致求解器数值精度异常。把大M换成element-wise约束或者用一个足够大但不过分的上界。第二步检查整数变量的数量。如果你把每台空调每小时的启停都设成独立整数变量那变量数很容易爆炸。可以考虑对同类型空调做聚合用一台等效空调代表一组整数变量瞬间降一个数量级。第三步增加Cplex的求解时间上限和MIP gap容差。实验类应用没必要追求全局最优解gap容差设置到2%或者3%完全够用求解速度能快好几倍。这一点是我实际感受最深的默认gap是0.01%有时候为了证明某几个变量之间的微小差异会耗费巨量分支完全没必要。5.5 结果画图与数据导出的细节最后分享一个很小但很实用的经验Matlab里导出的图片默认字体和图例在投稿或者写报告时经常显得不够清晰。不要偷懒用截图直接用exportgraphics函数导出设置分辨率300dpi以上。尺寸上我通常设置为16厘米×9厘米这样插到论文双栏里刚好合适。还有做对比分析时不要只画一张总图。把空调总功率、室内温度平均值、最高温度、节点电压最低值、购电功率这几条曲线分别画成多个子图标注清楚每个子图的优化策略。审阅者看起来省力你自己复盘结果时也容易定位问题。做仿真研究结果图的叙事能力很多时候比参数表更打动人。说实话这个项目做完之后我的一个体会是空调负荷优化控制真正的难点不是算法本身而是模型的合理性和参数的可信度。Matlab代码实现的部分反而是相对固定的套路。无论是ETP模型的RC参数、可再生能源出力数据、还是用户舒适度权重任何一项拍脑袋乱定最终优化结果都会经不起推敲。所以建议大家拿到别人的代码第一件事不是跑结果而是把里面的参数一个一个抠出来搞清楚来源和物理意义再替换成自己场景的数据这样改出来的项目才是自己的东西。如果你正在做类似的方向我的建议是从确定性模型入手把ETP模型和潮流计算的接口先跑通再加场景分析和随机规划。现在很多论文直接用深度强化学习做空调负荷控制但不了解底层优化模型就直接上端到端的强化学习中间出了问题很难排查。先把传统的优化控制模型吃透再结合强化学习方法做对照这条路走起来会稳很多。