首页 / 资讯中心 / 文章详情

电动汽车充电负荷概率化计算:蒙特卡洛与MATLAB实战

电动汽车充电负荷概率化计算:蒙特卡洛与MATLAB实战 ★ FEATURED ARTICLE
推荐所住的小区最近在讨论要不要安装一批公共充电桩物业拿不定主意核心原因是没人说得清“装上之后配电房容量到底够不够”。这种问题其实很有代表性电动汽车充电负荷不是一个固定值它跟每辆车几点到家、今天跑了多远、电池还剩多少电都有关系甚至和天气、路况、出行习惯都有关系。单纯按“车数乘以充电功率再乘一个同时率”去估算结果往往和实际差得很远。蒙特卡洛抽样就是解决这类随机性问题的主流方法通过大量重复抽样把“最可能的负荷曲线”和“最坏情况”同时算出来而MATLAB恰好是实现这种仿真最顺手的工具。这篇文章把我做充电负荷计算时的建模思路、概率分布参数选取、完整可运行代码和踩过的坑一次性摊开来讲适合正在做配电网规划、充电设施布局或者电动汽车V2G研究的朋友直接参考。1. 从“拍脑袋”到“掷骰子”充电负荷为什么必须概率化模拟1.1 传统确定性估算的局限在哪里很多人拿到“500辆电动汽车”这个数字时下意识会这样算单台充电功率7kW500辆车就是3500kW再乘以一个同时率系数。问题就出在这个同时率上——有的取0.3有的取0.5取多少全凭经验。但充电行为本身就是高度随机的通勤规律不同、回家的时间不同、当天行驶里程不同实际同时率根本不是一个常数。更麻烦的是充电负荷还会随时间呈现明显的“峰中峰”。工作日晚上六点到十点是私家车充电的高峰这个时段恰好也是居民用电晚高峰。如果规划时低估了这个叠加效应变压器可能在秋冬季节夜间直接过载。确定性估算给不出这个叠加过程的概率分布它只能给一个静态数字而这个数字既不知道有多大把握发生也不知道最坏情况能到多少。这正是概率性负荷计算的用武之地。1.2 蒙特卡洛抽样的核心思想蒙特卡洛抽样的本质就是用大量随机试验去逼近一个复杂系统的统计特征。它不追求解析公式而是把每个随机输入都建模成概率分布函数然后反复抽样、逐次模拟最后从大量样本中统计出结果的分布形态。放到充电负荷场景里逻辑非常直观每一辆电动汽车的“今天跑了多远”“几点到家”都可以看成一次随机试验。一次抽样就是一辆车的一天。抽1000辆车就模拟了一个小区1000辆车的充电行为再把这一天的过程重复1000遍相当于模拟了1000个“平行宇宙”里这1000辆车的行为差异。最后把所有“平行宇宙”的负荷曲线做个统计就能同时得到平均负荷曲线、95%分位数曲线、峰值负荷期望值这些能直接支撑工程决策的指标。这种做法有个很明显的优势不需要对充电行为做太多人为假设。你只要把各输入变量的概率分布定好剩下的事情全部交给抽样和统计模型的扩展性也很强——想加入快充桩、加入有序充电策略、加入V2G反向放电都只是在抽样环节增加新逻辑而已。1.3 蒙特卡洛用于充电负荷的总体框架整个计算框架可以拆成五个环节输入变量建模、单次抽样、负荷叠加、重复仿真、统计输出。有些教程会加入“车辆状态初始化”“出行链模拟”这些更细的模块那是往交通行为建模方向扩展了。对于用电负荷计算这个目标最核心的输入其实就是四个随机变量加一组固定参数日行驶里程、开始充电时间、起始SOC、充电功率等级以及电池容量、充电效率、百公里电耗这些常量。这里我先给一个整体流程图式的思路后面每一节再逐步展开先根据概率分布生成一辆车的行驶里程和回家时间算出它需要充多少电再把充电功率按时间轴叠加到负荷曲线上。所有车都处理完后一条仿真日的负荷曲线就诞生了。这个流程循环几百上千次最后求均值和分位数就得到了蒙特卡洛意义上的充电负荷结果。2. 模型输入先理清四类随机变量与固定参数2.1 日行驶里程对数正态分布与典型参数电动汽车充电负荷最核心的驱动变量是日行驶里程因为它直接决定了一辆车当天消耗了多少电量。大量交通调查数据表明私家车日行驶里程近似服从对数正态分布。所谓对数正态是指“行驶里程取对数之后服从正态分布”这比普通正态分布更符合实际——因为行驶里程不可能为负而且少数长途出行会造成一个很长的右尾。在MATLAB里用lognrnd生成样本时要注意它的输入参数是“对数空间”的均值和标准差不是原始数据的均值和标准差。常见的参考参数是lognrnd(log(40), 0.5)这个配置下中位数是40km均值约46km主体分布在15-80km之间。国内城市通勤数据可以在此基础上微调把log(40)改成log(35)或log(45)标准差保持在0.4-0.5即可。实际仿真中我还会把最大里程截断在200km左右因为纯电私家车的单日极限续航不会无限大不截断的话偶尔抽出一个300km的极端值会让充电时长显得离谱。2.2 开始充电时间回家时刻的混合正态分布充电起始时间通常取“到家时间”因为绝大多数私家车主回家后就会把充电枪插上。回家时间分布有一个显著特征傍晚到夜间有两个小高峰一个是18:00左右下班直接回家的人群一个是20:30左右外出活动结束后到家的人群。单一的正态分布拟合效果并不好用两个正态分布加权混合高斯混合更贴近实测数据。常见配置是主峰均值18:00、标准差60分钟次峰均值20:30、标准差45分钟主峰权重0.7。这里的时间都要换算成分钟制18:00就是第1080分钟20:30就是第1230分钟。这样建模还有个好处后续叠加负荷曲线时可以直接用分钟索引不用反复做小时和分钟的转换。2.3 充电功率、电池容量与充电效率的选择家用慢充场景下充电功率通常取3.5kW或7kW两个等级。7kW对应220V/32A的单相交流桩是目前小区私人桩的主流配置。如果是公共快充功率等级会跳到30kW、60kW甚至120kW以上但快充更多属于应急补电场景负荷计算时一般单独建模块处理。电池容量按车型取40-100kWh不等主流中型纯电车按60kWh处理比较合理。百公里电耗取15kWh/100km是个比较中庸的值SUV或冬季低温场景要上调到18-20。充电效率取0.9-0.95因为交流充电过程中AC-DC变换和电池内阻都会产生损耗电表端消耗的电量要大于真正充入电池的电量。这里有个初学者容易漏掉的点最终叠加到电网侧负荷曲线上的充电功率是“电表端功率”而计算充电需求时用的是“电池端能量”。中间差了效率系数。如果不做转换计算出的充电时长偏短负荷会被系统性低估。2.4 参数表速查与常见设置错误下面是我在做私家车慢充场景时常用的一组基准参数可以直接抄作业参数取值说明电动汽车数量500辆按小区配建规模调整电池容量60 kWh典型中型纯电百公里电耗15 kWh/100km冬季上调至18-20慢充功率7 kW220V/32A单相充电效率0.90电表端到电池端充电截止SOC90%避免满充过充日行驶里程分布lognormal(mulog(40), sigma0.5)截断在200km开始充电时间混合正态主峰18:00占70%次峰20:30占30%峰值时段和居民晚高峰重叠起始SOC扰动到家SOC再叠加±5%随机扰动模拟用户插枪时的状态差异参数设置最常犯的三种错误第一是把lognrnd(log(40), 0.5)误认为“日均里程是40km、标准差是0.5km”0.5是对数空间的标准差。第二是忽略充电效率导致负荷偏低。第三是让起始SOC和行驶里程脱钩出现“开了200km回家电量还剩80%”这种物理矛盾。第三点下面专门展开讲。3. 抽样与叠加完整算法的每一步推导3.1 单个车辆的充电能量需求计算从行驶里程到充电时长中间要过三关。第一关是算出当天行驶消耗的电量行驶耗电量 日行驶里程 / 100 × 百公里电耗假设抽到一辆车当天跑了40km百公里电耗15kWh那它就消耗了6kWh。第二关是推算插枪时的起始SOC。这里要让物理过程自洽车主早上出门时电池电量较高假设90%开了一天车消耗了上述电量回家时的剩余电量就是到家SOC 0.90 - 行驶耗电量 / 电池容量如果电池容量60kWh跑了40km消耗6kWhSOC大约下降10个百分点到家SOC约80%。我再叠加一个±5%的随机扰动用来模拟不同用户的充电习惯差异比如有的人剩余30%就充有的人剩余60%就充。第三关是计算需要充入的电量。按照“充到90%即停”的设定充电需求量 (0.90 - 到家SOC) × 电池容量注意这里有个细节充电截止SOC设90%是为了模拟多数用户不会每次都充满到100%的行为习惯而且锂电池在90%以上充电速率会明显下降一个晚上的停留时间通常无法完成最后那段的恒压充电。这个设定对结果的影响在于——它限制了单次充电电量的上限也间接约束了充电时长不会无限拉长。3.2 充电时长与跨天衔接的处理充电时长由充电需求量和充电功率共同决定充电时长(h) 充电需求量(kWh) / (充电功率(kW) × 充电效率)除以充电效率这个动作特别关键。比如充电需求量是40kWh7kW的桩如果不算效率时长是5.7小时考虑0.9的效率后变成了6.3小时。看起来只差半小时但在几千次抽样累计下峰值负荷和充电量总额都会出现系统性偏差。跨天衔接是新手最容易翻车的地方。假设一辆车22:30到家也就是第1350分钟插入充电枪计算出的充电时长是7小时即420分钟。从第1350分钟充到第1770分钟早已超出了1440分钟的一天边界。很多简化代码直接对1440取余把后半段负荷扔到凌晨3:20这其实是错误地假设了“充电功率在第2天0点前绝对停止0点后重新开始”。实际物理过程是充电枪一直插着功率连续存在。正确的做法是把充电区间切成两段当天第1350分钟到第1440分钟叠加一次次日第0分钟到第330分钟再叠加一次。在每日曲线模型里次日的片段就归到第二天曲线的开头。为了避免首日边界效应我通常会在仿真开始前先跑几天预热或者直接分析时跳过每条曲线最早的两个小时。3.3 从单辆车到一万辆负荷曲线的统计叠加单辆车的充电行为映射到负荷曲线上就是一个矩形波横轴是时间纵轴是充电功率。把500辆车的矩形波按各自的起始时间和持续时长放在同一张时间轴上求和就得到一条当天的总充电负荷曲线。这一步的本质是线性叠加前提是假设所有充电行为相互独立、充电功率不会因为同时充电而自动降额。这个假设在慢充场景基本成立——只要小区变压器容量没有到极限交流桩的充电功率基本稳定。如果考虑台区自动功率控制或有序充电调度模型就要在叠加逻辑里加入“功率限值反馈”那是另一套玩法。重复抽样K次之后我们手里有K条相互独立的日负荷曲线。对这K条曲线逐时间点求平均得到平均负荷曲线逐时间点求95%分位数得到“95%概率不会超过”的包络曲线。工程上平均曲线用于电量估算95%分位数曲线用于容量校核。3.4 为什么结果要取均值还要看分位数这一点我想单独强调。只看平均曲线会严重低估风险。假设平均峰值是1200kW看起来离变压器1500kW的容量还有余量但95%分位数峰值可能到了1450kW最坏情形甚至超过1600kW。对于规划决策真正需要回答的问题是“极端情况下会不会跳闸”而不是“平均情况下够不够用”。这也是蒙特卡洛方法比传统确定性计算有优势的关键确定性计算给一个数你不知道它代表平均水平还是保守水平蒙特卡洛给出整个分布你可以按需取均值、取P95、取最大值甚至计算“负荷超过变压器容量的天数占比”。后者的表述方式恰好是配电网运行风险评估里最需要的概率语言。4. MATLAB 实现完整可运行的仿真程序4.1 主程序结构与参数初始化我先把代码整体放上来然后逐段说清楚每个模块的作用。这段代码的主结构分四步定义参数、生成随机样本、逐日叠加负荷、统计输出。刻意没有用函数封装是为了让初学者能一行行看到数据怎么流动跑通之后再封装不迟。%% 参数配置区 clear; clc; rng(2024); % 固定随机数种子保证结果可复现 n_ev 500; % 电动汽车数量 n_sim 1000; % 蒙特卡洛抽样次数模拟天数 day_min 24 * 60; % 一天1440分钟 charge_p 7; % 慢充功率 kW eta 0.90; % 充电效率 cap 60; % 电池容量 kWh e100 15; % 百公里电耗 kWh/100km soc_max 0.90; % 充电截止SOC mile_max 200; % 日行驶里程截断上限 km %% 随机样本生成 % 日行驶里程对数正态分布截断到200km mile lognrnd(log(40), 0.5, n_ev, n_sim); mile min(mile, mile_max); % 到家时间双峰混合正态单位分钟 home_t zeros(n_ev, n_sim); mix_sel rand(n_ev, n_sim) 0.7; % 70%主峰 n1 sum(mix_sel(:)); home_t(mix_sel) normrnd(18*60, 60, n1, 1); home_t(~mix_sel) normrnd(20.5*60, 45, n_ev*n_sim-n1, 1); home_t round(min(home_t, day_min - 1)); % 最晚不超过23:59 % 到家SOC由行驶耗电反推再加扰动 drive_energy mile / 100 * e100; % 当天行驶耗电 kWh home_soc soc_max - drive_energy / cap - 0.05 * rand(n_ev, n_sim); home_soc max(home_soc, 0.10); % 下限保护 % 充电需求与充电时长 need_energy (soc_max - home_soc) .* cap; % 需要充入的电量 kWh charge_time_min round(need_energy ./ (charge_p * eta) * 60); % 分钟 %% 逐日叠加 load_matrix zeros(n_sim, day_min); % 预分配存储 for k 1:n_sim day_curve zeros(1, day_min); for i 1:n_ev ts home_t(i, k); % 开始充电时刻 te ts charge_time_min(i, k); % 结束充电时刻 if te day_min day_curve(ts:te) day_curve(ts:te) charge_p; else % 跨天分两段叠加 day_curve(ts:day_min) day_curve(ts:day_min) charge_p; day_curve(1:te-day_min) day_curve(1:te-day_min) charge_p; end end load_matrix(k, :) day_curve; end %% 统计输出 mean_curve mean(load_matrix, 1); % 平均负荷曲线 p95_curve prctile(load_matrix, 95, 1); % 95%分位数曲线 p05_curve prctile(load_matrix, 5, 1); % 5%分位数曲线 peak_mean max(mean_curve); % 平均场景峰值 peak_p95 max(p95_curve); % 高概率场景峰值 sim_ratio peak_mean / (n_ev * charge_p); % 实际同时率 t_axis (0:day_min-1) / 60; % 时间轴小时 figure; plot(t_axis, mean_curve, LineWidth, 2); hold on; plot(t_axis, p95_curve, LineWidth, 1.5, LineStyle, --); plot(t_axis, p05_curve, LineWidth, 1, LineStyle, :); xlabel(时间 (h)); ylabel(充电功率 (kW)); legend(平均负荷, 95%分位数, 5%分位数, Location, northwest); grid on;4.2 核心逻辑的逐段解读先看随机数生成的几个关键选择。rng(2024)这行最容易让人忽略但它极其重要——没有固定种子每次运行的随机样本都不同结果不可复现后面调试和写报告都会非常痛苦。固定的种子值可以随意指定2024只是我选的。home_t(mix_sel) normrnd(...)这一段是典型的矩阵索引赋值。mix_sel是逻辑矩阵为真的位置生成主峰正态样本为假的位置生成次峰样本。这里有一个小细节n1 sum(mix_sel(:))先把符合条件的个数算出来normrnd第三个参数必须和这个数量一致否则MATLAB会报维度不匹配。用逻辑索引配合逐类生成比在循环里逐个判断快得多。叠加部分最核心的是跨天分支的处理。te day_min时把充电需求拆成两段从ts到当天最后以及从次日0点到te-day_min。这比mod(te, day_min)的写法严谨得多。te-day_min这个值可能刚好等于0吗不会因为te day_min这个分支已经保证差值是正数。注意load_matrix是n_sim行day_min列的矩阵预先用zeros分配好。如果不预分配循环里每次load_matrix(k,:) ...都会触发矩阵扩容在n_sim上千、day_min上千的场景下性能会差到让人怀疑电脑坏了。预分配是最基础的MATLAB性能优化手段没有之一。4.3 性能优化方向与是否使用 parfor上面这段代码在普通笔记本上跑500辆车、1000次仿真大约需要几十秒到两三分钟完全可以接受。如果车辆数到几千、仿真次数到几千就有必要优化了。第一个优化方向是向量化叠加。用accumarray把每辆车的充电区间一次性映射到日负荷向量上可以去掉内层500次的循环。但代码可读性会明显下降我建议先把功能跑对再优化。第二个方向是并行计算。MATLAB的parfor可以把n_sim次日仿真并行跑起来每核处理一部分仿真理论上能快两三倍。但要注意并行池的随机数流问题——需要为每个worker单独设置随机数子流不然并行进程可能产生相同的伪随机序列。简单做法是parfor循环内部用RandStream.create(mlfg6331_64, Seed, k)创建独立子流。我的建议是不要一上来就优化。先用串行代码把业务逻辑验证清楚等模型稳定、需求明确后再考虑向量化和并行。早期优化往往是负资产尤其是当你想调整变量建模、增加新策略模块时简洁的串行代码改起来成本最低。4.4 输出图形与统计指标的说明代码最后画出的三条曲线里平均负荷曲线是“最常见的场景”95%分位数曲线是“比较恶劣的场景”5%分位数是“比较乐观的场景”。三条线之间的带状区域直观反映了充电负荷的随机波动范围。sim_ratio算出的同时率很有意思——基于上面这组参数通常落在0.35到0.55之间远高于很多规划文档里拍的0.2、0.3。这说明充电负荷的同时性比想象中强得多尤其晚高峰时段集中率非常高。这个数字本身非常值得在规划讨论中拿出来说事。如果想和其他负荷叠加比如和居民基础负荷求合可以把mean_curve按15分钟间隔聚合reshape(mean_curve, 15, [])然后对每列求平均或求最大得到的96点曲线就可以和常规负荷数据对齐了。注意这里reshape的前提是一天1440分钟恰好能被15整除这是刻意选分钟为单位带来的便利。5. 收敛性检验蒙特卡洛到底要抽多少次5.1 收敛判据怎么定蒙特卡洛的一个经典问题抽多少次才算够这个没有固定答案取决于你要什么指标的精度。峰值负荷、平均电量、95%分位数不同指标的收敛速度不同。实用的判据是看关键指标随仿真次数的变化趋势。具体做法固定随机数种子把仿真次数从50依次加到200、500、1000、2000每次记录峰值负荷的期望值和P95值观察这些数值是否趋于稳定。如果从1000次到2000次峰值负荷变化不到1%说明抽样次数基本够用。另一个辅助判据是看负荷曲线的“毛刺程度”。次数太少时曲线尤其是峰值段会有明显的锯齿状抖动因为个别车辆的极端充电行为没有被足够多的样本平均掉。曲线变得平滑本身就是收敛的视觉信号。5.2 一组实际收敛实验的观察我按第4节的代码分别跑50、200、500、1000、2000次观察到典型的趋势是这样的50次时峰值在1350kW上下跳动前后两次运行可能差出80kW以上曲线的峰段锯齿很重200次时峰值降到约1300kW波动范围收窄到±30kW左右500次以后均值峰值稳定在1250-1270kW区间到1000次和2000次峰值几乎不变差异小于10kW。95%分位数峰值的收敛速度会慢一些大约需要1500次以后才明显稳定。峰值负荷的波动范围收窄速度快于平均值这是蒙特卡洛的典型特性——均值收敛快尾部极端分位数收敛慢。如果你只关心平均负荷和总充电量500次就够如果要用P95曲线做变压器容量校核建议至少跑到1000次以上。5.3 提高收敛效率的配置技巧想提高收敛速度可以从方差缩减入手其中最简单的技巧是用“公共随机数”。具体做法是把mile和home_t的随机种子固定后在同一个随机样本集上比较不同方案比如不同充电功率配置、不同充电策略这样两组结果的差异主要来自方案本身而不是样本波动。这在做“有序充电对比无序充电”这类策略评估时尤其重要能把对比实验的信噪比明显提高。另一个技巧是分层抽样。把日行驶里程按短途、中长途、长途分成三层每层按比例抽取定额样本。这样能保证长途这种小概率但高影响的场景不被抽样波动淹没。实现起来稍麻烦但对关注极端尾部的场景很有价值。时间步长的选择也值得提一句。整篇代码用的步长是1分钟这对私家车充电已经足够精细。如果只想看整体曲线形态15分钟步长也能用充电时长取整到15分钟即可计算量直接降到原来的十五分之一。至于要不要用秒级步长我认为没有必要——充电功率是一个持续数小时的过程秒级分辨率不会增加有效信息只会拖慢计算。6. 结果能干什么用以及我踩过的坑6.1 从负荷曲线到配电网评估拿到平均曲线和P95曲线之后最直接的应用是和小区现有基础负荷曲线做叠加。晚上8点前后充电负荷和居民生活用电高峰叠在一起叠加后的峰值就是变压器容量校核的依据。进一步可以做电量层面的评估平均日充电电量等于平均负荷曲线对时间积分再除以1000得到的单位是kWh。用这个数乘以电价就能估算充电运营成本乘以电动汽车数量可以推算区域充电总需求。这类分析对充电桩运营商的投资回报测算非常有用。再往前一步把模拟出的负荷曲线输入潮流计算工具可以评估配电网节点电压偏移和线路负载率。这是电动汽车对配电网影响研究的常规路径——先用蒙特卡洛算出负荷再代入配电系统做确定性或概率性潮流。只要把输出的负荷曲线整理成标准时序数据很多电力系统分析软件都能直接接收。6.2 随机模型与有序充电策略评估蒙特卡洛模型最大的扩展价值在于评估有序充电策略。无序充电的模拟方法是“到家即充”有序充电只要在叠加环节加一层控制逻辑比如延时充电策略要求充电时段从23:00开始谷价充电策略要求充电过程避开晚高峰。对比方法非常简单——用同一组随机样本分别跑“无序充电”和“谷价充电”两种场景得到两条负荷曲线和两组峰值指标一看便知削峰效果到底有多少。因为用的是同一组随机样本对比结论不会混淆“策略差异”和“样本差异”这个优势前面提过实际操作时你会真正体会到它的好。如果想加入V2G只需要在叠加逻辑里给部分车辆增加“放电区间”把放电功率的负值叠加到曲线上。基于那组随机样本还能统计“哪些车在哪些时段有可放电量”这正好对应了V2G可用容量评估的需求。模型框架不变核心只是扩展车辆行为模块。6.3 MATLAB 实现中的常见坑与排查清单最后把我实际踩过的坑集中列一遍按“症状—原因—解决”的格式写方便对照排查。症状原因解决方法每次运行结果都不一样没固定随机数种子代码开头加rng(固定值)充电时长明显偏短充电效率被忽略能量需求除以效率再算时长个别车辆充电时长异常大行驶里程未截断用min(mile, mile_max)限制凌晨0点附近出现突兀的负荷跳变跨天用mod取余充电区间被错误拆分按“当天段次日段”两段分别叠加负荷曲线锯齿感很强仿真次数太少加到1000次以上或检查收敛性程序运行很慢循环内动态扩充数组预先zeros分配load_matrixnormrnd报维度错误混合正态逻辑索引后数量没匹配用sum(mix_sel(:))先统计数量峰值同时率低得不合理所有车近半夜才开始充电检查home_t分布参数是否合理这里想单独说下标红的那种情况。负荷曲线在零点前后出现“一刀切”的跳变很容易被误判成真实负荷特征实际上纯粹是边界处理错误。判断方法也很简单把仿真次数调小到几十次单条曲线拉出来看如果总有车辆在23:00以后回家但充电曲线在0点戛然而止基本就是跨天逻辑出问题了。还有一个隐蔽的坑藏在四舍五入里。round把充电分钟数取整单次误差最大30秒500辆车1000天累积下来总充电量的误差可以忽略。但如果用fix或floor取整会系统性低估充电时长每辆车少算最多1分钟峰值位置的统计就会微偏。遇到这类问题不用慌统一用round即可。参数校验这件事也值得多说一句。跑正式仿真前我会先用一个很小的规模做单元测试比如只抽5辆车手动心算每辆车的到家时间、充电时长、跨天与否再和代码输出对比。这招虽然土但能在一分钟之内发现绝大多数逻辑错误。等小规模测试无误后再放大到500辆、1000次基本不会跑出让你半夜怀疑人生的结果。
阅读完成 · 觉得有帮助?
咨询建站