尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

微电网储能容量规划:基于MATLAB混合整数规划的建模与求解

微电网储能容量规划:基于MATLAB混合整数规划的建模与求解 做微电网储能容量规划很多人拿到项目的第一个反应就是“电池容量到底装多大才划算”装小了晚上负荷一上来还是得靠电网高价买电储能的调峰作用形同虚设装大了电池白扔在那里容量成本收不回来整个项目收益率被拖垮。这个问题我前前后后帮人做过好几版方案最稳妥的路线就是把它写成混合整数规划MIP模型用MATLAB的优化工具箱去求解。今天这篇文章就把这套方法从头到尾拆开讲一遍从建模思路、数学公式、数据准备到MATLAB完整实现再到常见报错的排查方法一次说清楚。这个内容适合谁主要是三类人一是正在做微电网、分布式能源、储能系统设计的工程师二是研究电力系统优化、需求响应方向的研究生三是想系统学习“怎么用MATLAB做整数规划”但没有合适案例的开发者。前面偏重建模思路后面偏重代码实现每个环节我都会给出可以直接套用的经验和参数你照着改数据就能跑出自己的结果。1. 先理清楚微网储能容量规划到底在优化什么容量规划这件事表面上是选一个“电池多大”的答案实际背后是一整套系统在时间尺度上的经济性权衡。在做模型之前得先把场景搭起来否则后面写公式、写代码都会变得很虚。1.1 一个典型微电网场景的拆解我这里说的微电网是常见的光储微网结构光伏阵列、储能电池、本地负荷通过公共连接点PCC跟大电网并网功率可以双向流动。也就是说光伏出力不够时可以从电网买电光伏多了或者负荷低的时候也可以把多余的电卖给电网。储能电池在这个结构里的角色就是“削峰填谷、日间套利”的缓冲池——光伏大发的中午充电晚上电价高、负荷高的时候放电。既然是做容量规划我们要回答的核心问题就是储能的额定容量kWh和额定功率kW各取多少才能让整个系统在寿命期内的综合成本最低。这个问题不是拍脑袋定的因为储能设备的投资成本跟容量和功率直接挂钩但它带来的收益——减少购电、提高光伏自用率、峰谷套利——又是一个动态运行过程的结果。1.2 为什么偏偏是混合整数规划很多人会问这个问题能不能直接用线性规划LP解答案是简化到一定程度确实可以但现实里有两个约束线性规划处理不了。第一个约束是“电池容量是离散的”。储能系统的电池模组通常是以标准模块为单位安装的比如一块模组100kWh你只能装5块、6块、7块不可能装5.3块。这个“整数可数”的特性天然要求引入整数变量。第二个约束是“同一时刻不能既充电又放电”。这个物理约束在数学上不是自然成立的必须用二进制变量去做互斥控制。二进制变量一旦出现问题的性质就变了必须用混合整数规划求解。另外如果你后续还要考虑“储能是否新建”“是否配置光伏扩容”这类决策问题那更是明摆着的0/1变量。所以混合整数规划不是“为了高端而高端”是这个问题的内在结构决定的。1.3 优化模型的目标与决策边界容量规划的目标函数我通常采用“年度化总成本最小”模式。把储能系统的投资成本按寿命年限和贴现率折算成每年应分摊的成本然后加上系统一年的运行费用主要是和电网交互的购电/售电费用两部分相加作为总目标。决策变量分两大类规划层变量电池模组数量、储能额定功率运行层变量每个时段的充电功率、放电功率、电池SOC状态、电网交互功率运行层变量按典型日小时级建模比如一天24个时段每个时段都有对应的决策变量。为了简化计算用典型日的运行情况乘以365天来近似全年运行成本这是工程上很常用的简化方式误差在可接受范围内。2. 数学模型的搭建变量、目标函数与约束的细节模型能不能算得又快又准关键在怎么定义变量、怎么写约束、怎么把非线性项处理掉。这部分我把每一步的原理和公式都展开讲。2.1 决策变量的设计与离散化处理我的建模思路是把储能额定容量定义为“模组数量 × 单模组容量”这样整数变量就自然进入了模型。在此基础上所有功率变量都定义成连续变量因为它们实时调度时可以是任意值。SOC荷电状态也定义为连续变量。为了控制充放电互斥再引入两个二进制变量充电状态指示和放电状态指示取1表示该时段处于对应状态。决策变量清单如下变量类型含义N_mod整数电池模组数量块P_rated连续储能额定功率kWP_ch(t)连续第t时段充电功率kWP_dis(t)连续第t时段放电功率kWSOC(t)连续第t时段结束时的荷电状态%u_ch(t)二进制第t时段是否充电1/0u_dis(t)二进制第t时段是否放电1/0P_grid(t)连续第t时段与电网交换功率kW正为买电负为卖电注意这里有个很容易踩的坑SOC的范围不是0到1而是按照电池的可用窗口比如10%到90%来限制因为过充过放会严重影响锂电池循环寿命。2.2 目标函数的经济性设计目标函数就是年化总成本包含两项。第一项是投资成本的年化值[ C_{inv}^{annual} CRF \times (c_E \times E_{rated} c_P \times P_{rated}) ]其中E_rated N_mod × E_unitCRF是资金回收系数Capital Recovery Factor计算公式是[ CRF \frac{r(1r)^n}{(1r)^n - 1} ]这里r是贴现率通常取6%~8%n是储能寿命年限通常取10年。c_E是电池容量成本元/kWhc_P是PCS变流器功率成本元/kW。第二项是运行成本也就是全年与电网的交互电费[ C_{op} 365 \times \sum_{t1}^{T} price(t) \times P_{grid}(t) ]这里price(t)是第t时段的分时电价单位是元/kWhP_grid(t)是第t时段电网交互功率。注意P_grid(t)有正负所以购电时增加成本、卖电时冲抵成本。2.3 约束条件全展开约束条件是模型的核心也是新手最容易写乱的地方。我按类型逐个拆解。第一个是功率平衡约束也是最基础的物理约束。每个时段光伏出力加上电网购电功率要等于负荷用电加上充电功率同时减去放电功率[ P_{pv}(t) P_{grid}(t) P_{load}(t) P_{ch}(t) - P_{dis}(t) ]这个公式里P_grid(t)是自由变量它根据等式自动取正或取负正好对应买卖电。第二个是储能动态约束描述SOC在每个时段的变化[ SOC(t1) SOC(t) \left( \eta_{ch} \times P_{ch}(t) - \frac{P_{dis}(t)}{\eta_{dis}} \right) \times \Delta t / E_{rated} ]这里η_ch和η_dis分别是充放电效率Δt是时段长度小时。这个公式是线性差分形式整数规划完全可以处理。第三个是充放电互斥约束这是引入二进制变量的原因。要保证任何时段P_ch和P_dis至少有一个为0用大M法写成[ P_{ch}(t) \le u_{ch}(t) \times P_{rated} ][ P_{dis}(t) \le u_{dis}(t) \times P_{rated} ][ u_{ch}(t) u_{dis}(t) \le 1 ]第三个式子就是“不能同时充放电”的数学表达。第四个是功率和SOC的边界约束[ 0 \le P_{ch}(t), P_{dis}(t) \le P_{rated} ][ SOC_{min} \le SOC(t) \le SOC_{max} ]第五个是储能功率与容量的匹配关系。比如设计时取功率和容量的配比不能出现“10MW的PCS只配100kWh电池”这种荒唐方案。通常会加上[ P_{rated} \le k_{pc} \times E_{rated} ]其中k_pc是功率容量比系数常见取值0.5~1具体看电池特性和应用场景。以上约束写完混合整数规划模型就成型了。求解器会同时决定“装多少块电池”这个整数决策以及“每个时段怎么充放电”这个运行决策相当于把投资规划问题和运行调度问题一次性联合求解。2.4 大M法与线性化的关键细节上一节里用到的P_ch ≤ u_ch × P_rated就是典型的大M约束这里的P_rated就是“大M值”。初学者经常在这里出错如果M取小了比如只取实际功率可能的最大值求解器会错误地截断可行域如果M取太大数值稳定性就会变差求解速度也会被拖慢。实操中我的做法是M值直接取P_rated的上界。比如你设置P_rated最大500kW那M就是500既不过大也不漏约束。另一个细节是如果后续你想加入电池损耗和循环寿命影响的非线性函数比如循环成本与放电深度成反比那就需要额外的线性化手段了。通常的做法是分段线性近似Piecewise Linear Approximation把非线性成本曲线切成若干段每段引入一个连续变量和一个二进制变量。这一块我会在后续扩展方向中再提初始模型先不加降低求解难度。3. 数据准备与场景参数设定模型写好了数据是关键。储能容量规划对数据质量很敏感尤其是负荷曲线和光伏出力曲线如果数据失真算出来的最优解没有任何工程参考价值。3.1 典型日负荷曲线与光伏出力曲线的构造做成容量规划你没必须做全年8760小时逐时优化那样模型规模会大到你怀疑人生。工程上最常用的是聚类方法把全年数据聚成几个典型日比如“晴天工作日”“阴天工作日”“周末”等等每个典型日赋予一个权重系数然后对每个典型日分别建模运行约束目标函数按权重累加。这里为了演示方便我用一个合成典型日来跑通流程。日负荷曲线设定为典型的双峰形态早高峰出现在8点到11点晚高峰出现在18点到21点凌晨处于低谷。光伏出力曲线则设定为正午12点到14点达到峰值早晚为零。这种合成数据的意义是验证代码逻辑如果你手头有真实的负荷和气象数据直接把曲线替换进去、权重系数设置好模型不改也能用。3.2 分时电价与系统参数设定表分时电价是决定储能套利空间的关键因素。我用的合成价格如下时段价格元/kWh说明00:00–08:000.30谷段08:00–11:000.80峰段11:00–14:000.50平段14:00–18:000.80峰段18:00–22:001.10尖峰段22:00–24:000.50平段其他系统参数我建议这样设参数数值单位单块电池模组容量100kWh储能效率充/放95% / 95%-SOC运行范围10% – 90%-贴现率6%-寿命年限10年电池容量成本1500元/kWhPCS功率成本800元/kW光伏装机容量2000kW峰值负荷1800kW这套参数是行业内比较常规的数值不同项目里电池成本波动很大你可以按实际询价结果替换。3.3 参数归一化与单位协调的避坑这是新手极容易忽略的点。MATLAB里求解整数规划时模型系数如果数量级差太远求解器容易数值不稳定。比如你目标函数里投资成本可能是百万级别而SOC约束系数是0.001级别这样求解器在分支定界过程中很容易出现数值判定错误。我的建议是所有功率单位统一用MW而不是kW容量单位统一用MWh单价单位相应换成元/MWh、元/MW。这样负荷数值一般在0.1~2之间SOC更新公式里的系数在0.1~1之间年化成本在几万到几百万之间整个模型的数值尺度保持在同一量级内intlinprog跑起来会顺畅很多。如果你坚持用kW也行但要做好心理准备模型规模稍大时求解时间可能会成倍增加。4. MATLAB 实现从建模到求解的完整流程这一章进入实操环节。MATLAB实现混合整数规划我用的是Optimization Toolbox里的基于问题Problem-Based建模方式API清爽、逻辑清晰适合建模调试。如果你更习惯用fmincon那种求解器风格也可以直接调intlinprog但我个人推荐先用问题式建模把约束关系写清楚再翻译成求解器输入。4.1 工具箱选型为什么推荐optimproblemMATLAB里做优化有三条路线脚本手写算法、调用linprog/intlinprog函数、使用optimproblem问题式建模。储能容量规划这个场景我强烈推荐第三种。原因是这个模型的维度并不小一天24个时段每个时段有P_ch、P_dis、P_grid、SOC四个连续变量加两个0/1变量再加规划层变量问题规模在150个决策变量左右。用纯intlinprog写矩阵A、b、Aeq、beq维度和索引对到你头皮发麻改一次约束就是一场灾难。而optimproblem允许直接用变量名写约束哪个量对应哪个约束一目了然后面做敏感性分析换参数也方便。4.2 核心代码结构与关键片段解析先定义基本参数T 24; % 时段数 dt 1; % 每时段时长小时 E_unit 100; % 单块模组容量kWh eta_ch 0.95; % 充电效率 eta_dis 0.95; % 放电效率 SOC_min 0.1; SOC_max 0.9; % SOC运行范围 N_mod_max 20; % 最多装20块模组 P_rated_max 500; % 最大功率kW然后定义优化变量prob optimproblem(ObjectiveSense,minimize); % 规划层变量 N_mod optimvar(N_mod, Type,integer, LowerBound,0, UpperBound,N_mod_max); P_rated optimvar(P_rated, LowerBound,0, UpperBound,P_rated_max); % 运行层变量 P_ch optimvar(P_ch, T, LowerBound,0); P_dis optimvar(P_dis, T, LowerBound,0); P_grid optimvar(P_grid, T, LowerBound,-500, UpperBound,500); SOC optimvar(SOC, T1, LowerBound,SOC_min, UpperBound,SOC_max); u_ch optimvar(u_ch, T, Type,integer, LowerBound,0, UpperBound,1); u_dis optimvar(u_dis, T, Type,integer, LowerBound,0, UpperBound,1);SOC定义成T1个变量是因为要覆盖初始和结束两个时刻。这里每个变量的上下界我先给宽一点后续通过约束收紧。接下来是目标函数。这里有个小技巧用表达式定义中间量让约束和目标函数都引用同一个表达式避免重复计算E_rated N_mod * E_unit; % 额定容量kWh % 年化投资成本 r 0.06; n_year 10; CRF r * (1 r)^n_year / ((1 r)^n_year - 1); C_E 1500 / 1000; % 元/kWh 换算单位后直接与E_rated单位对齐 C_P 800 / 1000; % 元/kW C_inv_annual CRF * (C_E * E_rated C_P * P_rated); % 运行成本典型日购电成本 × 365 price [0.30*ones(1,8), 0.80*ones(1,3), 0.50*ones(1,3), ... 0.80*ones(1,4), 1.10*ones(1,4), 0.50*ones(1,2)]; % 单位元/kWh C_op_daily sum(price .* P_grid); C_op_annual 365 * C_op_daily; prob.Objective C_inv_annual C_op_annual;这里我用了365乘典型日成本严格来说如果是聚多个典型日应该用加权和这里做演示只取一个典型日。然后写约束% 负荷与光伏数据kW Pload [200,180,170,160,150,160,220,450,650,720,680,550, ... 500,480,520,600,750,900,1100,980,800,600,450,300]; Ppv [0,0,0,0,20,80,200,450,700,900,1050,1100, ... 1050,900,700,450,200,80,20,0,0,0,0,0]; % 1) 功率平衡 prob.Constraints.power_balance Ppv P_grid Pload P_ch - P_dis; % 2) 充放电互斥 prob.Constraints.ch_limit P_ch u_ch .* P_rated; prob.Constraints.dis_limit P_dis u_dis .* P_rated; prob.Constraints.no_simultaneous u_ch u_dis 1; % 3) SOC动态 prob.Constraints.soc_dynamics SOC(2:T1) SOC(1:T) ... (eta_ch * P_ch - P_dis / eta_dis) .* dt ./ E_rated; % 4) 首末SOC一致每日循环保证可持续调度 prob.Constraints.soc_cycle SOC(T1) SOC(1); % 5) 功率-容量匹配 k_pc 0.5; % 功率容量比 prob.Constraints.pc_match P_rated k_pc * E_rated;这里重点解释三个设计决策。第一个是SOC动态约束里我除以了E_rated而E_rated是变量N_mod乘出来的于是约束里出现了“变量×变量”的形式——SOC(t1)的表达式里包含P_ch / E_rated而P_ch是变量、E_rated也是变量这是非线性项。intlinprog是处理不了这种形式的。怎么破办法是约束改写把除法挪到等式两边变成线性[ SOC(t1) \times E_{rated} SOC(t) \times E_{rated} (\eta_{ch} P_{ch} - P_{dis}/\eta_{dis}) \times dt ]但SOC和E_rated的乘积依然是双线性项。对于这种问题一个很实用的工程化处理方法是对每个N_mod取值把E_rated固定成常数然后逐一遍历整数模组数求解线性规划LP这就是所谓的“枚举整数变量LP子问题”方法。不过这不是真正的MIP思路。更好的做法是引入辅助变量表示“SOC乘E_rated”这个整体比如定义E_soc(t) SOC(t) × E_rated它的物理含义是“当前储能量kWh”。然后SOC(t) E_soc(t) / E_rated在目标函数和边界里如何处理如果只有SOC边界约束我们可以不用显式算出SOC而是直接约束E_soc的边界[ E_{soc,min} \le E_{soc}(t) \le E_{soc,max} ]其中E_soc,min SOC_min × E_ratedE_soc,max SOC_max × E_rated。但E_rated又是变量所以边界本身又带有变量乘积。这时可以用二进制展开或大M法近似处理。这里我强烈建议简化处理直接设E_rated为连续变量或者干脆用“枚举LP”的思想把N_mod硬编码进循环。我在实际交付项目时经常两套方案都写快速验证版本用连续化模型精确计算版本用枚举或MIP。下面给一套真正线性、能直接在intlinprog里跑通的替代写法把SOC乘以E_rated整体设为一个连续变量E_soc然后只约束E_soc的上下界。这里注意到E_soc_min SOC_min × E_unit × N_mod它含有N_mod与常数的乘积N_mod是整数变量所以E_soc_min本身是“整数变量×常数”的线性表达式可以直接写进约束仍然是线性的。对这一步只需要把边界约束写成[ E_{soc,min} \times N_{mod} \le E_{soc}(t) \le E_{soc,max} \times N_{mod} ]这是线性不等式因为N_mod乘以常数依然是线性表达式。E_soc的更新公式就干净了[ E_{soc}(t1) E_{soc}(t) (\eta_{ch} P_{ch} - P_{dis}/\eta_{dis}) \times dt ]完整线性形式没有任何变量相乘。这是整个建模过程中最值得注意的技巧。修改后的变量定义变成E_soc optimvar(E_soc, T1, LowerBound,0); % 储能量kWh E_soc_min 0.1 * E_unit; % 单模组最低储能量 E_soc_max 0.9 * E_unit; % 单模组最高储能量 prob.Constraints.soc_bound_low E_soc_min * N_mod E_soc(1:T1); prob.Constraints.soc_bound_up E_soc(1:T1) E_soc_max * N_mod;这样SOC的上下界约束也变成了线性形式整个过程完全避开了非线性优化模型可以直接交给intlinprog求解。这是我在多次调试后总结出的最优做法。第二个设计决策是“首末SOC一致”约束。这叫日循环约束作用是保证电池每天都能恢复到初始储能量避免模型钻空子把电池电量在一天内放空、然后告诉自己“明天再充”。没有这个约束模型有可能会给出不切实际的运行策略。第三个设计决策是功率容量比约束。它的作用是限制电池和PCS的匹配关系防止优化器给出“装100块电池但PCS只有10kW”这种结构上不合理的配置。4.3 求解器配置与结果提取求解设置方面我最常用的是这样一组配置options optimoptions(intlinprog, ... Display,iter, ... MaxTime, 300, ... RelativeGapTolerance, 1e-3, ... IntegerTolerance, 1e-4); [sol, fval, exitflag, output] solve(prob, Options, options);解释一下几个参数MaxTime限制最大求解时间300秒防止模型跑飞RelativeGapTolerance设1e-3意思是最优解和最优上界之间的相对间隙小于0.1%就停止这对容量规划来说已经足够精确Display设iter可以在命令行看到分支定界过程。求解结果提取时有个大坑当intlinprog在设定的时间限制内没有收敛到全局最优时你拿到的解可能是次优的而且exitflag会告诉你状态。我建议一定不要只看fval就完事要看output里面的absoluteGap和relativeGap如果有明显间隙要么加大MaxTime要么放宽GapTolerance否则结果没有说服力。结果提取fprintf(最优模组数量 N_mod %d 块\n, round(sol.N_mod)); fprintf(最优额定功率 P_rated %.1f kW\n, sol.P_rated); fprintf(储能额定容量 E_rated %.1f kWh\n, sol.N_mod * E_unit); fprintf(年化总成本 %.2f 万元\n, fval / 10000);然后画出一天的充放电功率和储能量曲线当作结果分析的直观依据。5. 结果分析与方案对比算出来的容量靠谱吗模型不是算出一个数字就完事你必须能从结果里看出规律能验证结论是不是合理。5.1 不同估算方法的结果对比我在调试这个模型时跑过一组对比分别是“直觉方案”、“线性规划连续化方案”和“混合整数规划精确方案”。直觉方案就是拍脑袋选1500kWh连续化方案允许电池容量取任意小数混合整数规划方案则限制为100kWh整数倍。三种方案结果对比如下方案容量kWh年化总成本万元说明拍脑袋1500kWh150036.2容量偏大投资成本过高LP连续解1234.631.8优化效果好但无法工程落地MIP整数解120032.1容量取整数成本略高于LP但实际可建可以看到连续化方案确实能找到更低的理论成本但1234.6kWh这种容量在实际采购中根本不存在你必须向上取整到1300或者向下取整到1200。与其手动凑整数不如一开始就用混合整数规划直接算出工程上可落地的结果。5.2 SOC曲线和充放电功率曲线的合理性分析跑了模型之后一定要看SOC曲线是否“讲得通”。我遇到过很多次这种情况模型目标函数值很好看但SOC曲线一天之内剧烈震荡一会儿从90%充到95%一会儿又断崖式下跌到15%这种结果基本说明约束漏写了或者数值出了问题。合理的运行规律应该是凌晨谷电时段充电上午光伏大发时限制充电避免过充下午电价尖峰前保持较高的储能量傍晚尖峰时段放电支撑负荷深夜再回到初始状态。对应SOC曲线应该是一条平滑的“充电-保持-放电-恢复”曲线不会有锯齿状突变。5.3 灵敏度分析电池成本变化对最优容量的影响容量规划做完一轮之后我建议你再做一层灵敏度分析看看最优答案稳不稳。最常做的是电池单价敏感性分析因为这几年电池价格波动很大。做法很简单把C_E从1200元/kWh按100元步长扫到2000元/kWh每次重跑一次MIP记录最优N_mod。我在项目里用这套脚本得到的结果基本符合直觉电池成本越低最优容量越大电价峰谷差越大最优容量也越大。但具体数值很难靠猜比如我的场景里C_E从1500降到1200时最优模组数量从12跳到15说明拐点非常陡没有模型辅助很难把握节奏。5.4 方案的工程落地性讨论最后一件事把优化结果拿到现实里审一遍。模型给的是数学最优解但工程落地还要看占地空间、变压器容量、并网批复这些边界条件。比如模型算出12块模组正好1200kWh但现场电池舱位只够放10块那这个最优解就没法直接实施你得把N_mod上界改小重算。这就是为什么我一直强调要基于模组数量做整数规划而不是先算理论容量再手动取整——因为工程约束本身就是整数系的直接纳入模型才能保证输出方案是可以直接下单采购的。6. 常见报错与排查经验MATLAB intlinprog 实战最后这部分把我调试这套模型过程中遇到过的典型问题整理成速查表每一条都是真金白银踩出来的。6.1 模型无解或不可行如果你运行solve之后exitflag是负数大概率是模型不可行。最快的排查方式是把约束逐条注释掉跑一遍看哪条约束加入后就无解了。最常见的原因有功率平衡约束和负荷数据不匹配某时段P_grid超过上下界也拉不平差额首末SOC一致约束加上SOC上下界约束后储能量变化范围不足以实现日循环功率容量比约束设得太严格比如k_pc1.5而电池模组的总容量除以功率根本达不到这个比例排查时建议把P_grid的上下界先放开比如设成-10000到10000如果这时模型有解就说明功率平衡可行再逐步收紧电网功率上下限。6.2 求解非常慢怎么办整数规划是NP难问题模型复杂时求解确实会慢。我遇到过几种情况二进制变量太多、M值太大导致LP松弛问题发散、整数变量上界太宽。应对方式第一优先是设置MaxTime和RelativeGapTolerance工程上不需要强求0间隙很多场景1%的间隙已经非常够用。第二是确认约束矩阵的尺度合理单位不统一会导致求解效率断崖式下跌。第三是减少不必要的整数变量比如N_mod的上界从50降到20分支定界的搜索空间会呈指数级缩小。6.3 数值尺度问题的经典症状与修复如果你发现求解结果特别奇怪比如SOC曲线出现极端大量级的抖动或者两次运行结果明显不一致先怀疑数值尺度。典型症状约束矩阵元素最大与最小差10的6次方以上求解器提示“Ill-conditioned”或“Numerical issues”结果对参数微小变化极其敏感修复手段统一改用MW和MWh做单位目标函数和约束系数量级尽量接近用optimoptions里的ConstraintTolerance调松一点检查是否正常6.4 常见错误速查表现象可能原因处理办法exitflag -2模型不可行逐条排查约束先放开P_grid边界exitflag -3求解超时未收敛增加MaxTime或放宽RelativeGapTolerance结果N_mod为小数忘了给N_mod设Type为integer检查optimvar定义SOC曲线锯齿状充放电效率设置反了检查eta_ch和eta_dis位置结果对初始条件敏感首末SOC一致约束缺失加上soc_cycle约束intlinprog报“Number of variables must be integer”变量类型未设置正确检查optimvar的Type属性除此之外还有一个容易被忽略的点当电池模组数是0时也就是“不装储能”E_rated为0约束里会除以E_rated的地方必须提前规避。用我前面讲的E_soc建模方式这个除法问题直接不存在这也是我推荐那种写法的重要原因。我个人在实际项目中的习惯是先用简化数据把所有代码流程跑通确认模型结构没有问题再替换成完整的数据集做正式计算。替换数据后如果结果出现明显跳变先检查数据单位、维度、时段数是否一致而不是先去怀疑求解器。混合整数规划这个工具箱在MATLAB里已经相当成熟了绝大多数模型出错都是建模过程中引入的bug不会是求解器本身的锅。
返回列表