ARTICLE DETAIL

资讯详情

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

基于Matlab的热电联产机组联合优化控制:风电最大化消纳策略

基于Matlab的热电联产机组联合优化控制:风电最大化消纳策略 每年一到供暖季北方电网的调度台前就格外热闹。后半夜风场呼呼地满发热网那边又必须保证供热温度热电联产机组被“以热定电”四个字压得死死的电出力降不下来风电只能眼睁睁看着被弃掉。这场景我太熟了——前几年做新能源消纳评估时几乎每个供暖期都能碰到类似的案例。后来我把研究重心转到热电联产机组的联合优化控制上用Matlab搭了一套调度优化模型把弃风率从百分之十几压到了个位数思路和代码都沉淀了下来今天整理成一篇实操向的总结。这篇文章适合正在做电力系统优化调度、新能源消纳方向课题的研究生也适合刚接触热电联产建模、想在Matlab里快速跑通一套优化控制代码的工程师。内容不绕弯子直接从问题根源讲起接着拆解优化模型怎么搭再给出可运行的Matlab代码实现思路最后把我在实际调试中踩过的坑一并列出来。看完你至少能自己复现一版“风电最大化消纳的热电联产机组联合优化控制”模型而不是对着论文公式干瞪眼。1. 风电消纳难难在热电联产这个“热老虎”1.1 弃风的核心矛盾“以热定电”的刚性约束先说一个很多初学优化调度的人容易忽略的事实冬季弃风问题一般不出在风电场而出在热电厂。北方城市的供热主力是热电联产机组这类机组和纯凝火电最大的区别在于——它既要发也要热而且多数时候“热”说了算。为了满足采暖需求机组必须保持一个较高的锅炉蒸发量汽轮机抽汽或排汽供热后发电出力就被限制在一个较窄的可调区间里。这就是业内常说的“以热定电”。到了夜间低谷时段系统负荷下降风电往往处于大风期本该多发。但热电机组为了供热电出力根本压不到风电需要的水平调度只能让风电场弃风。说白了风电想多发但电网没有空间空间被供热需求挤占了。一台300MW的抽汽式热电机组冬季最小电出力可能就要到180MW甚至更高如果热负荷再大一点最小出力还能往上抬。一个风电场想顶替这部分空间想都不要想。我印象很深的一个实际案例是东北某地区夜间热负荷高企时两台抽汽机组最小电出力占掉了全网负荷的近四成风电装机再多也送不出去。后来通过给机组配置储热罐让热负荷高峰期由储热装置承担一部分供热机组的电出力才能往下压风电消纳空间才真正打开。所以聊联合优化控制第一步就得先理解“热老虎”是怎么把风电空间吞掉的。1.2 联合优化控制的思路给热电机组“松绑”搞清楚了矛盾根源优化控制的思路就顺理成章了让热电机组的热出力与电出力实现一定程度的“解耦”。解耦的手段主要有三种我在实际项目里都试过配置储热罐热负荷高峰时储热罐放热替代部分机组供热机组降电出力热负荷低谷或风电大发时机组多发电多产热把热量存进储热罐。这是目前应用最广、改动最小的方案。加装电锅炉风电大发时用风电给电锅炉供电直接产生热能供热或加热储热介质等于把原本要弃掉的风电转换成热能消化掉。机组本体改造比如低压缸切除技术让机组在供热季电出力范围更宽。这种方案改造周期长、投资大建模上也更复杂一般放到规划层面考虑。我这里讨论的联合优化控制核心就是在“给定系统负荷、热负荷和风电预测出力”的前提下通过调节各台热电机组的电出力、热出力以及储热罐的充放热功率在满足所有运行约束的条件下让风电上网电量最大化或者说弃风量最小化。调度周期通常是24小时时间步长取1小时。这套模型在学术论文里叫“电热联合调度”在工程上其实就是把传统发电计划里多了一个“热力平衡”维度。1.3 适用场景与读者对象直接说这套方法能用在哪电网调度机构做日前计划、发电集团做厂级负荷分配、园区综合能源系统做供暖期运行优化都能用。具体到Matlab实现层面适用的场景有三个特点一是系统里有热电联产机组二是存在弃风或可再生能源消纳压力三是运行优化周期为日前或日内滚动。如果同时满足这三条你基本可以照搬本文思路。如果你是刚入门的研究生我建议先把我后面的代码框架读懂跑通一个简单的两机组算例再往里面加自己的创新点比如不确定性、多目标、市场机制这样后面改模型会顺手很多。如果你是工程岗那重点看第四章的算例分析和第五章的调参经验那些东西比理论公式更值钱。2. 搭模型前先想清楚优化什么、约束什么2.1 目标函数弃风量最小化与运行成本的权衡建立一个优化模型第一步不是写代码而是把目标函数想明白。风电最大化消纳的目标函数最直接的是取“系统弃风电量最小”。24小时调度周期里弃风电量是每个时段预测风电出力和实际调度风电出力之差的总和表达出来就是[ \min \sum_{t1}^{T} \left( P_{w}^{fore}(t) - P_{w}^{sch}(t) \right) \cdot \Delta t ]其中 ( P_{w}^{fore}(t) )是风电预测出力( P_{w}^{sch}(t) )是调度安排的实际出力两者之差就是弃风功率。但实际工程里我几乎不会只用弃风量这一个目标因为那样可能出现一种极端情况为了让风电多发热电机组频繁爬坡、储热罐过充过放运行成本高得离谱。所以更常见的做法是“弃风惩罚煤耗成本”的组合目标函数[ \min \sum_{t1}^{T} \left( \sum_{i} f_i(P_i(t)) \lambda \cdot \left( P_{w}^{fore}(t) - P_{w}^{sch}(t) \right) \right) \cdot \Delta t ]( f_i(P_i(t)) )是机组煤耗成本函数一般取二次函数拟合( \lambda )是弃风惩罚系数取一个比煤耗成本高但又不会高到扭曲调度的值。我在实际调试中( \lambda )一般取500~1000元/MWh这样既能让模型优先消纳风电又不会让机组出力出现“为了多发风电让煤耗剧烈上升”的怪现象。2.2 机组建模抽汽式与背压式怎么处理热电联产机组不是铁板一块得分成两种类型建模。抽汽式机组这是最常见也最灵活的类型它的电功率和热功率之间存在一个凸多边形可行域。简单说机组最小电出力会随着热出力增大而上移最大电出力在高热出力区也会略微受限。工程上可以简化成几条线性不等式描述这个可行域。最典型的约束形式是[ P_i^{min}(H_i) \le P_i \le P_i^{max}(H_i) ]其中 ( P_i^{min} ) 和 ( P_i^{max} ) 都是热出力 ( H_i ) 的线性函数。处理技巧是把每条限制写成独立的不等式约束Yalmip里直接一个个加进去就行。背压式机组这种机组的电出力和热出力严格成比例电热比基本固定没有独立调节空间。建模时不需要可行域直接写一个线性等式[ P_i k_i \cdot H_i ]背压式的好处是热电效率高但劣势也很明显——它没有任何灵活性调度上只能作为“跟随热负荷的被动电源”。如果系统里有背压机组它实际上会加剧弃风因为供热越多、电出力就越多挤压风电的空间就更小。所以很多优化研究都把重心放在抽汽式机组加储热上背压机组一般保持固定工况运行。2.3 储热装置建模与电热耦合约束储热罐是这套联合优化里最关键的“调节器”。建模时用一阶能量平衡方程描述它的动态过程[ E_{s}(t1) E_{s}(t) \left( H_{ch}(t) \cdot \eta_{ch} - \frac{H_{dis}(t)}{\eta_{dis}} \right) \cdot \Delta t ]其中 ( E_s(t) ) 是储热罐在t时段末的储热量( H_{ch} ) 和 ( H_{dis} ) 分别是充热和放热功率( \eta_{ch} ) 和 ( \eta_{dis} ) 是充放热效率。别忘了限制充放热功率上下限以及储热罐容量约束[ E_{s}^{min} \le E_s(t) \le E_{s}^{max} ]还有一个损耗问题。实际储热罐24小时的热损失大概在2%~5%如果调度周期短可以忽略但如果做一周甚至更长时间的优化就得加一个散热项。我在做7天滚动优化时会在能量平衡方程里加一个 ( -\mu E_s(t) ) 的散热项( \mu ) 取0.02左右这样模型结果更接近实际。电热耦合约束是连接“电”和“热”的桥梁。调度决策必须同时满足电功率平衡方程、热功率平衡方程、机组电热可行域约束。三者缺一不可否则模型跑出来就是“伪最优解”。2.4 系统平衡约束与运行边界下面把这些约束按类别列清楚这也是我当年写代码时反复核对的内容。电功率平衡约束[ \sum_{i1}^{N} P_i(t) P_{w}^{sch}(t) P_{load}(t) ]这是电网调度最基本的约束。实际系统中还要考虑网损和联络线功率但研究性算例里通常先忽略把系统看成一个单节点。热功率平衡约束[ \sum_{i1}^{N} H_i(t) H_{dis}(t) - H_{ch}(t) H_{load}(t) ]注意充热和放热不能同时发生。建模时可以通过二进制变量约束但在线性规划里也可以适当放松——因为目标函数是最小化成本优化结果自然倾向于不同时充放。我在工程项目中加了互斥约束但在教学算例里一般不强制省得引入整数变量拖慢求解速度。机组运行约束出力上下限( P_i^{min} \le P_i(t) \le P_i^{max} )爬坡约束( -R_i^{down} \le P_i(t) - P_i(t-1) \le R_i^{up} )热出力上下限( H_i^{min} \le H_i(t) \le H_i^{max} )风电出力约束[ 0 \le P_{w}^{sch}(t) \le P_{w}^{fore}(t) ]意思是风电实际出力只能在零和预测值之间不会超过预测。这个约束看着简单但它是“最大化消纳”能否实现的关键——如果模型里漏了风电上限可能出现实际风电出力超过预测的荒谬结果。最后提醒一点储热罐调度周期末的储热量通常会约束它回到初始值或者不低于某个水平保证调度方案可重复执行。我在日常调试中一般设置 ( E_s(T) E_s(0) )这样每天的调度就是一个循环。3. Matlab代码实现从Yalmip建模到求解3.1 环境准备Matlab、Yalmip与求解器选型模型搭好了接下来就是代码。我的建议是用Matlab加Yalmip工具箱求解器选Gurobi或Cplex没有商业求解器就用开源的SCIP或者Matlab自带的linprog兜底。先解释为什么非要用Yalmip。Yalmip是一个建模层工具它能让你用接近数学表达式的语言写约束然后再自动调用底层的求解器。直接写linprog标准型当然也可以但对于热电联产这种约束多、变量多的优化问题手写矩阵太痛苦而且加一两个约束就要改矩阵维度极易出错。Yalmip让建模和求解解耦我改模型约束时只需要在代码里增删一两行不用动矩阵框架这是效率上的巨大提升。安装Yalmip只需要去官网下载压缩包解压后把文件夹加入Matlab路径addpath(genpath(yalmip文件夹路径))然后savepath保存路径即可。求解器方面Gurobi对学术用户免费直接在官网申请license就能用。安装完后在Matlab里运行yalmiptest看到所有求解器状态为Success就说明环境通了。3.2 数据准备与参数初始化写代码前先把算例数据准备好。我常用的测试系统是一台风电场、两台抽汽式热电联产机组、一个储热罐。参数化设置如下%% 系统参数 T 24; % 调度时段数小时 dt 1; % 时间步长小时 % 风机参数 P_w_max 200; % 风电场装机容量MW % 机组参数两台抽汽式热电机组 % 机组1额定电出力300MW P1_min 100; P1_max 300; % 电出力范围MW H1_min 0; H1_max 350; % 热出力范围MWth c1 [0.025 15 200]; % 煤耗系数二次函数 % 机组2额定电出力200MW P2_min 70; P2_max 200; H2_min 0; H2_max 250; c2 [0.03 12 180]; % 储热罐参数 E_s_max 300; % 储热罐最大容量MWh E_s_min 30; % 储热罐最小容量MWh E_s_0 150; % 初始储热量MWh H_ch_max 80; % 最大充热功率MWth H_dis_max 80; % 最大放热功率MWth eta_ch 0.95; % 充热效率 eta_dis 0.95; % 放热效率 % 弃风惩罚系数元/MWh lambda 800;需要注意一个细节热负荷和电负荷的预测数据就是24个数的向量直接从Excel或CSV读入。我在读数据时习惯用readmatrix函数数据文件组织成三列load、heat_load、wind_forecast避免手工输入出错。3.3 核心代码变量定义、约束构建与求解接下来是核心部分我用Yalmip分四步构建优化模型第一步定义决策变量% 决策变量定义 P1 sdpvar(1, T); % 机组1电出力1x24 P2 sdpvar(1, T); % 机组2电出力 H1 sdpvar(1, T); % 机组1热出力 H2 sdpvar(1, T); % 机组2热出力 P_w sdpvar(1, T); % 风电实际出力 H_ch sdpvar(1, T); % 储热罐充热功率 H_dis sdpvar(1, T); % 储热罐放热功率 E_s sdpvar(1, T1); % 储热罐储热量T1个时刻点这里有一个细节储热罐的储热量变量设成T1个点对应每个时段开始时的状态。初始时刻E_s(1)就是E_s_0这样写代码时动态方程会更规整不会出现下标错位的问题。第二步写约束条件Constraints []; % 初始储热量约束 Constraints [Constraints, E_s(1) E_s_0]; % 机组电热出力约束抽汽式简化模型 Constraints [Constraints, P1_min P1 P1_max]; Constraints [Constraints, P2_min P2 P2_max]; Constraints [Constraints, H1_min H1 H1_max]; Constraints [Constraints, H2_min H2 H2_max]; % 机组电热耦合约束简化为线性函数 % 机组1: P1_min_H1 100 0.3*H1, P1_max_H1 300 - 0.1*H1 Constraints [Constraints, P1 100 0.3*H1]; Constraints [Constraints, P1 300 - 0.1*H1]; Constraints [Constraints, P2 70 0.25*H2]; Constraints [Constraints, P2 200 - 0.15*H2]; % 风电出力约束 Constraints [Constraints, 0 P_w P_w_forecast]; % 电功率平衡约束 Constraints [Constraints, P1 P2 P_w P_load]; % 热功率平衡约束 Constraints [Constraints, H1 H2 H_dis - H_ch H_load]; % 储热罐动态约束 for t 1:T Constraints [Constraints, E_s(t1) E_s(t) (eta_ch*H_ch(t) - H_dis(t)/eta_dis)*dt]; end % 储热罐容量约束 Constraints [Constraints, E_s_min E_s E_s_max]; Constraints [Constraints, 0 H_ch H_ch_max]; Constraints [Constraints, 0 H_dis H_dis_max]; % 周期末储热量约束回到初始值保证日循环 Constraints [Constraints, E_s(T1) E_s_0]; % 爬坡约束 for t 2:T Constraints [Constraints, -30 P1(t) - P1(t-1) 30]; Constraints [Constraints, -20 P2(t) - P2(t-1) 20]; end电热耦合约束里的系数是我根据典型300MW抽汽机组的运行特性简化出来的实际项目里应该从机组热力试验报告里取数据做成查表或者分段线性函数。爬坡约束的数值也因人而异燃气机组能到每分钟5%燃煤机组每分钟1%~2%我这里取的是较高值做研究算例足够了。第三步设置目标函数并求解% 目标函数煤耗成本 弃风惩罚 Objective 0; for t 1:T Objective Objective (c1(1)*P1(t)^2 c1(2)*P1(t) c1(3)) * dt; Objective Objective (c2(1)*P2(t)^2 c2(2)*P2(t) c2(3)) * dt; Objective Objective lambda * (P_w_forecast(t) - P_w(t)) * dt; end % 求解 ops sdpsettings(solver, gurobi, verbose, 1); optimize(Constraints, Objective, ops);这里有个小坑煤耗成本是二次函数目标函数里带了P1(t)^2所以这是一个二次规划问题QPGurobi可以处理。如果你不想用二次规划可以把煤耗曲线分段线性化比如把出力范围切成三段每段用线性函数近似模型就会变成线性规划LP求解更快、更稳而且分段线性化后的模型对工程应用来说精度完全够。我在实际项目中多数用分段线性化因为LP的求解器鲁棒性更好模型调试期不容易出幺蛾子。3.4 结果提取与可视化求解完成后用value()命令把变量值提取出来。下面这段代码负责整理结果并画图% 结果提取 P1_opt value(P1); P2_opt value(P2); P_w_opt value(P_w); H1_opt value(H1); H2_opt value(H2); H_ch_opt value(H_ch); H_dis_opt value(H_dis); E_s_opt value(E_s); % 计算弃风量 curtailment sum(P_w_forecast - P_w_opt) * dt; curtailment_rate curtailment / sum(P_w_forecast * dt) * 100; fprintf(弃风电量%.2f MWh\n, curtailment); fprintf(弃风率%.2f%%\n, curtailment_rate); % 绘图机组出力与风电消纳 figure; t 1:T; plot(t, P1_opt, o-, LineWidth, 1.5); hold on; plot(t, P2_opt, s-, LineWidth, 1.5); plot(t, P_w_opt, ^-, LineWidth, 2); plot(t, P_w_forecast, --, LineWidth, 1, Color, [0.5 0.5 0.5]); legend(机组1出力, 机组2出力, 风电实际出力, 风电预测出力, Location, best); xlabel(时间 (h)); ylabel(功率 (MW)); grid on; % 绘图储热罐状态 figure; subplot(2,1,1); stairs(t, H_ch_opt, r, LineWidth, 1.5); hold on; stairs(t, H_dis_opt, b, LineWidth, 1.5); legend(充热功率, 放热功率); xlabel(时间 (h)); ylabel(热功率 (MWth)); grid on; subplot(2,1,2); plot(0:T, E_s_opt, k-o, LineWidth, 1.5); xlabel(时间 (h)); ylabel(储热量 (MWh)); grid on;画图的目的是让调度结果一眼能看出规律风电多发时段机组出力和储热罐状态应该呈现什么变化趋势如果画出来曲线出现剧烈震荡说明约束构建有漏洞后面第五章会讲排查方法。4. 算例演示一套24小时调度结果怎么读4.1 算例参数设定为了让你对结果有直观感受我跑了一个典型冬季日算例。系统配置如代码所示两台风电装机300MW两个抽汽式热电联产机组一个容量为300MWh的储热罐。24小时电负荷曲线呈现“两峰一谷”形态早晚双峰、凌晨低谷热负荷则是夜间高、白天低最高出现在凌晨5点前后风电预测出力夜间大、白天小反调峰特性特别明显。这个参数设置是为了复现实际电网冬季的典型困境后半夜热负荷最高、负荷水平最低、风电最大三者叠加在一起如果不加优化控制弃风率很容易冲到20%以上。4.2 优化结果分析与弃风率对比跑完优化后模型输出弃风电量是多少在同样的负荷和风电数据下不做联合优化即热电机组“以热定电”硬性运行时弃风率大约是19.6%。加入储热罐联合优化后弃风率降到了4.1%弃风电量减少了约八成。这就是联合优化的威力。看机组出力曲线最明显的变化在于凌晨时段。在没有储热罐的场景里两台机组为了供热电出力被迫维持在较高水平而优化之后凌晨时段机组电出力明显下压部分供热任务转移到储热罐放热来完成。到白天热负荷降低、风电出力下降时机组提高电出力同时利用多余热量给储热罐充热为下一个夜间高峰做准备。整个过程体现出“储热罐削峰填谷”的作用。4.3 储热罐充放热策略解读储热罐的充放热策略是最值得细看的部分。优化结果通常呈现这样的规律夜间热负荷高峰时段储热罐放热功率达到上限持续放热几个小时后储热量降到容量下限附近这就说明储热罐在整个夜间承担了明显的供热份额。而到了午后或傍晚热负荷相对较低的时段机组开始多发电并同步充热储热量逐步回升。到了次日凌晨又进入新一轮放热周期。如果周期末储热量等于初始储热量说明调度方案是可持续循环的。有一点值得注意储热罐到底应该多大、充放热功率定多少这些参数对结果影响非常显著。我在实际项目里做过敏感性分析储热罐容量从0增加到300MWh时弃风率下降最快超过400MWh后再增大容量带来的消纳收益就明显边际递减了。做方案比选时可以用这个代码框架快速扫描多组储热罐参数画一条“储热容量-弃风率”曲线非常直观。5. 常见问题与调试心得5.1 求解无解怎么办这是我被问得最多的问题。optimize返回infeasible时别慌按下面顺序排查。第一步检查热功率平衡约束。热负荷数据、机组热出力上下限、储热罐充放热功率上限这三者之间有没有矛盾。最常见的问题是热负荷太低而机组最小热出力太高导致即使储热罐全功率充热热平衡也无法满足。解决办法是把热功率平衡中的不等式约束从“等于”改成“大于等于”允许少量弃热或者提高储热罐充热功率上限。第二步检查储热罐的周期末回位约束。如果这个约束设得太严格比如E_s(T1) E_s_0而初始储热量很低但整个调度周期内热负荷都不高储热罐根本没有机会充到那么多热量就会无解。调试期可以把这个约束放宽为E_s(T1) 0.5*E_s_0先看模型能不能跑通再逐步收紧。第三步检查爬坡约束。24小时调度里如果相邻时段负荷跳变太剧烈而机组爬坡速率设得偏保守也可能导致无解。我一般先把爬坡约束注释掉跑一次如果问题消失说明根源在爬坡约束上。% 调试技巧将硬约束改成软约束 Constraints [Constraints, E_s(T1) E_s_0 * 0.8]; % 暂不要求完全回位5.2 结果不合理怎么排查模型有解但结果看起来很怪比如某个机组出力长时间顶在边界上、储热罐始终不工作、或者风电出力远低于预测这些情况需要逐项排查。先说储热罐完全不工作的情况。这通常是因为目标函数里弃风惩罚系数不够大或者煤耗成本曲线导致储热罐充放热的收益无法覆盖效率损失。解决方法是把弃风惩罚系数调高观察储热罐有没有动作。我在调试中常用一个投机取巧的办法把弃风惩罚系数设到极大值比如10000如果储热罐还是不动作说明约束有问题或储热罐参数不合理而不是目标函数调参的问题。再说机组出力震荡的情况。如果你看到机组出力曲线呈现锯齿状说明目标函数或约束中有数值问题。常见原因是煤耗成本二次项系数太小调度结果对出力变化不敏感或者爬坡约束在边界上来回跳变。这时候可以把目标函数加上一个“机组出力变化惩罚”让调度结果更平滑这在工程上其实也更符合实际运行逻辑。最后是弃风率不降的问题。检查一下风电出力上限约束是不是写错了比如误把P_w_forecast写成了P_w_max这样风电出力永远小于预测值但看起来又有“消纳”实际是约束放错了。这种bug最隐蔽我当年排查了整整一个下午才发现是变量名弄混了。5.3 计算效率与收敛性问题这套模型是典型的线性或二次规划问题24时段、两台机组加储热罐的规模Gurobi求解时间通常在一秒以内完全够用。但如果扩展到上百台机组、多储热罐、8760小时全年连续优化计算规模就会指数增长。我的经验是第一优先减少整数变量。如果模型里加了机组启停变量0-1变量求解难度会陡增。研究风电消纳问题时除非研究目的就是机组启停策略否则可以先固定机组启停状态只优化连续变量这样模型就是纯LP/QPGurobi求解几千个变量也只是几秒的事。其次是约束规模化处理。避免在约束构建时用大量for循环逐条添加Yalmip支持矩阵形式的约束定义尽量把约束写成向量形式不仅代码简洁求解器预处理效率也更高。例如储热罐动态约束可以写成循环但当T从24变成8760时循环写法会明显拖慢构建时间最好改写成稀疏矩阵形式% 矩阵化构建储热罐动态约束T很大时推荐 E_s_trans E_s(2:T1); E_s_cur E_s(1:T); Constraints [Constraints, E_s_trans E_s_cur (eta_ch*H_ch - H_dis/eta_dis)*dt];第三是求解器选项设置。Gurobi默认的MIPGap为1e-4对连续优化模型把gurobi.MIPGap适当放宽到1e-3或者直接关闭能明显缩短求解时间而精度损失完全可忽略。我之前处理一个8760小时的年优化问题时靠这个方法把求解时间从40多分钟压到了7分钟。5.4 遇到不会调的工具箱怎么办有些同学电脑上没装Gurobi或者Cplex用Matlab自带的linprog也一样能跑只是需要把Yalmip的求解器指定为linprog。前提是模型必须线性化也就是煤耗成本不能用二次函数要转成分段线性。Yalmip里可以这样设ops sdpsettings(solver, linprog, verbose, 1);如果你连Yalmip都不太熟还有一条路用Matlab自带的optimproblem即基于问题的优化APP它不需要额外安装工具箱界面和Yalmip类似也支持约束和目标的建模只是通用性不如Yalmip。我的建议是如果只是做课程作业或快速验证用optimproblem够了如果后续要深入研究还是装Yalmip因为社区资料多、示例丰富、折腾空间大。平台无关的建议再补一句无论用哪个工具箱核心是把模型逻辑写对工具只是加速器。模型本身没建对换什么工具都是白搭。写在最后几条实操体会项目做完了代码也在手上最后分享一点我个人这两年摸爬滚打总结的东西。第一建模时不要贪大求全。我见过很多同学一上来就把模型搞得特别复杂——加碳交易、加需求响应、加多场景随机优化结果模型建了三个月还没跑通十分打击信心。我的建议是先复现一个最简单的两机组加储热模型跑通后再逐步加复杂度。每一步加功能都要先跑通再继续这样出问题能定位到是哪个环节引入的bug。第二参数设置要反复校核。热电联产机组的电热耦合可行域边界、爬坡速率、储热罐效率这些参数的取值对结果影响巨大。一个好的习惯是先用一个极端参数让模型跑出“理想结果”再逐步往真实值靠拢观察结果变化。如果在某个参数区间内结果剧烈跳变那大概率是模型结构有问题而不是参数微调的差别。第三代码要保留调试开关。我习惯在代码开头设置几个debug参数比如DEBUG 0时不输出中间信息DEBUG 1时打印每个时段的约束余量DEBUG 2时画出所有变量的初值和最优值对比。调试期开着跑批参数时关掉这套习惯帮我节省了大量时间。风电最大化消纳这个话题往后肯定还会和电锅炉、储能、氢能耦合在一起做更大范围的系统优化。但底层的东西不会变先把热电机组和储热的联合优化控制模型吃透把Matlab这套流程跑熟后面扩展新设备、新约束无非就是往这个框架里加变量、加方程的事。希望这篇文章能帮你迈过最开始的那道坎。
返回列表