十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

两阶段鲁棒微网优化调度:关键场景辨别算法实现与调参实战

两阶段鲁棒微网优化调度:关键场景辨别算法实现与调参实战 微电网优化调度这几年基本是能源方向研究生的必修课但大多数入门教程都停留在“确定性调度”的舒适区里——给定光伏曲线、给定负荷曲线优化一个机组组合完事。实际项目里光伏和风速的预测误差往往超过20%负荷也不是乖乖按历史曲线走定了的调度计划根本执行不下去。所以“考虑不确定性”的调度模型才是真正能落地的东西而两阶段鲁棒优化就是目前工程和学术上都认可的主力方法之一。这篇内容我围绕“基于关键场景辨别算法的两阶段鲁棒微网优化调度”展开把这套方法从头到尾讲透模型长什么样、为什么需要关键场景辨别、Matlab代码怎么组织、算例结果怎么分析。适合正在做微网方向毕业设计、准备发论文或者工作里要写实际调度策略的工程师参考。我会把求解细节、避坑点和调参经验一并放出来争取你读完之后直接能照着复现一个可跑的版本。1. 为什么微网调度必须考虑不确定性从确定性模型到两阶段鲁棒先聊一个实际问题。你建一个微网调度模型里面有柴油机、储能、光伏、风机还有和上级电网的联络线。如果按照确定性模型来做日前调度你需要假设明天的光伏出力曲线、风速曲线、负荷曲线都是“已知”的。但在真实运行中这些都是预测值而且误差不小。晴天变阴天光伏出力直接腰斩工厂临时加班负荷曲线可能整体抬升。这时候你昨天定好的机组启停计划和储能充放电计划轻则成本飙升重则出现切负荷、弃光弃风甚至安全约束被突破。不确定性怎么处理业界大致有三条路线。随机规划的思路是给不确定性变量赋予概率分布然后用场景抽样近似期望成本。它的优点是经济性描述比较精细缺点是需要知道比较准确的概率分布而且场景数量一大模型规模就爆炸。模糊鲁棒和分布鲁棒在概率不确定性描述上做了很多文章但建模复杂度和求解难度也随之上升。最常用、最稳妥的其实是鲁棒优化——不假设分布只假设不确定量落在某个集合范围内优化目标是在“最恶劣情况”下仍然可行且成本可控。鲁棒优化的关键在第一层不确定性集合的构造。常用的是盒式集合也就是每个不确定参数都在一个区间范围内负荷在预测值的[1-ε, 1ε]区间波动光伏在[0, P_max]范围波动。但纯盒式集合的问题在于把所有变量都顶到边界求解结果往往过于保守——实际运行中不可能所有扰动同时取最坏值。工程上普遍采用带“budget”预算约束的盒式集合限制最多只有Γ个不确定性变量可以同时偏离预测值到极端。这个Γ参数直接控制保守程度是我后面代码里最需要调的参数之一。确定性模型到鲁棒模型的升级本质上是把“给一组确定数值求最优解”变成“在无限多组可能取值中找到最坏情况求最优解”。而两步走的“两阶段”结构则是在时间和决策逻辑上做了拆分第一阶段做日前决策定下机组启停、储能日前充电计划这类“不可随时变”的大决策第二阶段等不确定性逐步暴露再做实时调整比如微调机组出力、调整储能功率、增减购售电量。两阶段鲁棒优化的核心问题就是今天先做第一阶段决策并且要确保明天无论哪种恶劣情况发生第二阶段都有办法用最经济的调整量让系统安全运行。两阶段鲁棒微网调度之所以难难在它不是一个普通优化问题而是“min-max-min”三层结构外层min是第一阶段决策中层max是搜索最恶劣场景内层min是第二阶段最经济的调整。这种结构无法直接丢给求解器必须把它拆解成可迭代求解的主问题和子问题。而拆解方式和求解效率就是我接下来要重点讲的内容。2. 两阶段鲁棒微网调度模型的数学结构与实现前提在动手写Matlab之前先要把模型形式化。本文采用的微网结构包括柴油机、储能系统、光伏单元、风力发电单元、本地负荷以及联络线。调度周期取24小时时间分辨率1小时。2.1 第一阶段(日前)决策变量第一阶段决策变量是那些在不确定性实现之前就必须确定下来的量通常取柴油机启停状态u_t0-1变量柴油机开机动作变量储能日前计划的充电/放电状态指示联络线日前购电/售电计划第一阶段的目标是极小化日前决策成本包括柴油机启停费用、运行准备费用以及按照预测场景预估的基础运行成本。但这个预估并不准确所以需要加上第二阶段“最恶劣场景下的调整成本修正”。第一阶段约束包括柴油机最小启停时间约束、机组启停逻辑约束、储能状态与功率的逻辑约束等。2.2 第二阶段(再调度)决策变量与约束第二阶段决策变量是看到不确定性实现后可以调整的量通常取柴油机实际输出功率P_g,t在启停状态固定的前提下调整储能实际充放电功率P_ch,t、P_dis,t联络线实际购售电功率切负荷量、弃光弃风量作为惩罚项第二阶段约束有功率平衡约束光伏风电柴油机储能放电购电负荷储能充电售电弃光弃风储能SOC动态约束荷电状态在连续时段之间递推柴油机出力上下限和爬坡约束联络线功率上下限储能充放电功率限制。2.3 两阶段鲁棒的抽象表达把上述模型写成数学上紧凑的形式min (c^T x max_{u∈U} min_{y∈F(x,u)} d^T y)其中x代表第一阶段决策u代表不确定性参数光伏、风速、负荷的扰动向量y代表第二阶段调整决策。U是不确定性集合F(x,u)是给定x和u之后的可行域。这个三层结构是第一道坎。在Matlab里用YALMIP建模时sdpvar定义变量很简单但不要试图直接把max-min写成一个优化问题丢给求解器。2.4 求解这个模型的通用策略CCG算法框架工业界和学术界求解两阶段鲁棒优化最常用的算法是列与约束生成CCG也叫Benders式切割方法。核心思想是把原问题拆成主问题和子问题主问题MP包含第一阶段决策变量和一组已经被识别出来的“关键恶劣场景”对应的第二阶段决策变量求解得到当前最优的第一阶段解x以及目标值下界。子问题SP给定主问题求出的x去最大化第二阶段的最小成本也就是找到最恶劣的场景u*并得到目标值上界。迭代过程是主问题→子问题→识别出一个新的关键场景把这个场景及其对应的第二阶段变量和约束加到主问题→重新求解主问题→再进子问题……直到上下界间隙小于设定阈值。这里就涉及到本文标题里的核心概念关键场景辨别算法。3. 关键场景辨别算法把“枚举所有场景”变成“只抓最恶劣的几个”先说说没有关键场景辨别时CCG子问题是怎么处理的。经典做法是用强对偶理论把内层min问题对偶成max形式和外层max合并成一个单层max问题然后一次性求解出最恶劣的不确定性实现。这个方法数学上是严谨的计算上也高效但它有一个隐藏问题对偶后的max问题本质上是把所有不确定性变量当成连续变量同时推向某个极端组合来构造最恶劣情形而你基于这个“连续最坏场景”生成的割平面加进主问题后往往导致收敛变慢——因为实际调度过程中真正值得关注的“关键场景”往往远少于对偶模型搜索空间中点出来的那个连续极点。我在这里采用的关键场景辨别算法思路上和“场景缩减迭代筛选”结合起来而不是直接解对偶max。3.1 第一层辨别场景缩减预处理先构造一个初始场景池。场景池的来源可以是历史数据抽样也可以对预测误差按某种概率分布蒙特卡洛抽样。假设我抽了N1000个光伏/风速/负荷组合场景。注意这1000个场景不能直接全塞进鲁棒模型里那样就退化成大型随机规划了求解规模和速度都受不了。所以先用场景聚类算法本实现用K-means变体加上概率距离加权把1000个场景缩减到30-50个代表性场景。这是第一层“辨别”——保留不确定性分布的特征去除冗余场景。但聚类缩减排出来的代表性场景不能直接当作鲁棒优化的“关键场景”因为它保留了整体分布的多样性未必包含真正的极端恶劣场景。所以还要有第二层辨别。3.2 第二层辨别面向最恶劣目标的动态筛选第二层辨别的核心逻辑是在CCG迭代中动态识别真正能够提升主问题约束紧度的场景。每轮迭代中把离线缩减得到的候选场景集合作为“候选池”对每个候选场景计算在给定第一阶段解x下的第二阶段目标函数值d^T y*(x, u_candidate)。取目标函数值最大的那个场景作为本轮“最恶劣场景”。如果这个最恶劣场景和第二阶段的“真实最恶劣场景”接近那就有资格进入主问题成为产生割平面的关键场景。判断“是否足够接近”的准则是关键候选场景中第二阶段目标值最大的值与用连续对偶max方法求解出的绝对最坏场景目标值之间的相对误差小于比如5%就认为这个候选场景已经足够恶劣可以采用它来生成割平面并可以提前终止对偶子问题的精确求解节省大量时间。3.3 为什么这样做能提升效率纯CCG中每一轮子问题都要解一个包含几百个变量的对偶max问题遇到混合整数约束时还要做线性化处理单轮耗时很大。关键场景辨别算法的思路是用“候选场景扫描目标值排序”替代“每轮都对偶求解”。候选场景只有30-50个每个场景的第二阶段问题是一个标准的LP或MILP求解速度极快两两对比其目标函数值即可定位到“相对最恶劣”的场景。只在这个场景与精确解误差超过阈值时才启动完整对偶求解作为必要时的高精度校验。这句话听起来简单但实际工程收益很大。我的测试算例中场景数1000时纯CCG求解要400多秒加入关键场景辨别之后降到80秒左右迭代轮数反而更少因为聚类缩减排除了大量数值接近的场景避免了割平面重复添加。3.4 参数选择与适用场景的注意事项关键场景辨别算法适合什么情况场景基数大、连续对偶模型规模大、且第二阶段子问题LP/MILP可以快速批量求解的情况。如果场景基数很小比如只有10个直接对偶求解可能更快。预算参数Γ即不确定性集合中允许同时到达最坏值的维度上限对结果影响很大Γ越大集合越保守找出来的关键场景往往集中在少数几个时段变坏算法加速效果也更明显。另外需要注意场景缩减后代表性场景可能把真正的极端情况“平均”掉。解决方法是保留一小部分边界场景比如光伏出力最低且负荷最高的极端组合作为额外候选防止聚类算法把尾部风险抹平。4. CCG迭代求解的工程实现主问题、子问题与割平面的代码级拆解这一章进入代码层面。假设你已经安装了Matlab R2020a及以上版本并配置了YALMIP工具箱以及Cplex/Gurobi求解器。没有YALMIP的先去装不然后面所有代码都跑不了。4.1 代码整体结构与数据准备我的工程目录结构是这样的two_stage_robust_microgrid/ ├── main_run.m # 主程序入口 ├── data_system.m # 系统参数定义 ├── data_scenarios.m # 场景生成与缩减 ├── build_MP.m # 构建主问题MP模型 ├── build_SP.m # 构建子问题SP模型 ├── solve_dual_SP.m # 对偶max子问题求解精确法 ├── key_scenario_detect.m # 关键场景辨别模块 ├── plot_results.m # 结果可视化 └── results/ # 保存结果data_system.m里定义微网基本参数包括柴油机额定功率50kW最小出力10kW爬坡上限20kW/h启动费用30元/次运行成本系数0.62元/kWh储能容量100kWhSOC上下限[0.1, 0.9]充放电功率上限25kW效率0.95初始SOC 0.5联络线购电功率上限80kW售电功率上限50kW光伏预测出力白天典型钟形曲线峰值40kW实际波动范围取±30%负荷预测值谷值30kW、峰值70kW波动范围取±15%data_scenarios.m里做场景生成% 生成1000个候选场景 N_scenarios 1000; for i 1:N_scenarios % 光伏误差场景预测值 随机偏差 pv_scenarios(:, i) pv_forecast pv_deviation_max * randn(24, 1); % 风速误差场景 wind_scenarios(:, i) wind_forecast wind_deviation_max * randn(24, 1); % 负荷误差场景 load_scenarios(:, i) load_forecast load_deviation_max * randn(24, 1); % 保证下限不小于0 pv_scenarios(pv_scenarios(:, i) 0, i) 0; load_scenarios(load_scenarios(:, i) 0, i) 0; end % 场景缩减保留30个代表场景 [key_scenarios_pool, pool_probability] kmeans_scenario_reduction(pv_scenarios, wind_scenarios, load_scenarios, 30);注意这里生成的场景直接用randn可能产生极端值导致鲁棒模型过于保守。所以我会在生成之后做一步截断比如限制光伏偏差不超过±50%负荷偏差不超过±30%当作场景筛除条件把太离谱的场景先扔掉。4.2 主问题MP的YALMIP建模主问题MP是CCG迭代中被反复修改的模型每轮加一组新的第二阶段变量和约束。初始时只包含第一阶段变量没有第二阶段变量随着迭代不断加入与关键场景对应的第二阶段变量。用YALMIP代码表示核心部分% 第一阶段变量 u_start binvar(24, 1); % 柴油机启停 u_on binvar(24, 1); % 开机动作 p_buy_DA sdpvar(24, 1); % 日前购电计划 p_sell_DA sdpvar(24, 1); % 日前售电计划 % 第一阶段目标 obj_DA sum(start_cost * u_on) sum(run_cost * u_start); % 第一阶段约束 % 启停逻辑开机当前状态-上一状态 Constraints_MP []; for t 2:24 Constraints_MP [Constraints_MP, u_on(t) u_start(t) - u_start(t-1)]; end % 最小运行/停机时间约束典型形式 % ... % 迭代中加入第二阶段变量与约束 % 每轮循环k添加一组对应的场景变量 for k 1:K_iteration % 定义该场景对应的第二阶段变量 p_g{k} sdpvar(24, 1); p_ch{k} sdpvar(24, 1); p_dis{k} sdpvar(24, 1); p_buy_rt{k} sdpvar(24, 1); p_sell_rt{k} sdpvar(24, 1); soc{k} sdpvar(25, 1); load_cut{k} sdpvar(24, 1); pv_curtail{k} sdpvar(24, 1); % 该场景的功率平衡约束 Constraints_MP [Constraints_MP, p_g{k} p_dis{k} p_buy_rt{k} pv_real{k} load_real{k} p_ch{k} p_sell_rt{k} load_cut{k} pv_curtail{k}]; % 柴油机出力上下限约束 Constraints_MP [Constraints_MP, p_g_min * u_start p_g{k} p_g_max * u_start]; % 储能SOC递推 Constraints_MP [Constraints_MP, soc{k}(t1) soc{k}(t) (p_ch{k}(t) * eta_ch - p_dis{k}(t) / eta_dis) / capacity]; % 切负荷和弃光上限 Constraints_MP [Constraints_MP, 0 load_cut{k} 0.05 * load_real{k}]; Constraints_MP [Constraints_MP, 0 pv_curtail{k} pv_real{k}]; end % 目标函数为第一阶段成本 各关键场景对应的第二阶段成本加权β变量这里容易踩坑的地方是变量索引问题。YALMIP的sdpvar在循环里创建cell数组时如果约束条件太多内存占用会快速上涨所以建议每轮加入割平面之前先跑一次optimize检查约束数避免主问题无解或内存溢出。4.3 子问题SP与对偶化处理不采用关键场景辨别时子问题SP是一个max-min问题给定第一阶段解x0内层是min_{y∈F(x0, u)} d^T y对偶化内层后得到max_{u∈U, λ∈Λ(u)} (d^T y λ^T (b - A u))其中λ是对偶变量Λ是对偶可行域。这个max问题中的目标函数包含-λ^T A u项而u是连续变量因此目标函数对u是一次的在盒式集合约束下最优解一定发生在U的顶点上。这条性质非常关键是可以用枚举顶点方法验证算法正确性的理论依据。在Matlab中我当时是手动推导对偶而不是完全依赖自动对偶工具。严谨的做法是先用纸笔把内层LP写标准形式算对偶再用YALMIP把对偶变量和互补松弛条件写出来。但如果你的子问题是MILP比如第二阶段包含整数变量、储能开关状态就不能直接对偶了需要做特殊处理要么把整数变量在第一阶段固定要么用大M法线性化互补松弛。我在实现中把储能充放电状态变量留在了第一阶段决策中这样第二阶段就是纯LP可以直接对偶。4.4 关键场景辨别模块的实现逻辑核心函数key_scenario_detect.m的伪代码如下function [worst_scene, gap, flag] key_scenario_detect(key_pool, x0) % key_pool: 预缩减后的候选场景池 % x0: 当前第一阶段解 % 返回: 识别出的最恶劣场景、与精确值相对误差、是否需要触发精确对偶求解 N_pool size(key_pool, 3); % 候选场景数量 obj_values zeros(N_pool, 1); for i 1:N_pool % 固定第一阶段变量x0求解该场景下的第二阶段LP [obj_values(i), ~] solve_second_stage_LP(x0, key_pool(:, :, i)); end [worst_obj, worst_idx] max(obj_values); worst_scene key_pool(:, :, worst_idx); % 精确求解对偶max评估差距 [dual_obj, dual_scene] solve_dual_SP(x0); gap abs(dual_obj - worst_obj) / abs(dual_obj 1e-6); % 若差距大于5%触发一次精确对偶求解并返回精确最恶劣场景 if gap 0.05 flag 1; worst_scene dual_scene; else flag 0; end end实际运行中绝大多数轮次gap都小于5%所以不需要调用精确对偶求解。只有在前几轮策略变化较大时候选场景池的目标值排序和精确最坏场景有偏差需要进入精确求解校准。这里也建议把每次迭代的目标值记录下来画收敛曲线时能明显看出“平台期”和“跳变期”。4.5 主循环与收敛判据主循环代码骨架% 初始化 LB -inf; UB inf; iter 0; max_iter 20; tol 1e-3; % 初始不确定性集合预算参数 Gamma 6; while (UB - LB) / abs(UB) tol iter max_iter iter iter 1; % 1. 求解主问题MP optimize(Constraints_MP, obj_MP, sdpsettings(solver, gurobi)); LB value(obj_MP); x0.u_start value(u_start); x0.u_on value(u_on); x0.p_buy_DA value(p_buy_DA); % 2. 用关键场景辨别模块求解子问题 [worst_scene, gap, flag] key_scenario_detect(key_pool, x0); % 3. 计算UB [sp_obj, ~] solve_second_stage_LP(x0, worst_scene); UB min(UB, value(obj_DA) sp_obj); % 4. 把识别出的关键场景加入主问题 K_iteration K_iteration 1; add_scene_to_MP(Constraints_MP, obj_MP, worst_scene); % 5. 记录迭代信息 iter_info(iter, :) [iter, LB, UB, gap]; end这个循环写起来不难但有几个隐藏坑要提醒。第一主问题求解完之后第一阶段变量x0传给子问题之前必须round处理0-1变量否则数值上0.9999和1的差别可能导致子问题可行域变化。第二UB的计算要取min(UB, obj_DA sp_obj)因为第k轮找到的最恶劣场景只针对第k轮的x不是全局最优上界取min才能保证上界单调递减。第三主问题每轮都加新变量和约束模型规模会逐渐变大但如果候选场景池质量高通常10轮以内就能收敛不会出现规模失控。5. Matlab代码实现中的高级细节与调参实战这一章总结我在实际编写和调试这套代码过程中踩过的坑以及最后整理出来的可复用经验。5.1 YALMIP-sdpvar与求解器之间的类型问题第一坑binvar和sdpvar混用时求解器选择非常敏感。Gurobi支持MILPCplex也支持。但如果你的YALMIP版本较老求解器接口配置不对会出现“无法处理非线性”或“求解器未安装”的报错。建议用YALMIP自带的yalmiptest命令先测试Gurobi是否正常工作。第二坑第二阶段LP的目标函数对d^T y如果里面有绝对值项例如储能充放电切换惩罚直接用abs()会让模型变成非光滑问题。我用的是引入辅助变量线性化的方案例如充放电切换费用 alpha * (p_ch p_dis)其中p_ch、p_dis都非负并且用约束p_ch * p_dis 0做互斥。但这个约束是双线性非凸的直接给求解器会报错。工程上的简化做法是不强制互斥只在目标函数里加一个很小的充放电总功率惩罚项避免同时充放电的经济浪费。结果基本等价。5.2 场景缩减中K-means的初始化敏感性K-means的聚类结果对初始中心点敏感直接默认的kmeans也不一定保证保留极端场景。我在实现中做了两步修正把极端场景作为种子点强制加入初始簇中心候选集。例如光伏最小值场景、负荷最大值场景、光伏最值且负荷最大值组合场景等。聚类距离度量改为加权欧氏距离权值与场景出现的概率相关让低概率但高影响的场景有被保留的机会。这些修正听起来很工程化但在最终的调度成本计算中影响不小。没有保留极端场景时最优调度在真实最恶劣输入下会出现切负荷处罚导致总成本上升10%-15%。5.3 预算参数Γ与保守度的关系Γ是两阶段鲁棒模型里最重要的旋钮。Γ0时退化为确定性模型Γ24时表示所有时段的不确定性都可能同时取最坏值结果最保守。实际算例中我画出了Γ从0到12的总成本变化曲线Γ在0到4之间成本上升较快4到8之间趋于平缓8以上基本不再变化——说明这个微网系统真正严峻的不确定性组合只集中在少数几个时段Γ取6到8是比较经济的选择。在论文里这也是个可以拿出来做敏感性分析的图。5.4 数值稳定性问题对偶变量、大M法与求解精度在对偶化子问题时需要把互补松弛条件线性化这里用大M法。M值的选取非常关键M太小会约束掉可行解M太大会导致数值病态。我的经验是M取该约束右侧量的10倍左右比如功率平衡约束M取最大负荷值的20倍。调M值的时候跑完一轮要检查主问题目标值和子问题目标值是否匹配如果不匹配说明大M法把某些本应满足的互补条件给松弛掉了。5.5 结果保存与复盘在main_run.m最后保存变量到results目录save(results/final_results.mat, x0, LB, UB, iter_info, Gamma); plot_results();plot_results函数输出三张图第一张是24小时功率调度堆叠图柴油机、光伏、储能、购电、负荷第二张是CCG迭代收敛曲线LB和UB随迭代次数变化第三张是关键场景识别数统计每轮识别出的场景标号。这三张图基本能支撑一篇论文的核心实验部分。6. 算例验证与算法性能对比从数据看关键场景辨别的价值为了让你直观看到算法效果我用上一章描述的系统参数跑了一组对比。微网系统参数固定不确定性场景抽样1000个候选池缩减到30个Γ取6收敛阈值tol1e-3。对比对象有两个Method A标准CCG每轮子问题精确对偶求解Method B本文的关键场景辨别增强CCG本文方法结果如下表指标Method A (标准CCG)Method B (关键场景辨别)迭代次数149总求解时间(秒)427.683.2最终总成本(元)3642.83651.3最恶劣场景下运行成本(元)4210.54215.9是否触发切负荷否否误差可接受范围-0.23%从表中能看到几个关键信息。第一Method B在迭代次数上少了5轮总求解时间只有Method A的约五分之一提速非常明显。第二最终总成本相差不到10元约0.23%这个误差主要来自关键场景对偶求解被提前截断产生的近似完全在工程可接受范围内。第三两种方法得到的最恶劣场景基本吻合验证了关键场景辨别算法的可靠性。再看候选场景数从30加到60对结果的影响候选池规模迭代次数求解时间(秒)最终总成本(元)10745.33678.220963.83659.530983.23651.36011128.63648.7候选池规模从10增加到30成本下降27元用时增加约84%再从30增加到60成本变化不足3元耗时却增加54%。这说明30个候选场景是这个算例的性价比拐点。不同微网结构该值不同建议做一次类似的候选池规模敏感性测试。从收敛曲线来看Method B在迭代前期第2-4轮就能快速逼近下界因为场景池中的关键候选场景在第一轮就被识别出来并加入到主问题实际效果是第二轮主问题添加的割平面已经非常接近最优割平面。Method A则因为每轮都在全空间搜索前期割平面质量参差不齐直到第7轮之后才进入稳定收敛区间。这些实验数据直接证明了关键场景辨别算法在这个问题上的价值它不是一个脱离实际的“数学游戏”而是在保证优化质量的前提下把计算资源从“每轮全空间搜索”转移到“预先筛选动态识别”上。需要客观说明的是这套算法也有它的局限。如果不确定性集合本身很小、场景天然就少那么关键场景辨别的优势就不明显甚至因为预处理流程增加了固定开销反而不如标准CCG。另外关键场景辨别算法依赖候选场景池的质量如果场景池构造不好比如只用了简单蒙特卡洛没有加极端场景种子那么识别出的“关键场景”很可能漏掉真正决定割平面的那一个导致迭代轮数不减反增。所以场景缩减这一步千万不要贪图省事这是整个算法效果的基石。我在自己的实际项目里后来还把这套流程推广到含多微网互联的园区级调度以及电-热-气多能互补的联合调度场景效果都还不错。核心的改进是把不确定性集合从一维的盒式拓展到多能耦合的椭圆集合关键场景辨别模块的排序逻辑不变变化的只是场景生成和约束形式。可以说掌握了“两阶段鲁棒关键场景辨别”这套组合拳之后微网调度的不确定性建模基本上能覆盖大多数工程需求了。代码跑通之后建议你先改改Γ参数再调调候选池规模亲手感受一下模型结果和求解速度的变化这套方法才算真正变成你自己的工具。
返回列表