1. 这题目在解决什么问题
做配电网规划项目做到一定阶段,你会很明显地产生一种“纠缠感”:分布式电源越装越多,充电桩也在疯狂铺开,一开始是两条线在跑,后来就整个绕在一起了。这个题目把两件事放进同一个优化框架里,用 Matlab 实现了一套联合配置方案,核心抓手就是“充电负荷空间可调度特性”这八个字。所谓空间可调度,一句话讲清楚:普通居民负荷在那个节点就是那个节点,你挪不走;但电动汽车充电负荷不一样,同一辆网约车、同一批通勤车主,A 站排队就去 B 站,这个需求是可以被引导、被转移、被规划的。把这一层属性用起来,DG 布点和充电站选址定容就能协调着做,网损、电压质量、年综合费用都会明显改善。
这篇文章适合谁来读?我建议这样定位:如果你在做电动汽车充电设施规划、分布式电源接入规划,或者你的课题恰好卡在“多目标协调配置”这一块,这篇文章就是一条完整的参考线——从问题建模到 Matlab 实现,再到求解器配置和避坑经验,基本能直接照着搭一个算例出来。当然,如果你是刚接触配电网优化的小白,文章里对潮流方程、混合整数规划这些基础概念也做了尽量通俗的解释,不会让你看得一头雾水。
1.1 单打独斗规划为何开始失效
先说一个非常典型的旧思路。某个园区或城市片区要发展电动车,规划人员往往先做充电需求预测,预测出“未来三年这里大概有多少充电需求”,然后拿这张需求表去布点建站。与此同时,分布式电源规划由另一拨人做,他们主要看日照、屋顶面积或者土地资源,算经济性,然后给出光伏或风机的接入点位。两条线最后能不能碰在一起?大多数时候碰不到。
这带来的问题在配电网里非常直观:充电高峰一般出现在傍晚和夜间,跟居民负荷叠加,这个时段光伏出力已经归零,如果充电站旁边刚好没有任何分布式电源,那么所有功率都得从上级电网送来,线路上潮流量猛增,末端电压直接压到越限线以下。相反,如果分布式电源布局合理,哪怕只是在靠近充电站的区域放一组光伏,白天的出力就能把一部分充电负荷就地平衡掉,晚上配合峰谷电价还能起到削峰填谷的作用。所以把这两个问题分开做,等于人为放弃了它们之间的耦合优化空间——这就是联合配置方法出现的最根本原因。
我自己的体会是,做“联合”的时候,难点不是多了一个目标函数,而是多了一类可以在不同节点之间流动的负荷。这一类负荷会把原来的确定性规划问题变成一个跟用户行为相关的决策问题,建模维度一下就上去了。所以这个题目真正要做的事情,是把充电负荷的“可迁移性”量化出来,再把它塞进一个传统的 DG 选址定容模型里,让优化器自己去体会“哪里建站、建多大、DG 怎么配合”这件事。
1.2 空间可调度:充电负荷和普通负荷最本质的区别
为了把“空间可调度”讲透,我拿一个具体例子来说明。假设一个配电网片区里有两个候选充电站位置:节点 A 靠近主干线,变压器容量充足,但周边居民少,充电需求低;节点 B 位于商业区,充电需求旺盛,可配电网已经接近满载。如果没有空间可调度,我们只能按“需求在哪就在哪建”的原则,忍受 B 节点电压越限和高昂的扩容成本。可现在,只要有一定比例的充电用户愿意接受“多走 1 到 2 公里”或者“错开半小时充电”,我们就能把 B 的一部分充电需求引导到 A。充电站在 A 建一部分、在 B 补一部分,配网潮流分布被改写了,DG 也不需要为了 B 点单独扩容。
这里最关键的一点是:“空间可调度特性”是一个比例,不是一个固定值,更不是简单的有或没有。现实中受充电价格、排队时间、用户行为习惯等因素影响,不可能 100% 的人都接受调度。所以在建模里通常引入一个“可调度比例系数”λ,λ 表示用户中愿意接受空间引导的占比。λ=0.3 意味着 30% 的充电负荷可以在空间上重新分配,另外 70% 是必须原位满足的刚性负荷。这个 λ 给规划者提供了一个非常有价值的调节旋钮:你可以通过价格机制、预约机制来提升 λ,也可以用保守的 λ 做规划,最后对比不同 λ 下的配置结果。
说句掏心窝的话,很多论文里把这个东西包装得很玄,实际落到 Matlab 代码里,它就是把原本“负荷是固定向量”的写法,改成“一部分负荷向量固定,另一部分负荷向量在几个候选站点之间待分配”。而且可调度负荷在空间上分配到哪个节点,还要满足用户就近原则——你不能把一个商业区的充电需求强行调到十公里以外。所以模型里通常还会加一个最大可转移距离或者覆盖半径的约束,让优化结果贴近现实。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 联合配置框架与优化模型
题目里的“联合配置”落实到数学上,就是一个带约束的混合整数规划问题:DG 的选址定容、充电站的选址定容、可调度充电负荷的空间分配,这三个决策被放到同一个目标函数里一起优化。为什么必须放到一起?因为三个决策相互影响,分开优化会陷入“先给 DG 定容→发现充电站建设方案不配合→回头再改 DG”的无限循环。一次性建模可以把这种往复迭代收敛到一个全局较优解上,这也是联合配置方法的核心价值。
这一节我把建模的骨架完整写出来,包括目标函数选什么、约束条件有哪些、空间可调度特性怎么进模型。为了让你快速理解,我会用自己的话解释,并在后面给出可以直接改的 Matlab 代码骨架。
2.1 目标函数:从单一成本到综合费用
我在实际算例里用的目标函数是“年综合费用最小”。这不是唯一选择,但对规划类问题来说比较稳妥,因为它能把一次性投资和长期运行费用放在同一个时间尺度上比较。年综合费用包含四个部分:
第一部分是分布式电源的年化投资与运维成本。投资成本用等年值法折算,也就是把设备一次性投资按寿命年限和贴现率摊到每年。等年值的计算公式是 C_inv = C_cap × r × (1 + r)^n / ((1 + r)^n - 1),其中 C_cap 是设备单位容量投资成本,r 是贴现率,n 是寿命年限。为什么一定要做等年值折算?因为 DG 和充电站在建设当年要花一大笔钱,如果不折算,直接跟年运行费用相加,会严重高估建设期年份的成本、低估运行期成本,导致优化结果偏向于不建设或少建设。这个细节在论文里可能只有一句话,但在代码里如果忘了折算,结果就会完全跑偏。
第二部分是充电站的建设与设备成本。充电站成本包括土建、变压器扩容、充电桩购置等。通常按“单桩容量×桩数量”来建模,再叠加一个固定建设费用。固定费用很关键,因为充电站哪怕只有一台桩,也要有场地、接入、配套,这部分成本不会随容量线性变化。如果目标函数里只有线性容量成本,优化模型一定会把充电桩建得极其分散,因为单个节点成本低,这在工程实际中是完全不合理的。
第三部分是网络运行损耗费用。配电网的损耗跟各支路电流平方与电阻乘积之和相关。DG 布点合理、充电负荷空间分配合理,都能显著降低线路上的传输功率,从而降低损耗费用,所以这一项是联合配置收益的直接体现。
第四部分是向上级电网购电费用,以及必要的环境折算成本。这里可以灵活处理,如果做纯经济性,环境成本可以不加;如果论文需要体现低碳,就把单位发电的碳排放系数乘上购电量加进去。我个人建议把碳排放单独做灵敏度分析,不要一开始就塞进目标函数,否则调试时很难定位到底是经济约束不满足,还是环境项导致模型无解。
2.2 约束条件:潮流、节点承载和充电站服务能力
约束条件是一个规划模型最不能含糊的部分。我在代码里按约束类型分了四组。
第一组是潮流约束。配电网规划常用的潮流模型是 DistFlow 方程,它的思想是把支路潮流写成从电源点到负荷点的递推关系,包含有功平衡、无功平衡和电压降落三个方程。DistFlow 本身是二次约束,直接丢进优化器会让问题变成非凸的,求解不稳定。工程上常见的做法是把它做二阶锥松弛:把电流平方项和电压平方项分别替换成辅助变量,二次等式松弛成锥不等式,最终变成一个二阶锥规划(SOCP)问题。这个松弛只有在目标函数推动潮流收敛到边界上时才严格成立,好在“年综合费用最小”这类目标通常会让损耗尽量小,所以松弛误差在实际算例里非常小。后面代码里我会给出 DistFlow 的完整写法。
第二组是节点电压约束。节点电压一般限制在 0.95 pu~1.05 pu 之间。这个约束很容易被忽略,但分布式电源接入过多会导致电压抬升,充电负荷接入过多会导致电压跌落。只有 DG 和充电站联合配置后,两者才有可能在某些节点上形成“对冲”:白天光伏出力大、电压高,但充电负荷如果在白天被引导到这个节点,就能把电压压回来。这个对冲效应,就是联合配置比单独配置在电压质量上更有优势的核心原因。
第三组是 DG 和充电站的容量约束。DG 的接入容量不能超过节点可承载容量,充电站的桩数不能超过候选站点可建设数量。这些约束往往来自电网公司的接入批复或者场地条件,做算例时一定要留出参数入口,方便后续跑场景对比。
第四组是充电站服务能力约束。具体来说,每个充电站的总容量要能够给“分配到该站的充电负荷”提供服务,也就是可调度负荷的分配结果必须满足容量匹配。容量不够,优化结果等于空中楼阁;容量太大,投资浪费。这组约束把充电负荷的空间分配和充电站定容耦合在一起,是模型里联动性最强的一组约束。
2.3 空间可调度特性的数学化表达
现在专门说说空间可调度特性怎么落到公式里。我自己习惯的做法是先把充电负荷分成两类:刚性负荷和柔性负荷。刚性负荷是必须留在原始需求节点的部分,占用充电需求的比例为 1-λ;柔性负荷是可以在候选站之间转移的部分,比例为 λ。这两类负荷加起来等于该节点的总充电需求。
接下来第二层,柔性负荷要能落地。规划前我们先确定每个需求点对应的候选充电站集合。这个集合怎么定?按实际距离或道路距离不超过某个上限来确定,比如 2 km 内可以到达的站都算候选站。如果候选站集合为空,那这部分柔性负荷事实上还是刚性负荷,因为用户无处可去。代码里用邻接矩阵 Candidates(i, j) 来表示:如果节点 i 的充电需求可以到候选站 j 去充电,矩阵元素就是 1;否则是 0。
第三层,柔性负荷的分配量要等于总柔性负荷,并且每个站的分配量不能超过站点建设容量。这三层关系加上站容量约束、总负荷守恒约束,就构成了完整的空间可调度模型。初学者最常犯的错误是只加了“可调度负荷可以在不同站之间移动”的等式约束,却忘了定义候选站集合,结果优化器把负荷调到几十公里外,方案当然不可行。所以代码里我特别强调 Candidates 矩阵的生成逻辑,它直接决定了优化结果有没有工程可实施性。
3. Matlab 代码实现全过程
这一节进入实操。我会用一个修改后的 IEEE 33 节点配电网作为算例,讲清楚从数据准备到优化模型、再到求解和出图的完整过程。整个实现基于 Matlab + YALMIP + GUROBI:YALMIP 是建模工具箱,GUROBI 用来求解混合整数二阶锥规划。如果你只有 Matlab 自带求解器,YALMIP 里也可以换 sedumi 或 cplex,但遇到大规模整数变量时会吃力很多。下面给出的代码框架尽量精简,去掉大量重复定义,核心逻辑保留完整。
3.1 算例场景与输入数据准备
第一步是构造配电网拓扑。IEEE 33 节点系统的数据在很多论文里都有,包含 32 条支路,每条支路的首端节点、末端节点、电阻和电抗。我把这些数据整理成两个矩阵:branch 矩阵每一行是一条支路,load 矩阵每一行是节点基础负荷的有功和无功。基础负荷数据要特别注意单位统一,我习惯用 kW/kVar 作单位,因为充电站容量也是用 kW 衡量的,如果混入 MW 而没做换算,最后优化出来的容量会差三个数量级,这类错误靠自己肉眼检查很难发现。
第二步是生成典型日场景。分布式电源出力和充电负荷都随时间变化,优化模型全时段联立会让变量数量爆炸。我用 K-means 聚类把全年 8760 小时聚成 4 个典型日,每个典型日包含 24 小时的光伏出力曲线、风电机组出力曲线、基础负荷曲线和充电需求曲线。聚类的作用是降低计算规模,同时保留季节差异。聚类后每个典型日还要赋予一个权重,代表这个日型在全年的占比,目标函数里的运行费用就按这个权重折算。
第三步是生成充电负荷的空间分布。规划不像调度,不需要逐车模拟,我采用“区域需求系数法”:先预测片区总充电需求,再按每个节点的商业面积、人口密度、道路流量打一个系数,把总需求分配到 33 个节点上,得到每个节点 24 小时的充电负荷曲线。这里可以加上随机扰动来做蒙特卡洛,但规划算例一般用均值场景就够了,随机性较强的研究才会考虑多场景鲁棒规划。
3.2 优化模型代码骨架
下面这段代码是联合配置模型最核心的部分。先看决策变量的定义。
matlab复制% 决策变量定义
% DG 选址:tau_dg(i) 为 0-1 变量,表示节点 i 是否接入 DG
tau_dg = binvar(n_bus, 1);
% DG 接入容量:连续变量,单位 kW
P_dg = sdpvar(n_bus, 1);
% 充电站选址:0-1 变量,表示候选站 j 是否建设
tau_cs = binvar(n_cs, 1);
% 充电站建设容量(kW),连续变量
S_cs = sdpvar(n_cs, 1);
% 柔性充电负荷分配量:从需求节点 i 分配到候选站 j 的值
F_alloc = sdpvar(n_demand, n_cs, 'full');
我用 tau_dg 和 tau_cs 做选址的 0-1 变量,用 P_dg 和 S_cs 做容量连续变量,用 F_alloc 矩阵做柔性负荷的空间分配。这里有三个容易踩坑的点:
第一,0-1 变量和容量连续变量之间一定要加逻辑关联约束。比如某节点不建 DG 时该节点容量必须为 0,建了 DG 时容量才允许在一定范围内取值。写成约束就是 P_dg(i) <= tau_dg(i) * P_dg_max(i)。没有这组约束,优化器可能在不建站的节点上给出一个容量,选址变量就失去意义。
第二,充电站容量 S_cs 同样要和 tau_cs 关联,而且要设置最小建设容量门槛。不设门槛的常规做法是 S_cs(j) <= tau_cs(j) * S_cs_max(j),这样容量可能取到非常接近 0 的值,优化结果里出现一个只有 1 kW 的充电站,从数学上说无懈可击,工程上完全不可行。所以我加了最小容量限制:一旦建站,容量至少是 50 kW,用 S_cs(j) >= tau_cs(j) * S_cs_min(j) 实现。这个约束看起来多余,实际是帮你排除无意义解的好习惯。
第三,DistFlow 潮流方程里要不要用大 M 法处理节点是否接入 DG 和充电站的影响?我的经验是不需要。DG 和充电站对潮流的影响通过节点注入功率体现,只要把 P_dg、刚性充电负荷和分配到的柔性负荷一起加进节点注入功率,潮流方程自然就能反映配置结果。大 M 法一般只用于处理存在联络开关、拓扑变化的场景,静态规划用不上就不要引入,避免求解规模膨胀。
3.3 求解器配置和关键参数
模型建好后,求解配置是整个环节里最影响心情的一步。YALMIP 里一条命令就能指定求解器,但不同求解器对问题类型的支持差异很大。先看配置代码:
matlab复制% 设置求解器
options = sdpsettings('solver', 'gurobi', 'verbose', 2);
% 求解混合整数二阶锥规划
options.gurobi.MIPGap = 0.01;
options.gurobi.TimeLimit = 3600;
options.gurobi.NumericFocus = 3;
% 求解
sol = optimize(cons, objective, options);
if sol.problem ~= 0
warning('求解失败: %s', sol.info);
end
我踩过的几个坑值得专门说。第一个是 MIPGap。默认情况下,混合整数二阶锥规划的停机容忍度如果设为 0,GUROBI 可能为了证明最优性耗费大量时间。实际规划问题不需要证明到小数点后第三位,把 MIPGap 设为 0.01 或 0.02,求解速度会有数量级提升,而配置结果的差别几乎可以忽略。在做论文场景对比时,我基本固定 MIPGap=0.01,并记录最终目标值,这样不同场景之间的对比才是公平的。
第二个是数值尺度问题。配电网里的电阻电抗是 0.1 欧姆级别,电压是 12.66 kV,功率是几百到几千 kW,变量跨度非常大。GUROBI 对这类问题有内部缩放,但偶尔还是会出现数值问题,表现为模型明明可行却报 infeasible,或者解出来电压轻微越限。我的办法是把电压、功率全部做归一化:电压用 pu 值,功率用 kW,电阻电抗用标幺值。IEEE 33 节点系统基准值通常取 10 MVA、12.66 kV,各参数做标幺后,数值量级就正常了。
第三个是求解器的许可问题。Matlab + YALMIP 可以免费使用,但 GUROBI 需要学术许可,很多刚上手的同学在这一步卡住。如果不想额外装求解器,可以把 solver 换成 'sedumi' 或者 'cplex'——sedumi 免费但速度慢,CPLEX 效果也好但同样需要许可。我个人的建议是直接申请 GUROBI 学术许可,安装一次可以用很多年,省下的调试时间远超装工具的时间。
3.4 结果输出与图表演示
求解完成后,四个方面的结果一定要检查:选址结果、容量结果、柔性负荷分配结果和电压网损指标。先看选址结果是否满足直觉——比如有充电需求的大节点附近大概率应该建站,DG 往往倾向于布置在线路末端或大负荷节点附近。如果完全反直觉,一般是约束写错了,而不是优化器出了问题,千万别急着怀疑求解器。
然后把电压剖面画出来。横轴是节点编号,纵轴是电压幅值,画三条曲线:不接入任何 DG 和充电站的原始电压、单独配置充电站的电压、联合配置后的电压。这张图是论文里最有说服力的一张,也是我自己调试时最依赖的图。它直观展示了两件事:单独配置充电站时,负荷增大让末端电压下降更严重;联合配置后,DG 在合适的位置出力,把电压抬升回来,末端电压明显改善。
再画一份 DG 和充电站容量配置的柱状图,以及充电负荷在候选站之间的分配图。分配图不是必须的,但如果你要写论文,它能非常清楚地展示“空间可调度”这个特性。Matlab 里可以用自带的 Graph 对象画简单节点流量图,也可以用 Plotly 扩展画更漂亮的桑基图,看个人习惯。
最后,也是最容易被忽视的:把优化后每个典型日的 24 小时节点注入功率保存下来,生成一个表格,包含节点号、时刻、有功注入、无功注入。这个表格一方面是结果的证据,另一方面是下一步做潮流验证的输入。很多论文里只给目标函数值和配置结果,讨论部分显得单薄,就是因为缺了这张“过程数据表”。
4. 实测中常见问题与排查实录
代码能跑、结果能用,中间通常要经历好几轮“发现问题—定位—修复”的循环。这一节我把实际操作中遇到的典型问题集中写出来,每个问题都附带排查思路和解决办法,希望帮你少走弯路。
4.1 潮流方程松弛后结果异常
有次我跑 SOCP 松弛模型,发现优化后个别节点电压刚好压在 1.05 pu 上,所有约束都满足,目标函数也很合理,但拿优化结果做一次精确潮流校验时,却出现了轻微越限。这个现象来自二阶锥松弛的误差。解决方案有两步:第一步,在目标函数里给松弛变量补一个极小的惩罚项,比如 1e-6 × 电流平方项之和,把松弛解往严紧解上“推”;第二步,求解结束后用 MATPOWER 或自编牛顿拉夫逊潮流对优化结果做一次验算,把校验出的偏差反馈到模型里微调电压上下限。做规划研究时,这个验算步骤是论文审稿人最喜欢看的,也是工程上必须走的流程。
4.2 充电负荷曲线生成不准
生成不合理的充电负荷曲线是最隐蔽的错误。早前我用一个固定充电功率 60 kW、充电时长 1 小时来生成负荷,结果所有充电需求都集中在白天光伏出力高峰时段,联合优化后几乎不需要配网互动,结论非常“漂亮”但脱离实际。后来我换了更贴近现实的建模方式:把充电行为拆成起始充电时间和充电功率两部分。通勤用户在晚间 18:00-20:00 到达充电站,起始时间服从正态分布;营运车在午后和凌晨各有一个小高峰。充电功率取决于桩类型,快充 60 kW、慢充 7 kW 按比例混合。这样得到的负荷曲线才有早晚双峰特征,联合配置的价值才能体现出来。
我建议在生成完充电负荷曲线后,做一个“合理性自检画图”:横轴时刻、纵轴充电功率,观察曲线是否出现异常尖峰或完全平坦。峰值功率和日充电量要跟初始预测总量做对比,数量级差超过 10% 就得回头检查分配系数是不是写错了。
4.3 空间可调度系数怎么选
前面提到 λ 是可调度比例,很多同学会随手设成 0.5,做出来的结果当然也可以,但我建议把 λ 当成核心灵敏度参数来跑:分别跑 λ = 0、0.2、0.5、0.8 四组场景,观察充电站选址、DG 容量和年综合费用的变化趋势。我的实测经验是,λ 从 0 提高到 0.2 时,年综合费用和网损下降非常明显,说明只要稍微引导一下用户,配电网的日子就宽裕很多;继续提高到 0.8 时收益逐渐变缓,说明空间可调度的价值存在一个边际递减的规律。这个规律写进论文里是很好的工程洞察,比直接给一个“最优 λ”更有说服力。
还有一个容易忽略的问题:某节点可调度负荷被分配到一个新建充电站,但两个节点之间的实际道路距离可能超过用户心理阈值。我的处理方法是把最大可接受充电距离作为候选站筛选条件,直接决定 F_alloc 变量的列范围。如果某需求节点到所有候选站都太远,它事实上就变成刚性负荷。这个方法在代码里实现很简单,但能让结果的可解释性极强。
4.4 YALMIP 报错与求解慢的排查顺序
调试中常遇到的报错主要是三类。第一类是“No suitable solver”,说明 YALMIP 没有找到匹配当前问题类型的求解器。通常检查两个点:命令窗口输入 yalmiptest 看求解器是否安装成功;确认模型里没有非线性相乘,因为我见过有人把两个 0-1 变量相乘写进约束,问题从线性变成二次,很多求解器直接退出。第二类是“Infeasible problem”,意味着约束之间有冲突。我会按照“先去掉整数约束→再去掉容量下限约束→逐个放开”的顺序排查,两三分钟就能定位到卡住的那条约束。第三类是求解超时,优先看变量规模是不是膨胀了,常见做法是把 24 小时聚类成 4 个典型日,或者把候选站数量从全部节点缩减到按照需求热度筛出来的 10~15 个节点。
5. 最后分享几个我在实际算例里得到的体会
关于 Matlab 实现,我觉得最值得强调的还是那句话:规划模型的价值建立在约束贴近工程实际的程度上。同样是联合配置,模型里多一个 2 公里范围限制,结果就完全不一样;多一个最小建站容量,系统总费用可能上升,但方案可用性大幅增强。论文可以做得非常理想化,但你在自己跑算例、写代码的时候,一定要把那些“看不见但工程上必然存在”的约束加进去。
第二个体会是,Matlab 做规划类问题非常合适,但别把所有事情都放在一个脚本里。我更习惯把数据读取、模型构建、求解、后处理拆成四个函数,中间用结构体传数据。这样调试一个函数的时候,其他模块完全不受影响。后面如果想把 IEEE 33 节点系统换成 123 节点或者实际馈线数据,只要改数据读取和场景生成部分,模型部分几乎不用动。这个结构帮我节省了大量时间。
第三个体会是关于结果“讲故事”的能力。优化程序跑完以后,目标函数值、配置容量这些只是最基本的结果,真正能说明问题的是三个对比:联合配置 vs 单独配置、λ=0 与 λ>0 的对比、不同 DG 渗透率下的费用对比。每次跑算例之前,先想清楚这一轮要展示哪个对比,再去设计代码输出,效率会高很多。盲目调参跑几百组数据,不如带着假设去验证来得快。
这个题目后续还可以往两个方向延伸:一是把时间尺度拉长,考虑未来 5~10 年电动汽车保有量增长和分布式电源扩容,做成动态规划;二是把充电站的运营策略考虑进来,用户充电价格、排队时间这些实时因素会影响空间可调度的实际比例,模型就可以从规划层面延伸到运行层面,做成规划-运行两阶段协同优化。如果你正在做类似课题,可以从这两个方向选一个深入下去,和这里的联合配置框架是天然衔接的。
