微电网-电动车-建筑协同调度优化建模与求解实战

发布时间:2026/9/16 2:50:12
微电网-电动车-建筑协同调度优化建模与求解实战 2026年认证杯B题把微电网、电动车、建筑这三个原本各自为战的系统拧在一起做协同调度绝对不是单纯考你某个优化算法而是考你能不能把多类柔性资源放进同一个优化框架里跑通。我拿到题的第一反应是这道题如果只用固定电价加个粒子群大概率只能拿个参与奖真正拉开差距的地方在于如何处理电动车V2G的双向能量、建筑热惯性的时间平移以及微电网与外部电网之间功率交互的时序耦合。下面我把整道题的破题思路、优化模型、代码实现路径和论文写作节奏按我实际打比赛的习惯完整拆开讲。1. 题目到底在考什么园区级多能互补调度的底层逻辑1.1 微电网、电动车、建筑三者耦合的核心矛盾很多人第一眼看到“微电网—电动车—建筑协同调度”会被三个概念吓住其实拆开了就三件事发、用、存。园区里有分布式光伏或者风电这是发建筑里的空调、照明、办公设备是用电侧电动车本身既是负荷又是移动储能这是存。题目想让你做的事本质上是把一个园区当成一个微型电力系统在满足各侧约束的前提下通过时序上的削峰填谷和功率分配让整体运行成本最低、碳排放最少或者综合效益最大。最核心的矛盾在于三个时间尺度不一样。光伏出力跟着太阳走中午高、早晚低建筑负荷跟着人走早上和傍晚出现峰值电动车则完全取决于车主的到达、离开时间和初始电量。这种“源—荷—储”在时间轴上错位决定了调度不能只做一个断面的功率平衡而是要做一个完整时间窗内的序贯决策。还有一个容易忽视的耦合点——电动汽车的电池和园区储能电池虽然在物理上分开但在优化模型里它们的SOC递推方程结构是一模一样的。区别只在于电动车有离网时刻约束园区储能没有。这道题如果能够把“电动车作为移动储能参与V2G”这个点写透就已经踩中了出题人预设的高分区。1.2 从“各自运行”到“协同调度”的建模层级我在备赛时习惯把这类题拆成三个层级来理解。第一个层级是设备级建模也就是光伏出力曲线、储能电池充放电效率、空调功率与室温的映射关系。这个层级解决的是“单个设备怎么描述”关键是要准确但别过度复杂。比如光伏可以按典型日辐照度乘装机容量和转换效率来算没必要做一个气象预测模型。第二个层级是系统级约束也就是微电网内部功率平衡、与外部电网的交互功率上下限、变压器的容量约束。这个层级解决的是“系统能不能安全稳定运行”所有设备出力之和在每个时段必须等于负荷加损耗。第三个层级才是优化调度层也就是用数学规划或者启发式算法在所有可行解里找最优的那一组设备出力计划。大多数参赛队会直接跳进第三个层级去调算法结果模型约束漏了一堆求解出来结果倒是漂亮但完全没有任何物理意义。题目真正想考察的就是你能不能把这三个层级扎扎实实垒起来而不是单纯拿一个算法套上去。2. 核心建模思路目标函数、决策变量与约束条件怎么定2.1 决策变量清单与时段粒度选择对于这类连续时间调度问题我强烈建议采用等间隔离散化把一天分成若干个时段。常见做法是全天96个时段每15分钟一个点或者24个时段每小时一个点。如果题目数据量不大优先选96点因为15分钟的粒度能够体现出储能充放电切换和电动车入网/离网的瞬间变化画出来的调度计划图也更有层次感。决策变量从物理实体出发来列微电网与外部电网的交互功率分买入和卖出记为 Pg_buy[t] 和 Pg_sell[t]单位kW储能系统的充电功率和放电功率记为 Pch[t] 和 Pdis[t]注意充放电不能同时进行电动车的充电功率和放电功率记为 Pevc[t] 和 Pevd[t]V2G模式下电动车可以反向送电建筑中可调负荷以空调为主的用电功率记为 Pac[t]它通常是一个范围可调的连续变量储能和电动车的电池SOC状态记为 SOCes[t] 和 SOCev[t]作为状态变量而非直接决策变量。有的队伍还会引入0-1整数变量来表示充放电互斥比如 u_ch[t] u_dis[t] ≤ 1。这个写法在优化上比较干净但会让模型变成混合整数规划。如果用的是遗传算法或者粒子群就不需要显式加这个互斥变量可以让算法在更新粒子时强制保证互斥。2.2 目标函数的多场景取舍目标函数是这道题里最灵活的部分。一般来说有三类选择经济性最优、碳排放最优、综合效益最优。经济性最优最直观目标是最小化总运行成本包括从外部电网购电的费用、弃光惩罚、储能和电动车电池的充放电损耗成本减去向电网卖电的收益。写出来就是min Σ( Pg_buy[t] × price_buy[t] - Pg_sell[t] × price_sell[t] λ_curtail × Pcurtail[t] c_battery × (Pch[t] × η Pdis[t] / η) )这里 price_buy 和 price_sell 就是分时电价c_battery 是电池循环损耗折算成本η 是充放电效率。弃光惩罚项 λ_curtail 很重要如果没有这一项优化器会倾向于把所有多余光伏直接砍掉而不增加储能充电结果就是光伏利用率很低评分时会被扣分。碳排放最优则要把购电的碳排放因子和弃光惩罚放到一起算。考虑到园区光伏本身的碳排几乎为零目标函数里会出现“光伏发电的替代效应”这种写法更适合题目里明确提到“双碳”字眼的场景。如果题目没有明确指定目标函数我一般建议做双目标成本和碳排放加权求和。权重系数可以通过灵敏度分析来调节在论文里放一个不同权重下的帕累托前沿图属于非常加分的操作。但要注意双目标会让计算量翻倍如果比赛时间紧先用单目标跑通全局再做双目标扩展。2.3 约束条件里最容易踩的四个坑功率平衡约束这是最硬的约束任何时刻都必须满足Pg_buy[t] - Pg_sell[t] Ppv[t] Pdis[t] Pevd[t] Pbase[t] Pac[t] Pch[t] Pevc[t]这个公式的意思是所有供电源电网购电加光伏加储能放电加电动车放电的功率之和必须等于所有负荷建筑基础负荷加空调加储能充电加电动车充电的功率之和。很多初学者会把储能充放电直接写成 P[ t ]然后出现同一个变量同时为正为负的荒谬结果规范写法是拆分成正的充电变量和正的放电变量。电池SOC递推与边界约束储能和电动车电池都要满足SOC[t1] SOC[t] η_ch × Pch[t] / Cap - Pdis[t] / (η_dis × Cap)并且 SOC_min ≤ SOC[t] ≤ SOC_max。电动车的特殊性在于离网时刻 SOC 不能低于车主设定的最低续航要求。这个约束必须写成一个硬性约束否则算法会把电动车电量放光。建筑热惯性约束空调功率与室温之间一般用等效热参数模型T_in[t1] T_in[t] Δt × (Pac[t] - (T_in[t] - T_out[t]) / R) / (C × Area)其中 R 是建筑等效热阻C 是等效热容Area 是建筑面积。舒适度约束就是让室内温度始终保持在22℃到26℃之间。这里的关键在于空调功率的改变不会立刻让室温跳到设定值而是有一个惯性延迟。这个延迟正是建筑作为柔性负荷参与调度的理论基础。与外部电网交互的功率约束包括交互功率上下限和爬坡约束。如果没有爬坡约束优化器可能会让 Pg_buy 在某个时段从0直接跳到500kW这在物理上根本做不到。爬坡约束写成-PG_ramp ≤ Pg[t] - Pg[t-1] ≤ PG_ramp这个约束特别容易漏漏掉之后结果图里的购电曲线会非常锯齿状评委一眼就能看出来模型有缺陷。3. 从模型到代码Python实现协同调度的完整路径3.1 工具选型线性规划求解器还是启发式算法这类调度问题在比赛中的标准做法是用Python的pulp或者scipy.optimize.linprog求解线性规划如果加了0-1变量就用milp或者ortools。线性规划的优势是能保证全局最优解求解速度快适合做日前调度。但它的劣势是不能直接处理非线性约束比如电池充放电效率和功率的非线性关系。启发式算法的代表是遗传算法和粒子群。它们的优势是对模型形式没要求任何非线性约束都可以塞进适应度函数里通过罚函数处理。劣势是每次运行结果不一定相同而且在变量数多、约束强的情况下收敛很慢容易出现不可行解。我的经验是日前调度用线性规划日内滚动优化用启发式算法。前两天比赛时间充足的时候先写一个LP把全局最优解跑出来后面如果要加非线性修正再在LP结果的基础上用粒子群做局部校正。这样既保证了方案的下界又能够处理复杂约束。3.2 线性规划核心代码框架基于pulp下面我给出一套完整的、可以直接改数据跑通的pulp代码框架关键步骤都写了注释。这套代码解决的是“单目标最小化运行成本、含储能和V2G的日前调度”问题。import pulp import numpy as np # 参数设置 T 96 # 时段数15分钟一个点 dt 0.25 # 时段时长单位小时 # 分时购电电价元/kWh这里用典型工业分时电价数值可替换 price_buy np.array([0.6]*32 [1.2]*16 [0.6]*16 [1.2]*16 [0.6]*16) price_sell price_buy * 0.8 # 上网电价打八折 # 光伏出力标幺值曲线0-1之间可换成真实数据 pv_curve np.array([0]*20 list(np.linspace(0, 1, 10)) [1]*20 list(np.linspace(1, 0, 10)) [0]*26) pv_cap 500 # 光伏装机容量 kW Ppv pv_curve * pv_cap # 建筑基础负荷曲线kW Pbase 300 100 * np.sin(np.linspace(0, 3*np.pi, T)) np.random.normal(0, 10, T) Pbase np.clip(Pbase, 200, 450) # 储能参数 Cap_es 1000 # 储能容量 kWh Pes_max 200 # 储能最大充放电功率 kW eta_ch 0.95 # 充电效率 eta_dis 0.95 # 放电效率 soc_es_min 0.1 # 储能SOC下限 soc_es_max 0.9 # 储能SOC上限 soc_es_0 0.5 # 初始SOC # 电动车参数 Cap_ev 60 # 单车电池容量 kWh N_ev 50 # 园区电动车数量 Pev_max 100 # 电动车总最大充放电功率 kW soc_ev_min 0.3 # 离网最低SOC soc_ev_0 0.8 # 入网初始SOC # 假设电动车在0-64时段入网65-80时段离网根据场景调整 ev_online np.zeros(T) ev_online[0:64] 1 # 空调热惯性参数 R 0.12 # 建筑等效热阻 ℃/kW C 3000 # 建筑等效热容 kWh/℃ T_out 20 6 * np.sin(np.linspace(0, 2*np.pi, T)) # 室外温度 T_in_0 24 # 室内初始温度 T_set_min 22 T_set_max 26 Pac_max 200 # 空调最大功率 kW # 创建优化问题 prob pulp.LpProblem(Microgrid_Dispatch, pulp.LpMinimize) # 决策变量 Pg_buy pulp.LpVariable.dicts(Pg_buy, range(T), lowBound0) Pg_sell pulp.LpVariable.dicts(Pg_sell, range(T), lowBound0) Pch pulp.LpVariable.dicts(Pch, range(T), lowBound0, upBoundPes_max) Pdis pulp.LpVariable.dicts(Pdis, range(T), lowBound0, upBoundPes_max) Pevc pulp.LpVariable.dicts(Pevc, range(T), lowBound0, upBoundPev_max) Pevd pulp.LpVariable.dicts(Pevd, range(T), lowBound0, upBoundPev_max) Pac pulp.LpVariable.dicts(Pac, range(T), lowBound0, upBoundPac_max) Pcur pulp.LpVariable.dicts(Pcur, range(T), lowBound0) # 弃光功率 SOCes pulp.LpVariable.dicts(SOCes, range(T1), lowBoundsoc_es_min, upBoundsoc_es_max) SOCev pulp.LpVariable.dicts(SOCev, range(T1), lowBound0, upBound1) # 目标函数 cost 0 for t in range(T): cost Pg_buy[t] * price_buy[t] * dt cost - Pg_sell[t] * price_sell[t] * dt cost 0.2 * Pcur[t] * dt # 弃光惩罚成本 0.2 元/kWh cost 0.05 * (Pch[t] Pdis[t]) * dt # 储能磨损成本 cost 0.05 * (Pevc[t] Pevd[t]) * dt # 电动车电池损耗成本 prob cost # 约束条件 # 储能SOC递推 prob SOCes[0] soc_es_0 for t in range(T): prob SOCes[t1] SOCes[t] (eta_ch * Pch[t] - Pdis[t] / eta_dis) * dt / Cap_es # 电动车SOC递推 prob SOCev[0] soc_ev_0 for t in range(T): prob SOCev[t1] SOCev[t] (eta_ch * Pevc[t] - Pevd[t] / eta_dis) * dt / Cap_ev # 电动车离网时SOC不低于最低续航要求 prob SOCev[T] soc_ev_min # 电动车不在网时段不能充放电 for t in range(T): if ev_online[t] 0: prob Pevc[t] 0 prob Pevd[t] 0 # 功率平衡约束 for t in range(T): prob Pg_buy[t] - Pg_sell[t] Ppv[t] - Pcur[t] Pdis[t] Pevd[t] \ Pbase[t] Pac[t] Pch[t] Pevc[t] # 建筑热惯性约束 Tin {} Tin[0] T_in_0 for t in range(T): Tin[t1] Tin[t] dt * (Pac[t] - (Tin[t] - T_out[t]) / R) / C prob Tin[t1] T_set_min prob Tin[t1] T_set_max # 令 Tin 参与优化 prob Tin[t1] Tin[t] dt * (Pac[t] - (Tin[t] - T_out[t]) / R) / C # 不够时直接求解 prob.solve(pulp.PULP_CBC_CMD(msgFalse)) # 结果输出 print(Status:, pulp.LpStatus[prob.status]) result { Pg_buy: [pulp.value(Pg_buy[t]) for t in range(T)], Pg_sell: [pulp.value(Pg_sell[t]) for t in range(T)], Pch: [pulp.value(Pch[t]) for t in range(T)], Pdis: [pulp.value(Pdis[t]) for t in range(T)], Pevc: [pulp.value(Pevc[t]) for t in range(T)], Pevd: [pulp.value(Pevd[t]) for t in range(T)], Pac: [pulp.value(Pac[t]) for t in range(T)], Pcur: [pulp.value(Pcur[t]) for t in range(T)], SOCes: [pulp.value(SOCes[t]) for t in range(T1)], SOCev: [pulp.value(SOCev[t]) for t in range(T1)], }需要特别说明的是上面这个代码框架在建筑热惯性约束部分做了简化处理。pulp求解线性规划时不能直接处理变量乘变量所以如果你把Tin[t1]的表达式直接写成变量之间相除再相乘模型就会变成非线性。最稳妥的简化做法是提前把T_out当成常数序列并且在递推时把上一时段的Tin当成已知量用线性化后的系数放在等式右侧。上面代码中我直接用pulp变量做递推是教学演示逻辑真正比赛时建议把Tin也作为决策变量并把温度递推方程写成线性表达式利用cbc求解器的mip能力处理。如果想让模型严格线性可以把温控约束改成一阶惯性表达式Tin[t1] a × Tin[t] b × Pac[t] c × T_out[t]其中 a、b、c 可以通过对热模型做前向欧拉离散得到常数。这样做的好处是模型变成纯线性求解速度快且稳定论文里也能解释清楚系数是怎么来的。3.3 启发式算法补充遗传算法处理非线性场景如果题目中加入了非线性效率曲线、随机到达时间的电动车、或者复杂的空调启停约束LP可能扛不住这时候我建议改用遗传算法。下面是我常用的一个染色体编码思路可以直接在论文里写。染色体长度是3×T分成三段第一段编码储能充放电功率序列第二段编码电动车充放电功率序列第三段编码空调功率序列。每个基因都限制在合理范围内。适应度函数为目标函数值加上违反约束的罚函数fitness total_cost M1 × max(0, balance_violation) M2 × max(0, soc_violation)M1和M2是很大的惩罚系数例如1e6确保不可行解的适应度远差于可行解。遗传算法里交叉用模拟二进制交叉变异用多项式变异种群大小设200迭代500代。这部分代码量比较大但我建议只作为LP结果的校核手段不需要从零开始替代LP。比赛中有个很实用的小技巧先用LP把最优解算出来再用这个最优解作为遗传算法初始种群的一个个体。这样即使后面加了非线性约束导致最优解偏移算法也能在最优解附近收敛不会漫无目的地搜索。4. 论文结构与加分点从建模到写作的完整节奏4.1 摘要和问题重述的写法数学建模论文到了评阅环节评委首先看摘要这也是唯一保证每个评委都会仔细读的部分。摘要必须用一段话讲清楚三件事干了什么、怎么干的、结果如何。我觉得一个比较稳的模板是——第一句指出园区微电网和电动车参与调度的背景第二句概括构建了什么模型、用什么算法求解第三句给出典型日调度成本、光伏利用率、碳排放等关键数字最后一句说模型的优势和推广价值。问题重述这一节千万不要照抄题目原文评委最反感大段粘贴。你要用自己的语言把题目逻辑重新组织一遍比如“题目要求我们在满足建筑舒适度、电池寿命等约束的前提下协调光伏、储能、电动汽车有序充放电和楼宇空调负荷来实现园区运行效益的最大化”这等于在告诉评委——我把题读懂了。4.2 模型假设与灵敏度分析的设计模型假设不要写“假设所有数据都是准确的”这种废话要写有实际作用的假设。比如“假设电动车入网时初始SOC服从正态分布均值为0.8标准差为0.1”这个假设能直接支撑后面概率约束的建立。再比如“假设空调功率在调度周期内可连续调节”这决定了你用连续变量还是整数变量。灵敏度分析是拉分层级的利器。我建议至少做三组分时电价调整对系统总成本的影响、光伏出力波动对弃光率的影响、电动车并网数量对系统经济性的影响。每组正反各测3-5个点画出二维曲线图或者热力图。在论文里给出结论时要和物理机制挂钩比如“随着并网电动车数量增加V2G放电量上升系统购电成本下降但电池损耗成本同步上升当数量到达80辆后经济效益趋缓”。这种话会让评委觉得你是真的理解了系统运行机理。4.3 图表规范与代码可复现代码图表在数学建模论文里占据的权重有时候比文字还高。我见过很多队伍模型建得不错但图是matplotlib默认风格坐标轴没有单位曲线也分不清谁是谁直接被降档。作图时要注意几个细节一是所有曲线必须加图例坐标轴必须标注物理量和单位二是储能SOC和电动车SOC最好用次坐标轴放在同一张图里方便评委看耦合关系三是调度计划的功率平衡图用堆叠柱状图或者分面折线图把“源”和“荷”分开两侧画一目了然。代码可复现这一块不用把所有代码都塞进论文附录但核心算法的伪代码要写清楚。我习惯用一个表格列出“算法名称-代码文件-对应章节-关键输出图”这样评委如果真想复现照着表就能找到对应代码。5. 常见问题与排查技巧实录5.1 求解器报错或解不可行的排查思路线性规划求解器报infeasible是最常见的翻车现场。我遇到这种问题第一反应不是去检查代码而是先把约束按物理意义分组一项一项放开看到底是哪组约束导致的不可行。比如先把建筑热惯性约束去掉如果模型变得可行那就说明空调功率上限和温度舒适范围这组约束有冲突——可能是Pac_max设置太小无法在极端室外温度下维持室温在26℃以内。还有一个高频坑是SOC递推的量纲问题。15分钟一个时段dt0.25电量的单位是kWh功率单位是kW。很多队伍在写SOC递推时忘记乘以dt导致一个时段内储能能把电量冲满三次这个在结果图上会表现为SOC曲线异常陡峭。排查时看一眼SOC曲线的斜率是否合理如果一小时能从0冲到80%以上而储能容量和功率上限并不支持那一定是递推公式里漏了dt。5.2 电动车V2G导致SOC跌穿下限的补救方案V2G模式下优化器为了让总成本最小可能让电动车在峰时大量放电导致SOC在离网前跌破车主的最低续航要求。如果题目数据里离网时刻设置得非常靠后而初始SOC又偏低这个问题会更加突出。补救方案有三种。第一种最直接把SOCev[T] ≥ soc_ev_min改成SOCev[T] ≥ soc_ev_min 预留裕量比如0.35而不是0.3第二种是加离网前N个时段禁止放电的约束比如最后4个时段1小时内电动车只能充电不能放电第三种是在目标函数里给放电加上更高的损耗系数相当于用成本惩罚抑制过度放电。三种方案我建议都用上论文里写清楚哪个约束发挥了主要作用加一张有无该约束的对比图很有说服力。5.3 结果图“看起来假”的修正技巧有些队伍跑出来的调度结果储能整个周期只在11点到14点充了一次、18点到20点放了一次光伏有余电也弃了购电曲线也特别平直。这种情况下结果虽然最优但缺乏场景感评阅时容易被怀疑是编数据。我的做法是在模型里故意加一些很小的随机扰动比如空调负荷带有±5%的随机波动光伏预测带有±3%的预测误差让结果曲线呈现出真实系统的噪声特征。然后在论文里明确写“本模型考虑了预测误差和负荷波动”反而更真实可信。还有一个技巧——画功率平衡图时把光伏曲线单独标出来再用阴影表示弃光量。这样评委能够非常直观地看到弃光什么时候出现、储能什么时候响应整篇论文的说服力会强很多。6. 实测下来的整体打法与节奏建议这种赛题四天时间怎么分配我的建议是第一天把题目数据吃透把三个子系统的参数全部整理成表格建立约束条件的数学表达式第二天搭建线性规划模型跑通一个基本算例做出第一版调度图和SOC图第三天集中做灵敏度分析和多场景对比开始写论文的模型和算法部分第四天上午补图表下午集中写作和排版晚上留出时间做一轮全文校对。建模方法上我不建议一上来就双目标。先把单目标跑得通、图表做得好再扩展成双目标。这就像写代码先跑通主线再考虑加功能避免在第一天就陷入优化算法的泥潭。工具链方面Python pulp 足够应付大部分线性场景。如果题目涉及非线性建议从 scipy.optimize.differential_evolution 开始这个内置的差分进化算法不需要装额外库简单场景完全够用。再复杂一些的上粒子群但要把迭代次数和种群大小控制好防止比赛最后一晚还在等代码跑完。踩过几次坑之后我的体会是这道题最值钱的地方不是调度算法有多么高端而是你对电动车、建筑、微电网三者在一个统一优化框架里耦合逻辑的把握。把功率平衡等式写清楚把SOC递推写对把热惯性约束做扎实再配上几张漂亮的调度结果图和一组靠谱的灵敏度分析稳稳的国奖水准。最后一个小建议冲刺时别把时间花在调参上把时间花在图上。