ARTICLE DETAIL

资讯详情

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

基于蒙特卡洛抽样的电动汽车充电负荷计算MATLAB实现

基于蒙特卡洛抽样的电动汽车充电负荷计算MATLAB实现 做电动汽车充电负荷计算相关课题的同行应该都有过这种体会电网侧要评估大规模电动车接入后的影响但手头既没有真实充电桩数据又不想用那种“拍脑袋定一个同时率”的粗糙做法那么蒙特卡洛抽样基本是绕不开的第一选择。最近我把基于蒙特卡洛抽样的电动汽车充电负荷计算完整代码在MATLAB里跑通了也调出了比较理想的效果曲线这篇就把整个实现过程、模型假设、代码思路以及调试中踩过的坑全部摊开讲。内容面对的是正在做充电负荷预测、配电网规划或者电动汽车入网影响分析的工程师和研究生哪怕你之前没接触过蒙特卡洛按着这套思路和代码框架也能搭出一版可用模型。先说结论这套方案适合做“规模化电动汽车集群负荷评估”能模拟任一时刻全网/台区范围内的充电功率需求曲线输出结果包含逐时负荷均值、波动范围以及不同渗透率下的对比完全可以直接嵌入到后续的配网潮流计算或容量规划里。1. 项目背景与整体思路1.1 为什么偏偏选蒙特卡洛抽样电动汽车充电负荷和常规空调、照明负荷的最大区别就是它的“用户行为主导”属性。一辆车几点开始充电、前一天跑了多少公里、回家后还剩多少电这些参数几乎没法用确定性公式描述只能靠概率分布去刻画。蒙特卡洛抽样就是干这件事的从已知的概率分布里反复抽取随机场景每个场景生成一组充电行为叠加出总负荷最后用大量场景的统计结果逼近真实期望。这比传统的“负荷同时率”法高明在两个方面。第一它能还原负荷曲线的自然形态尤其是傍晚下班后的充电高峰叠加效应这是同时率法给不出来的第二它能输出负荷的波动范围也就是置信区间这对评估配电网设备过载风险特别重要。实际计算中单次抽样可能有很大的偶然性但上千次抽样后的均值会收敛到稳定的期望曲线这就是蒙特卡洛大数定律的直观体现。1.2 蒙特卡洛方法的底层逻辑蒙特卡洛的思想可以类比成“用海量实验逼近真相”。好比你想知道一万个人随机到达车站后等车人数的分布最简单可靠的办法不是列方程而是真的模拟一万个人的到达行为统计每个时刻的人数。充电负荷计算同理每辆车就是一个随机样本样本里有起始充电时间、日行驶里程、电池容量、充电功率这些属性抽样一次就是生成一辆车的充电曲线把所有车的曲线叠加就是某一天的负荷曲线。关键点在于单次抽样只是众多个体行为的一种组合并不代表典型情况。所以要重复抽取N次比如500到2000次每次代表一天把每天的负荷曲线做平均得到的就是期望负荷曲线同时统计每一天对应的曲线波动范围就可以画出置信带。整个流程核心只有三步构建输入变量的概率模型、逐车抽样形成单日负荷、多次重复后做统计分析。MATLAB在这套流程里最大的优势是随机数生成函数丰富、矩阵运算快、画图方便调试和结果可视化都不需要额外工具。1.3 系统总体框架我搭的整体计算框架分四层参数层、场景层、计算层、统计层。参数层定义电动汽车保有量、充电桩功率、电池容量、各类概率分布参数场景层负责对每辆车抽样生成起始充电时间和初始SOC计算层按照时间序列累加每一时刻的充电功率统计层多次循环后计算均值、标准差、分位数并出图。这四层各司其职也方便以后扩展。比如想把慢充换成快充桩只需要修改参数层的充电功率分布想加入有序充电策略只需要在计算层增加一个控制逻辑模块不影响其他部分。项目实际代码也是按这个结构组织的函数边界清晰后续维护和改参数都很顺手。2. 充电负荷计算的关键模型搭建2.1 影响充电负荷的三大随机因素做过几轮仿真之后我总结出对负荷曲线影响最大的三个随机输入起始充电时间、日行驶里程、充电功率。起始充电时间决定负荷曲线的相位什么时候出现高峰完全由它决定日行驶里程决定充电需求电量也就是每辆车充多久充电功率决定单车的充电速率这个参数还直接影响配电网的瞬时冲击。除此之外还有两个次要因素电池容量和充电效率。电池容量理论上也可以是随机变量因为不同车型差异很大但为了控制复杂度不少模型里把它设成几种典型值的离散分布充电效率更多是作为修正系数出现在功率转换环节不是核心随机源。实际建模时应该把主要精力放在前三个变量上因为它们对结果的影响是决定性的。2.2 概率分布选择与参数确定起始充电时间的分布不同研究用的模型不太一样。主流文献里常用正态分布均值在18点到19点之间标准差1到3小时这对应的是“下班回家后顺手插枪充电”的主流行为模式。有些精细化研究会把工作日和周末分开建模或者考虑快充站的随机到达过程但经典版本用截断正态分布就够用。日行驶里程更贴近对数正态分布因为大部分车每天跑几十公里少数车跑上百公里右拖尾特征非常明显。MATLAB里直接用lognrnd函数就可以抽取。下面是我常用的参数表随机变量分布类型参数设置备注起始充电时间截断正态分布均值18.5h标准差2h截断到16h~24h对应晚归高峰日行驶里程对数正态分布均值40km标准差对应ln分布参数城市通勤为主电池容量离散正态分布40/60/80kWh占比约3:5:2模拟不同车型充电功率离散分布7kW慢充为主少量50kW快充慢充为主场景有人会纠结参数的精确度我的建议是初期不用追求完美关键是要让模型行为符合直觉。比如均值参数改了之后高峰时段确实发生了对应的移动这就说明模型是敏感的、合理的。后续如果拿到真实充电桩数据直接替换分布参数做标定即可。2.3 充电行为约束与边界条件模型不能只抽样不管过程还得加上几条物理约束否则会出现“充满了还继续充”这种不合理的曲线。第一是SOC上下限约束车载电池一般不允许低于10%充电目标通常设到90%左右所以实际可充容量按电池容量的80%计算。第二是充电结束条件充电时长等于需求电量除以充电功率达到目标SOC就停止充电不允许超出。第三是起始SOC与日行驶里程的耦合约束。起始SOC不应该独立抽样而是由前一天行驶里程推导起始SOC等于前一天结束时的SOC减去当天行驶消耗。这个耦合关系我一开始漏掉了导致大量车出现“电量接近满的还在充电”的假象曲线失真很严重。处理完这些约束之后充电功率曲线在时间轴上的分布就自然呈现出一个特点大量车集中在晚间开始充电充电过程持续2到8小时不等负荷曲线从前一晚的18点开始爬升到20点到22点之间达到峰值后半夜逐渐回落。3. MATLAB实现流程与核心代码拆解3.1 整体算法框架MATLAB程序的执行流程我用一个主脚本加若干个函数来组织。主脚本负责设置参数、循环调用单日场景函数、汇总统计结果函数层面包括场景生成函数、单个车辆充电曲线函数和日负荷叠加函数。这么设计的好处是后期如果要把慢充换成有序充电只需要替换或修改场景生成函数主脚本基本不用动。主循环结构用for k 1:N每轮循环做三件事抽样生成一批车的参数、累加每辆车的充电功率时间序列、保存这一天的总负荷曲线。N的值我试过500、1000、2000三档最后选的是1000次。原因后面会在收敛性部分细说。3.2 随机场景生成代码场景生成是核心中的核心。起始充电时间我直接用了normrnd生成再截断日行驶里程用lognrnd电池容量用randsample按权重抽取充电功率也按离散概率抽取。截断的逻辑不复杂生成后把超出范围的样本裁剪到上下限即可代价是个别样本会堆积在边界但只要截断点离分布中心足够远对结果影响可以接受。% 起始充电时间截断正态分布小时 t_start normrnd(mu_t, sigma_t, N_car, 1); t_start min(max(t_start, 16), 24); % 日行驶里程对数正态分布km mileage lognrnd(log(40), 0.5, N_car, 1); % 抽取电池容量和起始SOC capacity randsample([40;60;80], N_car, true, [0.3;0.5;0.2]); energy_consumed mileage .* 0.18; % kWh/km soc_start 0.9 - energy_consumed ./ capacity; soc_start max(soc_start, 0.1);这段代码里最值得注意的就是randsample按权重抽样电池容量数组以及SOC起始值由行驶能耗反推这两行实际上决定了充电需求量的真实度。0.18 kWh/km这个百公里电耗20度左右的能耗系数是可调的如果模拟的车型偏微型车可以下调到0.12到0.15。3.3 负荷累加与迭代收敛逻辑有了每辆车的起始充电时间、SOC和充电功率就能叠加载荷了。先把时间轴切成1440分钟或96个15分钟点然后把每辆车的充电区间映射到对应的时间索引上把功率加进去。向量化可以这么写先确定每辆车充多少小时再根据起始时间计算跨越的索引范围逐车累加。t_end t_start charge_duration; % 充电结束时间小时 for i 1:N_car idx_start round((t_start(i) - t0) / dt) 1; idx_end round((t_end(i) - t0) / dt) 1; idx_end min(idx_end, T); P_day(idx_start:idx_end) P_day(idx_start:idx_end) P_charge(i); end逐车循环在小规模下很快但如果车数量超过几万台可以用histcounts配合权重一次性累加性能提升明显。收敛性方面我统计了不同迭代次数下的均值曲线标准差500次时波动还有约3%1000次以后波动降到1%以内所以取1000次作为默认配置既保证精度又不至于跑太久。4. 仿真结果与分析4.1 充电负荷曲线的典型形态用默认参数跑完1000次仿真后输出的典型日负荷曲线是很有辨识度的下午16点前几乎可以忽略不计17点后开始爬坡19点到21点之间出现明显峰值峰值后缓慢下降凌晨1点后逐步回落到低位。这个形态符合大多数文献和实测数据的规律本质上就是用户下班回家充电行为的集中反映。我测试的算例是5000辆电动汽车、慢充7kW为主、电池容量以60kWh为主。这个配置下晚高峰总负荷峰值大约在22MW左右。如果单纯按5000辆车乘以7kW得到35MW会觉得电网早上天天过载但实际因为起始充电时间的分散性和SOC差异叠加后峰值远低于装机总和。这正是蒙特卡洛模型的价值——它还原了“同时率”的真实构成逻辑而不是拍一个固定系数。4.2 渗透率与充电功率对曲线的影响参数敏感性测试我做了两组。第一组固定其他参数只改变电动汽车数量从1000辆逐步加到10000辆负荷峰值基本线性增长但曲线的形状不变峰值依然出现在晚间20到21点这说明起始充电时间的分布对峰谷形态起决定性作用渗透率只改变纵轴尺度。第二组只改变充电功率构成把一部分7kW慢充替换成50kW快充峰值明显前移且冲击变大原因很简单快充功率高同样电量能在更短时间内完成大量车会在更集中的时间窗口内形成更陡峭的功率峰。这对配电网的影响尤其大变压器短时过载的风险比慢充场景高很多。4.3 结果可信度评估仿真结果不能只信一次曲线我习惯把1000次迭代中每一天的负荷曲线的均值和±1倍标准差一起画出来。均值曲线周围会形成一个“走廊”走廊宽度代表了不确定性。这批算例中晚高峰时刻的标准差大约在峰值的8%到12%之间说明这个时段的负荷随机波动比较明显而深夜时段的走廊则窄得多因为大部分车已经充满停止充电随机性主要集中在前半夜。这种不确定性信息对实际应用特别有价值。规划人员在评估变压器容量时不仅要看均值是否越限还要看最坏情况下比如95%分位数是否越限。我建议在最终输出中加上P95曲线作为保守决策的参考这个操作在MATLAB里用prctile(P_all, 95, 1)一行就能搞定。5. 常见问题与调试心得5.1 随机数种子与结果复现蒙特卡洛仿真第一件要养成习惯的事就是固定随机数种子。如果不加处理每次运行结果都会有细微差别写论文时数据对不上改参数前后也难以比较。早期我吃过这个亏改了个功率参数实验结果变化太大以为是逻辑错误后来发现只是随机波动。解决办法很简单脚本开头加一句rng(2024); % 固定随机数种子这样保证同参数下结果完全可复现改一个参数再跑也只看得到真正由参数引起的变化。实际研究中我会在种子位置留一个变量批量参数扫描时按组序号动态改种子保证每组实验独立可复现。5.2 仿真速度优化1000次迭代、每轮5000辆车代码最初跑一轮要将近三分钟瓶颈在逐车时间序列累加的那层循环上。优化手段有两种一是把dt从1分钟改成15分钟时间点从1440降到96个计算量直接降一个量级二是对充电起始时间做归并同一时刻开始的车辆可以合并成一组功率叠加避免逐车循环。优化后同样计算规模只需要10到20秒速度提升非常明显。如果车规模再大还有一个思路是预先生成场景矩阵再用单次矩阵运算完成累加MATLAB对矩阵运算的优化远好于循环但内存占用会上升需要权衡。5.3 参数敏感性踩坑记录调参过程中的一个大坑是起始SOC取值过于理想。早期版本里我把起始SOC设为固定0.9结果单日电量需求全部来自于行驶里程虽然曲线形态合理但把电池容量曲线上整体抬高了高峰更加明显。实际中很多人开完车并不会立刻充满第二天接着开所以SOC起始值的随机性必须通过行驶里程耦合进来。另一个坑是截断正态分布带来的边界堆积。把起始充电时间截断在16到24点后16点和24点附近的样本明显增多这是我后来观察直方图发现的。解决办法是把正态分布均值设置在18.5标准差控制在2小时以内这样截断区离均值较远堆积问题基本可以接受。常见问题可能原因解决建议结果每次运行都不一样未固定随机数种子用rng(seed)固定种子曲线出现双峰快充和慢充混用时起始时间分布不匹配分开建模分别抽样后叠加峰值过高失真忽略SOC上限约束或起始SOC恒定用行驶里程反推起始SOC深夜仍有充电负荷充电时长未截断超量充电加充电结束时间约束运行太慢时间粒度太细且循环累加改用15分钟粒度并向量化做这套代码最大的体会是蒙特卡洛抽样本身并不难难得是把行为模型建得“像那么回事”。概率分布参数选择是否合理、行驶里程与SOC是否耦合、充电结束条件是否严密任何一个环节粗糙了最终的负荷曲线都会在不经意的地方露出马脚。建议你拿到代码后先跑一遍默认参数再把起始充电时间均值改成22点试一次你会立刻看到峰值后移那种“模型对参数有正确响应”的感觉是验证代码逻辑最有效的手段。后面如果想继续扩展可以考虑加入温度对能耗的影响、节假日与工作日的行为差异甚至把蒙特卡洛生成的负荷序列直接喂给潮流计算模块做配电网的时序概率评估这套框架都留好了扩展口子。
返回列表