简介:本资源面向能源系统优化、智能楼宇调度及微电网研究领域的高校师生与工程技术人员,提供一套融合电-热-冷多能耦合与价格型/激励型需求响应的智慧楼宇多时间尺度调度完整解决方案。资源包含日前、日内、实时三阶段Matlab建模与求解程序,支持风光不确定性建模、储能容量协同配置、电动汽车负荷分阶段响应策略(可平移负荷前置、可削减负荷嵌入日内、储能动态参与全周期),并涵盖源荷预测误差分布对储能配置的影响分析、弹性电价系数矩阵维度适配等关键技术细节。压缩包共95个文件,含69个.mat数据文件(如P_EV_96.mat、E_load_96.mat等)、5个.m主程序脚本、8个.fig可视化结果图、7个.vsdx架构图(含多时间尺度调度框架、CHP热电耦合、ELMAN回归神经网络等)、2个.xlsx记录表及2个.lp优化模型文件,整体3.11MB,结构清晰、模块解耦。已有322人学习下载,可直接运行复现调度全过程,获取完整数据链、分阶段变量处理逻辑及多能流平衡验证结果。 智慧楼宇的能效优化这几年一直是能源领域的热门方向,但真正能把“综合需求侧响应”落到代码层面、跑通整条调度链路的资料并不多。很多人拿着概念模型图能讲得头头是道,一打开Matlab就不知道怎么把那些抽象的设备模型、时间尺度衔接变成可运行的程序。这篇博文围绕“考虑综合需求侧响应的智慧楼宇多时间尺度调度策略(Matlab完整程序和数据)”这个主题,把我自己在搭建这套仿真框架时的建模思路、程序架构、数据准备和调试过程完整梳理一遍。适合正在做建筑能源管理、需求响应策略研究,或者需要快速上手Matlab调度优化程序的研究生和工程师参考。
1. 智慧楼宇里的可调度资源:从单一电负荷到综合能源
1.1 为什么传统需求响应在楼宇场景下不够用
传统需求响应通常把用户侧看成“被削减的刚性负荷”,给个激励信号,楼宇关掉一部分空调机组、照明或者让生产线错峰,逻辑上是“电网让削多少,用户削多少”。这种模式在工业用户身上相对有效,因为工业负荷集中、可控性强,但在智慧楼宇里就会遇到问题:楼宇内部的负荷构成复杂,冷、热、电多种能源耦合在一起,楼宇里通常还有分布式光伏、储能、蓄冷蓄热装置,用单一的“削负荷”思路去操作,既不经济,也容易牺牲舒适度。
我最早做这个项目时也走过弯路。当时只把楼宇当作一个电负荷节点,空调、电梯、照明全部看成刚性负荷,用分时电价做削峰填谷,结果储能配置很大,收益却寥寥。后来换成“综合需求侧响应”的思路——把冷、热、电三类能量统一放入调度框架,用空调的热惰性做短时调控,用蓄冷蓄热罐做小时级的能量搬移,用储能和电动汽车做功率平衡,调度空间一下子大了很多。所谓“综合”,本质是打破能源品种之间的墙,让电、冷、热互相补充。
1.2 楼宇可调负荷的分类与聚合建模
做Matlab程序之前,第一步必须把楼宇里的可调资源分类整理清楚。综合需求侧响应下的智慧楼宇通常包含以下几类可调度资源:
- 空调系统:占楼宇电耗30%-50%,是最大的柔性负荷。空调系统的可调度性来自建筑热惰性——房间温度变化是渐进的,短时间改变机组出力不会立刻导致舒适度超标。建模时可以用等效热参数模型来描述室内温度与空调功率的关系,用热容C、热阻R这两个核心参数刻画蓄热惯性。
- 储能系统(电池):具备双向调节能力,充电、放电、待机三种状态,约束条件包括功率上下限、SOC上下限以及充放电倍率约束。电池在综合响应中的角色是“功率缓冲器”,负责平衡光伏波动和负荷峰谷。
- 蓄冷/蓄热装置:楼宇冷热系统的“量缓冲器”。冰蓄冷或水蓄冷可以在电价低谷期把冷量储存起来,在电价高峰释放。蓄冷槽的状态用蓄冷量(kWh)表示,类似电池SOC,但时间常数更大,储存成本更低。
- 分布式光伏:不可调度但可预测的电源。在日前调度中作为确定性出力,在日内滚动调度中根据实时气象修正。
- 柔性照明与插座负荷:可削减的比例不大,但响应速度快,适合日内实时调节。通常设定一个最大削减比例,比如10%-20%。
这些设备的响应时间常数差异很大。电池是秒到分钟级,空调是分钟到小时级,蓄冷罐是小时级。如果只用单一时尺度的模型去描述它们,必然产生偏差。这就引出了多时间尺度调度的必要性——设备响应速度不同,调度决策的时间粒度也应该分层。
1.3 楼宇综合能源系统的耦合关系
楼宇里电、冷、热三种能源通过设备耦合在一起。最常见的耦合设备是电制冷机和燃气锅炉,以及可能存在的冷热电联供系统。在纯电力视角下,空调就是一个电负荷;但放到综合能源视角下,空调消耗电力产出冷量,这个冷量可以部分替代蓄冷罐的放冷,或者反过来——蓄冷罐在电价高峰放冷,让电制冷机停机,等效于削减了电负荷,这就是“以冷代电”的需求响应。
在Matlab中表达这种耦合关系,需要建立能量母线的概念。我习惯的做法是把楼宇系统分成电母线、冷母线、热母线三条虚拟枢纽,所有设备都挂接在对应母线上:
- 电母线节点:光伏出力、电网购电、电池放电、电制冷机耗电、常规电负荷、空调耗电
- 冷母线节点:电制冷机制冷、蓄冷罐放冷、空调冷负荷需求
- 热母线节点:燃气锅炉供热、蓄热罐放热、生活热水与采暖负荷
耦合关系用能量平衡方程表达。比如电母线平衡方程:
P_grid(t) + P_pv(t) + P_bat_dis(t) = P_load(t) + P_es_driven(t) + P_ac(t) + P_bat_ch(t)这个平衡方程是后续所有优化模型的基础。写程序之前先把这些母线和节点图画清楚,能避免后面写约束时丢项漏项。我在搭框架时习惯按“母线-设备-约束”三层结构来组织代码,每一层单独一个函数或脚本,这样调试时定位问题非常快。
2. 日前-日内两级调度:多时间尺度框架如何搭建
2.1 多时间尺度调度到底在解决什么问题
多时间尺度调度的核心动机是“不确定性”。光伏出力有预测误差,负荷也有随机波动,如果只做一次日前调度,当天实际情况和计划偏差一大,整个优化就失效了。解决办法是仿照电网调度的“多级协调”思想,把调度决策拆成不同时间尺度:
- 日前调度:提前24小时做,时间粒度1小时,决策所有可控设备的启停和出力计划。前提是使用预测数据,目标是全天运行成本最小化。
- 日内滚动调度:每1小时滚动一次,预测未来4小时的负荷和光伏,时间粒度15分钟,修正日前计划与实时状态的偏差。
“多时间尺度”不是简单跑两个优化模型,关键是两级模型之间的衔接。日内模型需要在追踪日前计划与追求实时经济之间找一个平衡——完全追踪日前计划会丧失日内电价和负荷变化带来的优化机会,完全不追踪又会让设备状态频繁波动。我的做法是在日内模型的目标函数里引入“偏差惩罚项”,让决策变量既响应实时变化,又不会偏离日前计划太远。
2.2 日前调度模型的目标函数与约束拆解
日前调度的目标函数我设计为全天总运行成本最小,包含四部分:
min F = F_purchase + F_battery_loss + F_comfort_penalty + F_response_costF_purchase:向电网购电的费用,分时电价下这部分是主要成本;F_battery_loss:电池充放电退化成本,用等效循环成本系数乘以充放电电量估算,避免优化结果让电池频繁充放;F_comfort_penalty:室内温度偏离舒适度区间的惩罚项,温度在设定范围内不惩罚,超出范围线性惩罚;F_response_cost:需求响应补偿费用,当调用柔性负荷削减时按削减量和补偿单价计费。
约束条件按设备类型分组,我把它们分成四类:
- 电平衡约束:任一时刻购电功率加光伏功率加电池放电功率等于各类电负荷之和;
- 设备运行约束:包括电池SOC递推方程、充放电功率上下限、蓄冷罐蓄冷量递推、制冷机功率范围、空调启停逻辑等;
- 建筑热动态约束:室内温度递推方程,描述空调功率如何影响室温变化;
- 需求响应约束:可削减负荷的上限比例,以及削减次数限制(避免频繁调节影响用户体验)。
其中建筑热动态约束最容易写错。等效热参数模型的标准形式是:
T_in(t+1) = T_in(t) * exp(-dt/(R*C)) + (T_out(t) + R * Q_hvac(t)) * (1 - exp(-dt/(R*C)))这个方程是线性的,可以很好地嵌入混合整数规划。但要注意,Q_hvac是空调的制冷功率,不等于空调的电功率,中间还隔着能效比EER。制冷功率除以EER才是电功率,这个转换在目标函数和电平衡约束中要一致。
2.3 日内滚动修正模型的设计
日内滚动调度模型的结构与日前类似,但有三点关键区别:
第一是时间尺度。日前是1小时间隔、24个时段;日内是15分钟间隔、未来4小时共16个时段。滚动优化意味着每15分钟重新求解一次,但只执行第一个时段的决策,然后滑向下一个时刻。
第二是状态初值。每次滚动求解时,电池SOC、蓄冷罐蓄冷量、室内温度都是当前实测或估计值,不是预测值。这就让日内模型能及时纠正日前预测误差带来的偏差。程序实现时,需要把日前调度得到的“最终状态”作为日内模型的“初始状态”。
第三是目标函数的差异。日内模型的目标是“在追踪日前计划的基础上最小化运行成本”。具体做法是加入软约束——设备出力与日前计划之间的偏差量乘以惩罚系数。惩罚系数不宜设得过大,否则日内优化形同虚设;也不宜过小,否则设备出力大幅波动。我的经验是惩罚系数取电价的1.5-2倍比较合适。
2.4 两级模型在Matlab程序中的衔接逻辑
两级模型共用一个设备模型库,区别在于调用时的参数维度不同。程序执行顺序是:
- 读取基础数据和预测数据;
- 运行日前优化,得到24小时的设备出力计划;
- 进入日内循环,设t=1;
- 基于t时刻的实际状态(SOC、室温、蓄冷量)和未来4小时的预测数据,求解日内优化;
- 执行第t时刻的决策,推进到t+1;
- 重复4-5直到全天结束;
- 汇总所有决策数据,计算实际成本和性能指标。
这个流程看似简单,程序里最麻烦的是状态变量的传递和存储。我使用结构体数组来管理:state(t).soc、state(t).temp_in、state(t).storage_cold,每一步优化结束后立即更新结构体,避免在长循环中出现变量覆盖的bug。
3. Matlab程序架构:模块划分与核心代码逻辑
3.1 程序目录结构与文件组织
一个完整的调度程序,文件组织直接影响调试效率。我的目录结构如下:
smart_building_scheduling/ ├── main_schedule.m % 主程序入口 ├── load_data.m % 数据读取与预处理 ├── build_params.m % 基础参数设置 ├── models/ │ ├── model_battery.m % 电池模型约束 │ ├── model_hvac.m % 空调热动态模型 │ ├── model_storage.m % 蓄冷蓄热模型 │ └── model_pv.m % 光伏出力模型 ├── optim/ │ ├── day_ahead.m % 日前调度优化 │ ├── intraday.m % 日内滚动优化 │ └── solver_cfg.m % 求解器配置 ├── utils/ │ ├── plot_results.m % 结果可视化 │ ├── calc_metrics.m % 指标计算 │ └── time_shift.m % 时间索引辅助函数 └── data/ ├── load_profile.xlsx % 负荷曲线数据 ├── pv_profile.xlsx % 光伏出力数据 └── price_profile.xlsx % 分时电价数据这个结构的好处是模型、优化、数据三层完全解耦。换一套数据,不用改模型代码;换一个求解器,只改solver_cfg.m。如果只是验证算法,也可以把全部代码写在单个脚本里跑通后再拆分,但正式交付的程序建议还是分模块,可读性和可维护性完全不是一个级别。
3.2 参数初始化与数据读取细节
参数初始化是看似简单但最容易出问题的环节。我在build_params.m里用结构体统一管理参数:
% 设备参数 params.battery.cap_kWh = 500; % 电池容量 params.battery.pmax_kW = 200; % 最大充放电功率 params.battery.soc_min = 0.1; % SOC下限 params.battery.soc_max = 0.9; % SOC上限 params.battery.eta_ch = 0.95; % 充电效率 params.battery.eta_dis = 0.95; % 放电效率 params.battery.init_soc = 0.5; % 初始SOC % 空调热动态参数 params.hvac.c_air_JpK = 20000; % 房间热容 params.hvac.r_e_KpW = 0.001; % 热阻 params.hvac.eer = 3.5; % 能效比 params.hvac.qp_kW = 600; % 额定制冷功率 % 蓄冷罐参数 params.storage.cap_kWh = 800; % 蓄冷容量 params.storage.pmax_ch = 150; % 最大蓄冷功率 params.storage.pmax_dis = 150; % 最大放冷功率 params.storage.loss_rate = 0.01; % 自损耗率 % 电价参数 params.price.peak = 1.2; % 峰时电价 params.price.flat = 0.7; % 平时电价 params.price.valley = 0.3; % 谷时电价数据读取方面,我建议使用readtable和table2array组合,不要用旧的xlsread函数。数据文件用Excel维护最方便,因为负荷曲线、光伏预测曲线这些数据通常需要人工检查和修改。读入后统一转换为列向量,并检查是否有缺失值:
function data = load_data() data.load = table2array(readtable('data/load_profile.xlsx')); data.pv = table2array(readtable('data/pv_profile.xlsx')); data.price = table2array(readtable('data/price_profile.xlsx')); % 检查数据维度一致性 assert(length(data.load) >= 96, '负荷数据长度不足'); assert(length(data.pv) == length(data.load), '光伏数据与负荷数据长度不匹配'); assert(length(data.price) >= 24, '电价数据长度不足'); % 检查缺失值 if any(isnan(data.load)) || any(isnan(data.pv)) error('数据中存在NaN值'); end end3.3 核心模型:用YALMIP构建优化模型
Matlab里做优化调度,最常用的建模工具是YALMIP,求解器用CPLEX或Gurobi。选择YALMIP而不是直接用求解器自带API的原因很简单:YALMIP的语法接近数学表达式,写起来快,读起来也直观。下面这段代码展示日前调度中电池模型的约束构建:
function constraints = model_battery(x, params, N) % x.bat_ch: 充电功率变量 % x.bat_dis: 放电功率变量 % x.soc: 荷电状态变量 constraints = []; % SOC递推约束 for t = 1:N-1 constraints = [constraints, ... x.soc(t+1) == x.soc(t) + ... (x.bat_ch(t)*params.battery.eta_ch - ... x.bat_dis(t)/params.battery.eta_dis) / params.battery.cap_kWh]; end % 功率上下限约束 for t = 1:N constraints = [constraints, ... 0 <= x.bat_ch(t) <= params.battery.pmax_kW]; constraints = [constraints, ... 0 <= x.bat_dis(t) <= params.battery.pmax_kW]; constraints = [constraints, ... params.battery.soc_min <= x.soc(t) <= params.battery.soc_max]; end % 充放电互斥约束 if params.battery.charging_exclusive for t = 1:N z = binvar(1); constraints = [constraints, ... x.bat_ch(t) <= params.battery.pmax_kW * z]; constraints = [constraints, ... x.bat_dis(t) <= params.battery.pmax_kW * (1-z)]; end end end充放电互斥约束有两种处理办法。一种是引入二进制变量,变成混合整数规划,更精确但求解变慢;另一种是省掉互斥约束,只靠效率损耗来自动避免同时充放电,因为同时充放电会有能量损失,优化目标会自动避免,但求解器偶尔会给出“既不经济也不合理”的微小同时值。我的建议是:对电池这种频繁动作的设备,加互斥约束更稳妥;对蓄冷罐这种时间常数大、本身允许一定同时率的设备,可以不加。这个取舍要根据实际设备特性和求解规模来定。
3.4 求解器选择与求解参数配置
CPLEX和Gurobi都能求解这类混合整数线性规划问题。用哪个主要看本机有没有安装和授权,Matlab自带的intlinprog也能解决小规模问题——楼宇单节点调度这种规模(24-96个时段,几十个变量),intlinprog完全够用,而且不用额外装环境对代码分享更友好。
我的经验是:代码里写一个solver_cfg.m配置函数,方便切换求解器,默认用自带求解器,有CPLEX的机器可以自由切换:
function optimize_settings = solver_cfg() optimize_settings = sdpsettings(); optimize_settings.solver = 'gurobi'; % 或 'cplex' 或 'intlinprog' optimize_settings.verbose = 0; % 不输出求解过程 optimize_settings.savesolveroutput = 1; optimize_settings.gurobi.timeLimit = 120; % 求解时间限制(秒) optimize_settings.gurobi.mipgap = 0.01; % MIP间隙容忍度 endMIP间隙这个参数值得单独说一下。默认追求最优解会把求解时间拉得很长,但楼宇调度问题是24小时或96时段的规划,偏差1%的电费影响很小,却能大幅缩短求解时间。我实际测试中,把MIPGap从0设置到0.01,求解时间从几分钟降到几秒,成本增加不到0.5%,这个换算是划算的。数据量大时这个参数是提速的关键。
3.5 结果可视化与指标计算
完整程序必须包含可视化和评价指标。我在plot_results.m里输出四张图:
- 功率平衡图:电母线各设备出力堆叠面积图,直观展示购电、光伏、电池充放电与各类负荷的平衡关系;
- 温度曲线图:室内温度变化与舒适度上下限的对比,验证舒适度约束没有越界;
- SOC和蓄冷量曲线图:电池和蓄冷罐的能量状态变化,看储能设备是否充分发挥了峰谷套利作用;
- 成本明细对比图:柱状图对比各设备成本和未调度前的基线成本。
指标计算部分至少包含四个量化指标:
- 日运行总成本(元);
- 峰时购电削减率(%)——对比无调度策略的基线;
- 峰谷套利收益(元);
- 室内温度最大偏移量(℃)——评估对舒适度的影响。
用calc_metrics.m函数算出这些指标后,会输出一个结构化摘要,让运行程序的人一眼看出调度策略的效果,而不是面对一堆变量列表发懵。
4. 案例数据准备与算例参数设定
4.1 基础算例参数表
为了让程序可直接运行,我设计了一个典型的办公楼算例。楼宇建筑面积约1万平方米,设定为商业写字楼,主要参数如下:
| 设备/参数 | 数值 | 单位 |
|---|---|---|
| 空调额定制冷功率 | 600 | kW |
| 空调EER | 3.5 | - |
| 电池容量 | 500 | kWh |
| 电池最大功率 | 200 | kW |
| 电池初始SOC | 50 | % |
| 蓄冷罐容量 | 800 | kWh |
| 蓄冷罐最大蓄/放冷功率 | 150 | kW |
| 光伏装机容量 | 200 | kWp |
| 房间热容C | 20000 | J/K |
| 热阻R | 0.001 | K/W |
| 舒适温度范围 | 22-26 | ℃ |
4.2 分时电价与需求响应激励参数
分时电价采用典型的峰平谷三段式结构:
| 时段类型 | 时间范围 | 电价(元/kWh) |
|---|---|---|
| 谷时 | 0:00-8:00 | 0.30 |
| 平时 | 8:00-10:00, 15:00-18:00, 21:00-24:00 | 0.70 |
| 峰时 | 10:00-15:00, 18:00-21:00 | 1.20 |
需求响应激励参数需要考虑两类场景。一类是削峰响应,电网公司在14:00-15:00发出削峰信号,楼宇参与削减负荷可获得0.8元/kWh的补偿;另一类是填谷响应,凌晨2:00-5:00鼓励增加用电,给予0.2元/kWh的补贴。这两个参数直接影响优化模型中需求响应约束的收益计算,也决定了楼宇是否响应、响应多少。
4.3 负荷与光伏预测曲线生成
楼宇负荷曲线要能体现工作日的典型特征:夜间基础负荷低(照明和待机设备,约80-120kW),白天工作时段负荷攀升,空调冷负荷随室外温度上升而增加,午后达到峰值,整体峰谷差约3倍。光伏曲线以夏季晴天为例,中午12:00-13:00达到峰值约180kW,早晚出力接近零。
为了模拟不确定性,数据生成时可以给光伏曲线加5%-10%的随机噪声作为预测误差。这个噪声幅度要适中——太小体现不出日内调度的必要性,太大又会让日前调度几乎失去参考价值。实际项目中,我还会准备多组数据(晴天、多云、阴天各一组),用来测试策略在不同气象场景下的鲁棒性。
5. 仿真结果分析:调度策略的实际效果
5.1 日前调度结果:设备出力计划的合理性
运行日前优化后,首先看功率平衡图里各设备的运行逻辑是否符合预期。正常情况下应该能看到:
- 凌晨谷时段,电池充电、蓄冷罐蓄冷,电网购电功率较高;
- 白天峰时段,电池放电、蓄冷罐放冷、电制冷机降载,电网购电功率压到较低水平;
- 光伏大发时段,多余的光伏给电池充电而不是反送电网,因为上网电价通常低于购电电价;
- 空调功率在工作时段大体同步于冷负荷需求,但不会在峰时段全功率运行,会适当预冷蓄冷。
如果出现凌晨电池放电、白天充电这类“逆逻辑”现象,优先检查电价参数是否设置正确,再检查约束方向是否有误。这类问题在模型刚搭好时非常常见,大多不是求解器算错,而是约束写反了。
5.2 日内滚动修正的真实效果
日内滚动调度的效果体现在面对预测误差时,系统能自动调整。以光伏为例,如果上午实际光伏出力比预测高出30kW,日内优化会自动降低购电功率、把多余的功率给电池充电。如果实际出力比预测低,日内优化会增加购电,必要时调用储能放能。
跟踪成本可以发现:日内优化结果比“只用日前计划”模式的总成本要低约3%-8%。这个数字在不同场景下会变,但结论是稳定的——预测误差越大,滚动调度的收益越高。单独看某个时刻的决策,日内结果可能会与日前计划有偏差,但整体上偏差量控制在合理范围内,这验证了偏差惩罚项的设计是有效的。
5.3 经济性与综合指标对比
以一个典型夏季工作日为基准,我的算例结果:
| 指标 | 无优化基线 | 日前调度 | 日前+日内 |
|---|---|---|---|
| 日购电成本(元) | 12860 | 9860 | 9570 |
| 峰时段购电削减率 | - | 28% | 32% |
| 套利收益(元) | - | 2480 | 2760 |
| 平均温度偏移(℃) | 0 | 0.6 | 0.8 |
| 最大温度偏移(℃) | 0 | 1.8 | 2.1 |
对比数据能清楚看出,日前调度已经能实现大部分经济收益,日内调度在日前基础上进一步挖掘了3%-5%的改善空间。温度偏移量在日内模式下略有增加,但仍控制在舒适度范围内,说明牺牲少量舒适度换取经济性优化的策略是可控的。
6. 完整程序中的易错点与调试经验
6.1 时间索引与维度对齐问题
多时间尺度程序最常见的bug是时间维度不一致。日前是24时段,日内是16时段(4小时×15分钟),数据文件里负荷可能是96点(15分钟间隔)或24点(小时间隔)。写代码时一定要先明确每个变量的时间维度,再开始建模。
实际编码中,我强烈建议把时间离散数定义为常量:
N_day = 24; % 日前调度时段数 N_intra = 16; % 日内滚动时段数 dt_day = 1; % 日前时间间隔(小时) dt_intra = 0.25; % 日内时间间隔(小时)在递推约束中,时间间隔必须乘到能量转换项里,否则会少算一个系数,导致SOC变化量错误。这种错误往往要到绘图查看SOC曲线时才能发现,排查起来很费神。
6.2 空调热动态模型线性化细节
等效热参数模型本身是线性的,因为指数项exp(-dt/(R*C))在固定时间间隔下是常数。但要注意这个常数的数值范围:如果R×C比dt大得多,指数项趋近于1,温度变化非常缓慢;如果R×C比dt小很多,指数项趋近于0,温度变化近乎瞬时。热时间常数的量级是否合理,直接影响调度结果的实际可行性。
写字楼的热时间常数通常在2-8小时范围内。取R=0.001 K/W,C=20000 J/K时,R×C=20秒,这个值对1小时时间尺度的日前调度来说太小——室温几乎会瞬变,优化的“温度惯性缓冲”效果就消失了,这与实际不符。所以程序参数里的C和R需要按建筑规模重新标定。我建议把房间热容C放大到10^7 J/K量级,让热时间常数落在小时级,这样调度结果才有物理意义。这类参数校验靠程序本身发现不了,必须结合工程经验判断。
6.3 求解器收敛问题与MIP Gap的平衡
混合整数规划在变量多了以后,求解时间可能暴涨。楼宇模型中的二进制变量通常来自充放电互斥约束、设备启停变量等。当二进制变量数量超过50个,求解时间从秒级跳到分钟级很常见。
处理收敛问题的顺序是:先检查模型规模是否合理——有没有冗余的二进制变量可以合并;再检查约束是否过紧——比如充放电互斥约束在电价差足够大时本来就不会同时充放电,可以去掉;最后才调整求解器参数,放宽MIPGap。我的习惯是:程序默认MIPGap为1%,用户可以手动改到0.1%甚至0来追求精确解,但要知道对应的等待时间可能是几十分钟。
6.4 结果合理性校验清单
调试完成后,我建议按以下清单逐项验证结果,确保程序交付时数据是可信的:
- 电量平衡校验:全天总购电量+光伏发电量+电池放电量是否等于总负荷+电池充电量+系统损耗,误差应在1%以内;
- 边界条件校验:SOC是否始终在设定范围内,蓄冷量是否在上下限内,充放电功率是否越限;
- 舒适度校验:室内温度是否在允许范围内,是否有异常的大幅温差跳变;
- 逻辑方向校验:峰时段购电是否明显低于谷时段,储能在谷时段充电、峰时段放电是否符合经济逻辑;
- 对比基准校验:优化后的成本是否确实低于基线成本,如果优化结果比不优化还贵,那一定存在模型逻辑错误。
第5项看似废话,实际非常重要。我遇到过空调参数设置错误,导致优化后的系统为了“最优”把空调全天关停,温度降到16℃,虽然电费低但完全不可用。所以指标评估时一定要同时看经济指标和物理指标,不能只盯着成本算。
完整程序我整理了两套数据:一套是夏季晴天的基准数据,用来跑通流程演示效果;另一套是带随机波动的多场景测试数据,用来验证策略的鲁棒性。实际运行时,可以先跑第一套数据确认程序无误,再用第二套数据做对比试验。这套框架里,模型和求解是主体,但前期的设备参数标定和后期的结果校验才是保证程序真正可用的关键,这两部分占据了整个项目大约一半的工作量。
本文还有配套的精品资源,点击获取