做配电网研究这些年最让我觉得值得写一篇文章分享的就是空调负荷优化这一点。每年夏天傍晚光伏出力开始往下掉空调负荷却踩着高峰往上蹿配电网的变压器和线路被压得喘不过气。而另一边白天光照最好的时候光伏又呼呼往电网里送电出现倒送功率、电压越限。一个要削峰一个要消纳两件事拧在一起很自然的思路就是让空调负荷动起来跟着可再生出力的节奏走。这篇东西我就围绕“含可再生能源的配电网最佳空调负荷优化控制”把问题建模、Matlab实现、算例分析和踩坑经验完整记录下来给正在做类似课题的同学和工程师一个可以直接参考的路线。1. 问题拆解与整体思路1.1 空调负荷凭什么能参与配电网优化一台家用空调的功率通常在1kW到3kW之间单看不起眼但一个台区几百台空调同时运行聚合起来的功率可能就是几百千瓦甚至兆瓦级。更重要的是空调本身就是带储能特性的负荷——房间墙体、室内空气和家具会储存热量所以空调具备“短时关机但温度不会立刻失控”的能力。这种热惯性决定了空调负荷不是刚性的它可以在一定范围内调整用电时机和用电功率本质上就是一种灵活资源。参与优化控制时空调负荷大致有两种调节手段。一种是直接负荷控制也就是我们常说的DLC由调度端下发指令对空调进行周期性启停或温度设定值调整。另一种是通过价格信号诱导比如分时电价下用户自主调整温度。针对配电网层面的优化控制我通常更倾向于温度设定值调节因为它对用户舒适度的影响更可控也更容易建模成连续变量或离散档位。一个很关键的点是空调负荷优化的价值必须放到“含可再生能源”的场景下才真正体现出来。光伏在午间大发净负荷被压得很低甚至出现负值这时可以把空调温度调低一点让空调多制冷相当于把光伏电量用掉转化为房间冷量存储起来。等到傍晚光伏迅速回落负荷尖峰出现时再把温度调高/关掉一批空调利用房间冷量释放来削减峰值。这个“储能”过程完全不需要电池代价只是房间温度在舒适区间内有变化。1.2 含可再生能源配电网的核心矛盾传统配电网的调控思路主要是“源随荷动”但可再生能源接入后电源侧变得不可控净负荷曲线出现了剧烈的双向波动。我在处理实际算例时最常见的两个现象就是午间光伏出力高而负荷低馈线潮流倒送节点电压升高存在过电压风险傍晚光伏出力快速下降负荷快速上升主变和馈线过载节点电压偏低。如果只靠调节有载调压变压器和投切电容器很难解决这种短时、反复的波动问题。储能当然可以但投资成本高。而空调负荷分布广泛、响应速度快通过优化控制可以起到类似储能的一部分作用。但这里有个约束配电网运行必须保证用户舒适度。空调负荷的优化不是“关掉就行”而是要在温度允许偏差范围比如设定温度26℃允许上浮/下浮1℃也就是温度维持在25~27℃之间内寻找最佳控制策略。这个约束让问题从简单的“直接切除负荷”变成了一个有边界条件的最优控制问题。所以我理解的“最佳空调负荷优化控制”核心是找一个控制策略序列在满足温度舒适度和配电网安全运行的前提下最大化可再生能源消纳、最小化网损或者削峰效果并且可落地到Matlab代码上。1.3 优化目标与建模路线选择建模之前必须先想清楚目标函数是什么。不同目标下最优控制策略差别很大目标类型数学表达式典型应用场景削峰填谷最小化净负荷曲线峰谷差配变容量紧张、需量电费高网损最小最小化支路功率损耗之和高渗透率光伏、运行经济性要求高运行成本最小最小化购电成本或弃光惩罚市场化售电或微电网电压控制最小化节点电压偏差低压线路长、光伏倒送明显多目标加权上述若干项加权组合综合示范工程我的经验是第一版模型尽量先做单一目标比如以“净负荷峰谷差最小”为目标跑通之后再慢慢加权重。一上来就写多目标加权很容易陷入参数调不过来、结果解释不清的窘境。求解路线方面如果只考虑温度设定值的离散档位空调优化问题可以建模成混合整数线性规划MILP用解算器能拿到全局最优解。如果考虑连续温度调节热动力学方程本身是线性差分方程所以仍然可以保持线性结构。配电网潮流如果需要精确计算可以用DistFlow方程做二阶锥松弛SOCP后问题就变成混合整数二阶锥规划MISOCPMatlab下可以用Yalmip建模再交给Gurobi或Cplex求解。对于刚起步的同学我建议先把潮流做成直流潮流或线性化的DistFlow用MILP先跑通再逐步提高精度否则模型复杂度和调试难度同时上来容易劝退。2. 数学模型构建与关键约束2.1 空调负荷热动力学模型ETP模型单个房间的热过程可以用等效热参数ETP模型描述。最常见是一阶等效模型就像给房间画一个热容量和一个热阻构成的电路。一阶ETP模型的状态方程是T_in(t1) T_out - η·R·P·u(t) - [T_in(t) - T_out η·R·P·u(t)]·exp(-Δt/(R·C))这里T_in室内温度℃T_out室外温度℃η空凋能效比EER或COPR房间等效热阻℃/kWC房间等效热容kWh/℃P空调额定电功率kWu(t)空调启停状态0或1Δt时间步长h这个模型物理含义很直观房间温度会朝“室外温度叠加空调制冷/制热等效温度”这个稳态值趋近趋近的快慢由R·C时间常数决定。我一般把Δt设为15分钟或1小时。1小时步长模型简单但空调启停控制粒度太粗15分钟步长的模型能描述更精细的调节策略缺点是优化变量会增加到4倍。聚合空调时不能简单把所有空调的R、C、P取平均就完事。更稳妥是保留多样性温度初始值、时间常数、设备容量按一定分布抽样生成然后聚合成若干个“空调群”每个群内部参数接近用“群聚合模型”参与优化。这样既能降低变量维数又不会损失太多精度。2.2 配电网潮流与可再生能源出力模型配电网潮流我推荐用DistFlow方程。对于辐射状配电网每条支路和节点满足P_ij - R_ij·L_ij sum(P_jk) - P_j_inj Q_ij - X_ij·L_ij sum(Q_jk) - Q_j_inj V_j^2 V_i^2 - 2(R_ij·P_ij X_ij·Q_ij) (R_ij^2 X_ij^2)·L_ij其中L_ij (P_ij²Q_ij²)/V_i²是支路电流平方项。这个方程本身是二次的一般做法是引入二阶锥松弛把等式L_ij (P_ij²Q_ij²)/V_i²松弛为不等式从而让整个问题变成可以高效求解的凸问题。算例规模不大时也可以直接用matpower做交流潮流把优化和潮流迭代耦合起来不过那样求解速度会慢很多调试也更麻烦。可再生能源出力模型相对简单。光伏出力曲线可以用某典型日的小时数据也可以加一定比例的正态扰动模拟预测误差P_pv(t) P_pv_forecast(t) ΔP(t)风电类似。我建议在代码里单独写一个renewable_forecast.m这样后续做鲁棒优化时改起来很顺手。另外要强调的是可再生能源出力的时间尺度和空调控制的时间尺度必须对齐都用15分钟否则末端控制执行的时候会跟实际出力对不上。2.3 目标函数与约束条件详解我常用的一个综合目标函数是min sum_t [ α·(P_net(t) - P_avg)² β·sum_branches(I²(t)·R) γ·sum_nodes(V(t) - V_ref)² δ·sum_aircon(P_aircon_baseline - P_aircon(t)) ]其中P_net是配电网根节点处与上级电网交换的功率P_avg是全天平均交换功率I²R是网损V是节点电压偏差最后一项是空调调节量惩罚防止为了削峰过度牺牲用户舒适度。约束条件大致分四类空调运行约束室内温度必须在舒适区间内比如[T_set - ΔT_max, T_set ΔT_max]空调功率有上下限如果采用启停控制启停变量是0/1整数如果采用温度设定档位档位也是离散整数。配电网安全约束节点电压上下限通常取0.95~1.05pu支路电流或视在功率不超过上限根节点交换功率不超过主变容量。可再生能源约束光伏/风电出力不能超过预测值的上限若允许弃光则实际出力是可调的且弃光量有上限或惩罚项。用户舒适度约束这是容易漏掉的关键点。如果目标函数里没有对空调功率偏离的惩罚优化器可能把空调全关或者全开虽然满足了电网目标但室温会越界。所以温度约束和功率调节惩罚要同时存在一“硬”一“软”搭配。我一般会把温度舒适度设成硬约束硬边界把用户可感知的“温变速率”设成软约束惩罚项。因为就算温度没越界如果半小时内从26℃掉到24.5℃用户也会觉得不舒服。3. Matlab代码实现架构3.1 整体文件结构与数据准备Matlab实现不必一开始就把所有代码写进一个大脚本。我推荐的文件结构是main.m主程序负责全局配置、调用各模块、展示结果load_input_data.m读取系统参数和预测数据build_aircon_model.m生成空调群的ETP参数和初始状态build_distflow_model.m构建配电网DistFlow约束矩阵formulate_optimization.m用Yalmip定义变量、目标函数和约束solve_optimization.m调用求解器处理求解选项和结果解析run_validation.m用matpower或直接计算验证解是否满足潮流约束plot_compare.m绘制优化前后对比曲线数据准备方面配电网参数我建议直接用IEEE 33节点算例的公开数据把线路阻抗、节点负荷改成带空调负荷的形式。可再生能源数据可以找一个典型日的光照强度然后转换成光伏出力。整个过程一定不要忘记设置时间参数total_period比如96个15分钟时段、dt 0.25h。3.2 核心代码模块讲解先看build_aircon_model.m的核心结构function aircon build_aircon_model() % 生成空调群参数聚合N台空调 n_aircon 200; % 空调台数 % 按分区抽样生成房间热阻、热容和空调功率 aircon.R sort(18 6*rand(n_aircon,1)); % ℃/kW aircon.C sort(0.5 0.2*rand(n_aircon,1)); % kWh/℃ aircon.P 2.5 0.8*rand(n_aircon,1); % kW aircon.T0 26 0.3*randn(n_aircon,1); % 初始室温 aircon.eta 3.2; % 能效比 aircon.Tset 26; % 设定温度 aircon.dT 1; % 允许波动范围±1℃ end这里R和C的分布要合理住宅房间典型热阻在10~30℃/kW热容在0.3~0.8kWh/℃别随手乱设否则温度响应时间会异常。formulate_optimization.m里用Yalmip定义变量和约束% u是n_aircon×T维的0/1启停变量或温度档位整数变量 u binvar(n_aircon, T_full); T_in sdpvar(n_aircon, T_full1); % 室内温度 % 温度递推约束 for k 1:n_aircon for t 1:T_full T_in(k,t1) T_out(t) - aircon.eta*aircon.R(k)*aircon.P(k)*u(k,t) ... - (T_in(k,t) - T_out(t) aircon.eta*aircon.R(k)*aircon.P(k)*u(k,t))*exp(-dt/(aircon.R(k)*aircon.C(k))); end end如果温度全程写成变量维度会很大。200台空调、96个时段T_in就有19200个变量u又有19200个二进制变量这个规模对MILP来说还勉强能解如果空调数量到1000台就如坐针毡。我的做法是采用“空调群聚合”策略把200台空调按参数相似性聚类成10~20个群每个群内的空调启停比例是连续变量用“群内可中断比例”代替每台独立开关这样变量数大幅下降。代价是精度稍低但工程上完全够用。DistFlow约束我通常不直接展开写成大矩阵而是用Yalmip的循环赋值方式for i 1:n_branch constraints [constraints, P_branch(i) - R(i)*L_branch(i) sum(P_child(i,:)) - P_inj(i)]; constraints [constraints, V_child(i) V_parent(i) - 2*(R(i)*P_branch(i) X(i)*Q_branch(i)) (R(i)^2X(i)^2)*L_branch(i)]; % 二阶锥松弛 constraints [constraints, L_branch(i) (P_branch(i)^2 Q_branch(i)^2)/V_parent(i)]; end注意二阶锥约束在Yalmip里可以直接写成不等式它会自动识别为SOC约束。3.3 求解器选择与参数调试我首选的求解组合是Yalmip Gurobi。Gurobi对MILP和MISOCP的支持都很好尤其是节点数到几万、变量几千时依然稳健。如果电脑没有Gurobi可以用Cplex或者退一步用MATLAB自带的intlinprog。不过intlinprog处理二次约束和SOCP的能力较弱所以模型里的二阶锥约束就得丢掉改回直流潮流或线性化潮流。求解器选项值得花时间调整。我最常用的是ops sdpsettings(solver,gurobi,verbose,2); ops.gurobi.MIPGap 0.01; % 1%的最优间隙 ops.gurobi.TimeLimit 300; % 限制5分钟 ops.gurobi.NumThreads 4; % 多核MIPGap不要设成0一方面很难在有限时间达到另一方面意义也不大工程上1%~5%的间隙完全可接受。TimeLimit很重要否则算例稍大就可能跑一整晚。调试阶段先用8个时段跑通再扩展到24、96个时段这样能快速发现模型错误。4. 算例分解与效果分析4.1 典型日场景设置我用IEEE 33节点配电网做一个代表性算例。33节点系统包含32条支路基座负荷约3.7MW我在节点6和节点18接入两座光伏电站装机分别800kW和600kW。空调负荷集中挂接在节点8、12、20及24总共模拟了200台用户空调聚合基线功率约300~400kW。时间范围选夏季典型日从上午6点到次日6点步长1小时总共24个时段。光伏出力按典型晴朗日曲线午间12~14点出力最大又叠加一个出力缩放系数。空调需求高峰在傍晚18~20点室外温度用一天的正弦曲线模拟集中在30~38℃之间。目标函数第一版设为minimize sum((P_net(t)-P_net_avg)^2)即最小化根节点交换功率的方差这样直接抑制净负荷波动。约束包括室内温度24~28℃节点电压0.95~1.05pu支路电流上限参照原算例热稳定极限。求解用GurobiMIPGap1%TimeLimit120s。4.2 优化前后对比无控制时净负荷曲线呈现典型的“鸭子曲线”午间光伏大发根节点交换功率降到1.8MW左右傍晚光伏降、负荷升交换功率冲到4.5MW峰谷差约2.7MW。优化控制后午间空调群温度设定值整体下调空调多出力净负荷低谷被“填高”到2.3MW左右傍晚温度上调部分空调停机净负荷峰值被削到3.6MW左右。峰谷差降到1.3MW削峰效果超过50%。节点电压方面午间原本节点18电压达到1.07pu优化后压到1.04pu以内傍晚原本节点24电压最低0.94pu优化后回升到0.97pu以上。空调用户舒适度如何呢优化后的室内温度曲线在午间会略低于设定值比如从26℃降到25℃傍晚略高于设定值最高到27℃始终在24~28℃区间内。这说明了柔性负荷的潜力用户几乎无感知电网却获得了可观的调节空间。4.3 敏感性分析我习惯把几个关键参数各跑一遍看结果是否稳健空调渗透率从20%提升到80%峰谷差削减率从12%提升到58%但渗透率超过60%后收益增速放缓原因是配电网其他安全约束开始占主导再增加空调可调容量也发挥不出来。允许温度波动范围从±0.5℃放宽到±2℃可调功率容量提升了约70%峰谷差削减率提升了约23个百分点。这说明舒适度区间是影响可调潜力的最大因素。光伏预测误差从±5%增加到±20%时如果采用确定性模型午间电压越限风险明显上升。后来我改成了鲁棒优化的简单版本用预测区间边界参与约束虽然目标函数值比确定解略保守但电压越限概率大幅下降。这些敏感性分析能帮你向评审或领导解释项目价值也更接近实际工程中的决策过程。5. 常见问题与排查技巧实录5.1 模型不收敛的排查清单遇到求解器长时间不收敛或者返回infeasible别急着怀疑求解器先按这个清单排查症状可能原因处理办法返回Infeasible温度约束与功率约束相互矛盾比如要求温度同时低于25℃且空调停机过热检查舒适度范围、空调功率上下限适当放宽温度边界或增加调节惩罚项求解进度长时间卡在0%二进制变量过多或约束过于复杂用空调分群聚合、缩短时段数、先线性化潮流解出来了但节点电压越限潮流模型与优化模型不一致比如DistFlow松弛不紧用matpower或前推回代校验必要时收紧松弛条件加罚额外松弛量温度曲线出现振荡时间步长太大或模型参数R、C不合理减小Δt到0.25h检查热时间常数R·C是否在数小时量级有一个很隐蔽的错误我在空调群聚合时对空气混合平均后直接求温度递推结果完全忽略了个体差异导致优化结果看似很好但单台空调的温度却越界。后来改为保留群体内温度的上下包络作为约束问题就正常了。5.2 参数整定心得ETP参数R和C是影响结果的第一要素。R和C没有实测值时不要随便从网络上抄一组数建议根据房间面积估算。我常用经验公式R约为20~25℃/kWC约为0.4~0.7kWh/℃时间常数τR·C约在8~15小时之间。τ太小房间保温差空调一停温度立刻反弹优化空间小τ太大温度对空调启停不敏感控制效果也不明显。目标函数权重α、β、γ的比例调起来很费时间。我建议先固定β和γ为0纯跑削峰目标得到功率曲线之后再把网损和电压偏差的权重从小往大加。注意权重跨数量级时比如α1β1000V0.01Yalmip自动归一化并不总是智能需要你手调数量级。另一个经验是Big-M取值。在很多约束中要引入启停的辅助变量需要一个足够大的M。如果M太大Gurobi求解数值会变差M太小又会错误地激活或钳制约束。我的方式是先计算所有变量可能的最大范围比如支路功率不超过5MW那么M取10就够了不要为了省事写1e6。5.3 代码实现中的几个隐藏坑第一Matlab的Yalmip在定义二进制变量时如果直接使用binvar(n,T)后续矩阵运算很容易因为维数不一致报错。我建议保持所有的变量名称带明确后缀比如u_open、P_aircon_agg、T_room不要复用变量名。否则Yalmip不会报错但会把新变量悄悄覆盖掉极端情况下结果完全错误却找不到原因。第二时间序列索引偏移。温度递推时T_in(k,1)是初始状态T_in(k,2)是第一个时段结束的温度。约束里如果把t1时的温度错误写成T_in(k,1)整个系统移位一个时段结果看起来也合理但物理意义是不对的。排查时我会打印前几个时段的温度值与递推结果核对。第三光伏出力数据的归一化。光伏出力原始数据可能是kW而配电网负荷单位是kW但节点基值可能用了MVA。DistFlow方程里的所有量纲必须统一否则电压计算结果会出现0.001量级的诡异偏差。我的习惯是所有数据进入优化函数之前全部转换为标幺值基准功率1MVA、基准电压12.66kV输出结果再转回有名值。第四关于“最佳”的误解。很多同学把“最佳”理解成单个空调的温度设定点最终输出一个全局最优温度曲线。实际上工程上更常用是“群组调节指令”也就是对每群空调发布一个温度调节量或者最大允许功率百分比而不是管每台空调的启停。所以代码实现时我更推荐输出“空调群功率调节比例”再在群内通过轮询启停实现这样既保护了用户私密性又降低了通信要求。结尾分享一下我个人的操作体会我最初做这个课题时一上来就把目标函数写成网损、电压、舒适度、弃光四项加权空调用了单台模型加上二阶锥潮流整个模型维度非常恐怖。Gurobi跑了两小时没出结果当时差点崩溃。后来我退回到“单目标聚合空调直流潮流”两天内就把整个流程跑通了再逐步加回精度效果反而更好。所以我特别建议第一版代码务必追求“能跑通、能出图、能解释”不要追求模型面面俱到。另外优化控制落地到实际系统时最容易被忽略的是通信时延和用户行为不确定性。模型求出来的“最佳”控制序列在实际执行时可能因为用户手动调温度、空调进入除湿模式等原因失效。一个务实的做法是采用滚动时域控制每15分钟重新求解未来1小时的优化问题只执行当前时段的指令。虽然代码里需要额外写一个循环调用求解器但这个改动能让控制效果非常稳定这一点在我后期做半实物仿真时体会特别深。如果你正准备复现这个题目我建议从IEEE 33节点加上200台空调聚合这个搭配开始先把优化后的峰谷差图跑出来再研究电压和消纳效果。代码写完之后一定要用matpower验证一下你优化结果对应的是否真正满足交流潮流约束。这一步能帮你发现绝大多数建模错误。希望这份经验能让你少走一些弯路。