ARTICLE DETAIL

资讯详情

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

充电负荷空间可调度性下分布式电源与充电站联合配置

充电负荷空间可调度性下分布式电源与充电站联合配置 1. 为什么“分布式电源 充电站”必须放在一起规划做电动汽车充电站规划的人迟早会撞上一个尴尬的问题充电站建好了配电网却“喂不饱”。尤其当分布式光伏大范围接入之后白天出力高峰和傍晚充电高峰完全错开配电网要么在中午面临倒送过压要么在晚上面临重载低电压。单独规划充电站不管怎么选址定容都只能被动挨打单独规划分布式电源又完全不考虑充电负荷的时空分布规律最后两个方案叠加在一起甚至可能互相对着干。这个项目标题的核心词是“联合配置”说白了就是在同一个优化模型里同时决定分布式电源在哪装、装多大以及充电站在哪建、建多少容量。这么做的好处不用多说让电源跟着负荷走或者让负荷去适配电源两边彼此协调最终目标是全系统综合成本最省、运行最稳。但真正有意思的地方其实是标题里那个容易被忽略的限定语——“充电负荷空间可调度特性”。这一下子把问题的复杂度拉高了一个维度也把一个普通的两层规划问题变成了一个需要考虑负荷转移行为的优化问题。很多人第一次看到“空间可调度”会有点懵我换个说法你就明白了。传统规划里充电负荷是“在哪建站就在哪充电”站址定了负荷就钉死在那了但现实中电动汽车用户是有选择权的——A 站排队长、电价高用户可能就去 B 站充。这种负荷在不同地理位置的充电站之间转移分配的能力就叫空间可调度性。更直白地说充电负荷不是一成不变的刚需负荷而是带有一定弹性、可以跨节点、跨区域“搬家”的柔性负荷。这个特性用好了能极大缓解局部电网压力用不好则会让某些规划方案刚落地就过载。那这篇博文就来把这个项目的思路、数学建模、Matlab 实现和调试经验从头到尾捋一遍。适合正在做配电网规划、电动汽车充电站布局研究的学生和工程师也适合那些想把“可调度性”这只潜力股纳入规划的从业者。下面所有内容都基于我实际跑通这个模型的经验代码框架、坑点都会给到你可以直接移植到自己的项目里改。2. 核心数学模型解构从目标函数到约束条件2.1 目标函数不止是“投资最少”这么简单联合配置模型的第一件事就是把成本函数立起来。我见过不少初稿只考虑投资成本结果优化出来电源全建到最便宜但没人用电的地方充电站全建在负荷中心但电网改造费高得离谱。这个项目里目标函数至少应该包含四块分布式电源的投资与运维成本光伏、储能如果有的单位容量投资成本、年运维费率充电站的建设与设备成本包括变压器增容、充电桩数量、场地费用折算网损成本规划后的典型日网络损耗折成年费用电压越限惩罚或运行风险成本这个容易被遗漏但它直接关系到规划方案能否被调度部门接受。把所有成本折算到年值后再做加和单位统一成万元/年这是规划类问题的通用做法。需要注意的是贴现率 r 和寿命周期 n折算公式是A P * r*(1r)^n / ((1r)^n - 1)别小看这一步光伏寿命 20 年、充电站设备寿命 15 年不折算直接比较投资结果会严重失真。2.2 约束条件每条约束都有物理含义这里我按工程习惯把约束分成三类每条都讲清楚为什么必须有。第一类配电网运行约束。DistFlow 潮流方程是基本盘这个项目里我建议用二阶锥松弛后的 DistFlow 线性化形式因为你要反复迭代求解非线性潮流会让问题变得极其难解。对应节点功率平衡P_inj,i P_DG,i P_cs,i - P_load,i - P_ch,i Q_inj,i Q_DG,i - Q_load,i同时要有节点电压上下限约束一般取 0.95~1.05 p.u.以及支路电流限额。这里有个隐蔽的坑考虑空间可调度后充电负荷P_ch,i变成了变量它会反过来影响潮流所以在约束里千万不能把它当常量写死。第二类充电站与可调度负荷约束。这是整个模型的灵魂。具体拆开是这么几条每个充电站的充电负荷总需求等于区域内电动汽车总充电需求数学上就是所有站点的充电量之和要覆盖总需求站点 i 的充电负荷必须在它的额定容量范围内即0 P_ch,i N_i * P_rated其中N_i是充电桩数量P_rated是单桩额定功率空间可调度性的量化表达通常用一个“转移比例系数”限制负荷能在多大范围内移动。比如用户愿意接受的最大跨站转移比例为 30%那站点 j 最多能向站点 i 转移0.3 * D_j的负荷这个系数一般通过问卷调查或交通流模拟数据定我第一次做的时候拍脑袋填了 0.5结果优化出来的总成本低得离谱仔细一看是负荷全塞到离电源最近的那个站去了完全不成立。第三类分布式电源安装约束。每个节点的 DG 安装容量有上限总安装容量受土地资源和接入点数量限制。这块相对常规但要注意 DG 渗透率约束在最小负荷方式下DG 总出力不能超过系统总负荷的一定比例否则会出现倒送潮流这在分布式光伏占比高的场景是硬约束一定不能漏。2.3 求解策略为什么我选 YALMIP CPLEX 而不是手写启发式算法模型建完之后下一步就是求解。标题里虽然写的是“Matlab 代码实现”但具体配套什么求解器、什么建模语言选择空间很大。我在这项目里用的是YALMIP 建模 CPLEX 求解 MILP原因有三二阶锥松弛后的问题可以直接喂给 CPLEX 这类商业求解器收敛性和全局最优性有保障YALMIP 的语法简洁调试约束条件时能逐条检查模型是否构建成功比手写单纯形法或自己实现内点法靠谱得多学术论文评审和工程交付通常都接受“求解器求解”的路径用启发式算法反而容易被质疑全局最优性。当然如果你没有 CPLEX 授权用 Gurobi 或者开源免费的 SCIP 也行YALMIP 在接口层是透明的换求解器基本不用改模型代码。另外有时会遇到二阶锥松弛不够严格的问题出现“假最优解”解决办法是引入电压幅值的辅助约束或者改用割平面法迭代收紧核心节点的电压边界。3. 充电负荷空间可调度性的建模这块是模型价值的核心3.1 可调度性从哪来用户选择的时空逻辑要把“空间可调度”从概念变成约束首先得理解它背后的行为逻辑。电动汽车用户的充电选择大致受三个因素驱动充电价格、排队时间、充电站与目的地的距离。这意味着即使已经规划好了几个站点实际充电量在每个站的分配也不是定死的。比如城东站的充电价格每度贵两毛那住在城西的用户大概率会选择去城西站充但如果城西站排队时间太长又会有一部分用户宁可多付点钱去城东。在规划模型中我们没办法仿真每辆车的决策过程但可以用一个集合约束来表达这个宏观结果总充电需求是刚性的但分配到各站点的量是柔性的且受最大转移距离、转移比例、站点容量三层限制。我实现的时候没有用复杂的 Logit 模型去刻画用户选择概率而是先把问题简化成“可转移负荷比例系数”。这样处理便于线性化后面你如果想精细化可以把这个系数替换成从交通 OD 分析得到的转移成本矩阵模型结构不需要动。3.2 模型里的三种可调度场景按电动汽车发展阶段的差异空间可调度约束有三种典型配方我建议你根据手头场景的成熟度来选。场景一充电需求约束到区域的总体平衡。适用于城市尺度规划比如把整个城区划分为若干块总需求必须满足但不限制各站之间的转移比例。这种最宽松可调度性最强优化结果成本最低但实际落地的可行性欠佳——你真以为用户会从城东跨半个城市去城西充电吗场景二带最大转移距离约束的站点间平衡。这是我在项目里实际使用的配方。每个站点周围定义一个服务半径负荷只能转移到半径覆盖范围内的站点配合转移比例系数一起约束。这个配方在数学上依然线性但求解效率会有所下降因为需要生成“可转移对”列表在大规模系统里会产生大量二进制变量。场景三计及实时电价响应的时空耦合约束。这是最复杂的版本充电站的负荷不只是空间上可迁移还会因为分时电价在时间上转移。这就变成了空间和时间双向耦合的约束模型规模会爆炸式增长。这个项目标题没提时间维度所以我最终没有用这个但你如果研究方向是“充电负荷时空可调度性”就得做好准备。我的建议是先用场景二跑通整体流程再根据审稿意见决定要不要加时间维度。% 伪代码展示可调度约束的 YALMIP 表达 P_ch sdpvar(N_bus, T, full); % 各节点充电功率变量 D_total sum(D_ev); % 区域内总充电需求 Constraints [Constraints, sum(P_ch, 1) D_total]; % 总体供需平衡 % 最大转移比例约束站点 i 的充电负荷不能低于其本址需求*(1-alpha)也不能高于本址需求*(1beta) for t 1:T for i 1:N_cs Constraints [Constraints, P_ch(i,t) (1 - alpha(i)) * D_ev(i,t)]; Constraints [Constraints, P_ch(i,t) (1 beta(i)) * D_ev(i,t)]; end end这里有个细节值得单独说D_ev(i,t)是站址所在节点的“原生充电需求”也就是不考虑跨站转移时该站本来就该承担的量。alpha和beta的取值不是对称的——用户愿意从本站转移到其他站的比例跟愿意从其他站转移到本站的比例技术上应该有差别但在数据不充分的前提下我取对称值即两者都等于 0.3。工程上这个值取 0.1 到 0.4 之间比较常见取值过大会出现离谱的“负荷搬家”现象。4. Matlab 代码实现工程化的分模块结构4.1 代码框架总览很多学生拿到这类代码最头疼的是读不懂整体结构。这项目里的 Matlab 代码我按功能拆成了七个文件每个文件职责单一调试或二次开发都方便。你不需要把所有代码都揉在一个脚本里那不是给人看的是给编译器看的。main.m主入口初始化参数、调用建建模型函数、触发求解、输出结果表data_load.m读取配电网系统参数、DG 候选位置、充电站候选位置、负荷曲线数据build_network.m构建 DistFlow 潮流方程的系数矩阵形成导纳矩阵和支路索引表build_optim_model.m核心建模函数声明变量、写目标函数、填约束条件solve_model.m调用 YALMIP 的optimize函数配置求解器参数postprocess.m结果整理计算各节点电压分布、DG 出力、充电站负荷分配结果plot_results.m出图规划结果可视化。我强烈建议你的主脚本里不要直接写具体的数据输入用独立的data_load.m来管理。因为这类项目的数据可能在几十个版本之间来回改每次改完跑一遍如果输入数据散落在主脚本的角落里找问题能找到让你怀疑人生。4.2 核心建模代码解读建模文件是整个项目的核心我摘几段实际代码出来讲讲每个变量的物理含义你要在心里有数不然后面调周期约束或者做敏感性分析时根本不知道该动哪里。变量声明部分% 决策变量 P_DG sdpvar(length(candidate_dg), T, full); % DG 出力连续变量 X_DG binvar(length(candidate_dg), 1); % DG 是否安装的 0-1 变量 X_CS binvar(length(candidate_cs), 1); % 充电站是否建设的 0-1 变量 N_CS intvar(length(candidate_cs), 1); % 每个站的充电桩数量整数 P_ch sdpvar(length(candidate_cs), T, full); % 各站充电功率变量注意N_CS用了intvar因为充电桩数量必须是整数这是 MILP 中“整数松弛”最容易出问题的地方。有的同学图省事直接把N_CS设成sdpvar连续变量最后松弛出来的结果可能是 7.5 个桩物理上完全说不通。如果你确实希望避免整数变量拖慢求解速度可以保留连续变量但要在后处理环节做取整并重新校验所有约束是否仍满足。目标函数部分% 年折算投资成本 invest_cost sum(X_DG .* DG_capex * CRF_DG) ... sum(N_CS .* CS_capex_per_unit * CRF_CS); % 年运维成本 om_cost sum(sum(P_DG)) * DG_om_rate ... sum(sum(P_ch)) * CS_om_rate; % 网损成本通过节点注入功率计算线损 loss_cost sum(sum(I_branch.^2 .* R_branch)) * loss_price * T_hours; Objective invest_cost om_cost loss_cost penalty_voltage;关于网损的计算这里是用支路电流平方乘电阻求的有功损耗。如果你用 DistFlow 的线性化形式支路电流需要用节点电压差和支路阻抗推算注意单位一致功率是 kW电价是 元/kWh时间单位要折算成年小时数。4.3 几个决定求解成败的工程技巧这一小节的坑我基本都是被现实教育过的回忆起来还有点肉疼。第一个是候选节点编号的映射问题。配电网系统的节点编号跟你在模型里用的变量下标经常不是一个东西。IEEE 33 节点系统节点编号 1~33但你可能只允许在节点 5、12、18、22、30 装 DG在节点 8、15、25 建充电站。如果你在约束里直接用循环变量i去索引系统节点很容易写出越界或者错位的约束。我建议在建模之前先构造一个候选节点表完整记录“候选编号 - 系统节点编号”的映射关系所有模式都用映射后的索引。第二个是 sdpvar 变量维度对不齐的问题。YALMIP 对维度检查很严格但报错信息有时候不太直观。常见的一种情况是把维度N_bus x T的变量和N_cs x T的变量直接相加报错是“Inner matrix dimensions must agree”。这种错误百分之百是模型设计时没有区分节点数和站址数。充电站只建在少数候选节点上其他节点的充电功率是 0但潮流平衡方程是每个节点都要写的所以你要么把P_ch扩展到全节点维度非候选点为 0要么做重映射。我在早期版本选择了后者后处理时发现遍历节点容易漏后来干脆把P_ch声明成N_bus x T约束里只允许候选节点非零其他位置显式约束为 0。这样代码啰嗦了一点但调试友好度大幅上升。第三个是求解器参数调优。模型规模一大直接用optimize求解可能要跑很久。我实际使用中会把mipgap设成 0.011% 的间隙就接受求解时间能从半小时降到几分钟。“算出来的不是最优解怎么办”这个担忧其实没必要——规划问题的数据本身就有很大的不确定性百分之零点几的成本差距在工程上完全可接受。另外如果遇到求解器中途卡死可以加一个savesolveroutput参数把求解器原始输出保存下来分析卡在了哪类约束上。5. 仿真算例与结果分析以 IEEE 33 节点系统为例5.1 算例设置我用的是经典的 IEEE 33 节点配电网这是做配电网规划绕不开的基准系统结构简单但各项约束齐全。电压等级 12.66 kV总负荷大约 3.7 MW 2.3 Mvar。在这个系统上做了三组对比场景目的就是想看清“空间可调度性”到底能带来多少收益场景 A不考虑可调度性充电负荷固定在各站址节点场景 B考虑空间可调度转移比例系数取 0.2场景 C考虑空间可调度转移比例系数取 0.4。分布式电源候选位置设为节点 6、12、18、24、30充电站候选位置设为节点 5、15、25、32。光伏装机单位容量投资按 4.5 元/W 折算充电桩单桩容量 60 kW单桩投资 8 万元寿命 15 年。看板参数列齐以后剩下的就是跑模型、看结果。5.2 结果可调度性对规划方案的影响跑完三组场景差异一目了然。我直接说最有价值的两个观察。第一个观察是总成本的下降幅度。场景 B 比场景 A 的总年化成本低了大约 8.6%场景 C 再比场景 B 低 4.2%。成本下降的来源其实不是单一项而是一个连锁反应允许负荷跨站转移后充电负荷可以从先前的重载节点“搬”到轻载节点网络末端电压跌落变小了潮流分布更均匀网损下降同时原来为了压电压而不得不建的 DG 容量也可以少装一点。这就是可调度性带来的“系统级红利”。第二个观察更微妙是充电站容量配置的变化。场景 A 里为了应对节点 32 附近的高需求最后在那个站配了 6 台充电桩但场景 C 里因为允许负荷向节点 25 和 5 转移节点 32 的站只需要 4 台就够。注意这省下的两台桩的投资一部分被转移到了节点 25 的站上它从 3 台变成了 4 台但总量依然少了 1 台。这个结果告诉电网规划者一个反直觉的结论对局部负荷做“加法”反而能实现整体的“减法”因为柔性负荷的存在让容量不再需要按峰值冗余配置。5.3 绘制结果时的重点图项目配套的plot_results.m画几张关键图我建议你至少保留这三张最优规划方案的系统拓扑图标明 DG 位置和容量、充电站位置和桩数典型日各节点电压分布对比图场景 A vs 场景 C直观展示可调度性带来的电压改善充电站负荷分配柱状图展示负荷从高负载站到低负载站的转移情况。第三张图最有意思它能一眼看出“可调度性”到底调度了谁的负荷。项目里用的是 Matplotlib 或 Matlab 默认绘图即可不需要花哨清晰标注坐标轴和单位才是重点。6. 常见问题与排查技巧实录6.1 求解器报错与模型调不通的问题我整理了一个排查清单按出现频率排序你照着查基本能解决大多数问题。问题现象可能原因解决方案求解器提示“Infeasible problem”约束过于严格如可调度比例系数太小且各站容量受限增大转移比例系数或放宽站点容量上限逐步测试最小可行值求解时间过长整数变量过多或二阶锥约束密集设置mipgap0.01或缩小候选站数量仍不行可改为启发式初值引导结果出现非整数充电桩数N_CS误用了连续变量改为intvar或后处理取整并重新校验约束电压约束在部分节点总是轻微越限无功支撑不足给储能或 DG 施加无功调节能力或在候选节点增加无功补偿装置最优解的成本为 0目标函数里成本系数单位混乱检查所有成本系数的量纲是否统一到 万元/年CPLEX 报错环境变量找不到Matlab 没正确配置求解器路径在 Matlab 里运行yalmiptest检查求解器状态参考安装文档重新配置路径6.2 数据不确定性的处理技巧这个项目里有一处容易让人挠头的地方可调度比例系数到底取多少是合理的这个数据如果没有交通仿真或行为调查支撑就只能拍脑袋定。我的建议是做敏感性分析把系数从 0 扫到 0.5每隔 0.05 算一次画一条“系数-总成本”曲线。如果发现成本对某个区间非常敏感比如从 0.15 到 0.25 下降了 10%就意味着这个参数在方案中具有很高价值应该更谨慎地取值如果曲线平缓说明结果对该参数不敏感用什么值都影响不大。我在这个项目里还尝试了鲁棒优化的变体把可调度系数设成一个不确定区间[alpha_min, alpha_max]用盒式不确定集去规划结果虽然偏保守整体成本高了大约 5%但方案对数据误差的容忍度明显增强。如果甲方那边拿不出相对准确的行为数据这个方案值得考虑。6.3 Matlab 运行环境的坑既然标题里点名了 Matlab顺便提两个环境配置上的实际经验。首先是求解器连接问题。很多人在装完 YALMIP 后调用optimize时提示找不到求解器实际原因是 Matlab 搜索路径没有包含求解器的安装目录。解决办法是在setpath里手动添加或者用addpath(genpath(C:\Program Files\IBM\ILOG\CPLEX_Studio...))添加后保存路径。这一步做完建议执行yalmiptest确认求解器被正确识别别急着跑主程序。其次是版本兼容性。新版 Matlab 对某些旧版工具箱函数的名称做了调整比如老版本里的strsplit用法到新版本有细微差异这类问题在运行别人的代码时最常见。我的习惯是把main.m的开头加上clear; clc; close all;之外再加一句version输出版本号然后再跑。真要出问题第一个就能想到是不是版本差异。7. 更适合工程的扩展方向与实际体会模型跑通之后我最后想聊聊这个框架能往哪些方向延伸尤其如果你准备拿这套方法做学位论文或者实际规划项目。第一个值得扩展的方向是多时间尺度。当前模型处理的是典型日内的时序运行但没有真正建模跨时段的储能调度。如果把储能引入作为第三个决策对象充电负荷不仅能在空间站之间转移还能通过储能实现时间上的“削峰填谷”这就是真正意义上的“时空可调度”了。不过我得提醒储能充放电引入了状态变量后模型会从 MILP 变成 MILP 加储能电站周期约束复杂度提升不少求解时间肉眼可见地上涨。第二个方向是多目标化。这篇的模型目标函数是经济成本单目标但在真实规划中碳排放、用户充电便利性、电网可靠性都要考虑。我的建议是不要一次性搞 NSGA-II 速攻全目标而是先做单目标敏感性分析挑出主要矛盾和次要矛盾再用加权法或约束法处理多目标。盲目上多目标进化算法的最大问题是你都不知道每个目标的合理范围算出来的 Pareto 前沿也解释不清。第三个方向是考虑电网运行的不确定性。光伏出力天然有波动电动汽车充电需求也有随机性确定性规划的结果在极端场景下可能崩溃。我之前尝试过用场景法Scenario-based把典型日和极端日打包进约束集结果方案鲁棒性明显提升代价是模型规模再翻一倍。如果你有求解资源这条路径值得投。按我个人的经验这类联合配置项目最容易踩的坑反而是对“可调度性”的理解。很多改进模型只停留在把负荷从重载节点挪到轻载节点这一步缺少对用户行为可行性的校验。你的调度方案再漂亮落到实际运营层面如果用户不买账优化就是个空壳。不管算法多高级最后一定要回到数据和工程常识里去做交叉验证。再说一个我在多次调试中养成的小习惯每调完一组参数就把目标函数里的总投资成本、运维成本、网损成本和惩罚项分别输出到一个 CSV 文件里方便对比不同场景的组成差异。这么做的好处是一旦结果出来跟预期不符你能很快定位是哪个成本项异常而不是对着总成本发愁。模型跑完结果符合预期我们再回头审视一下整个过程中有没有什么地方是可以优化的——其实从数据到模型的每一步都有改进空间但先把主体框架跑通、把结果解释清楚永远是第一优先级。
返回列表