ARTICLE DETAIL

资讯详情

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

基于MISOCP的主动配电网最优潮流建模与MATLAB实现

基于MISOCP的主动配电网最优潮流建模与MATLAB实现 1. 项目背景与核心价值为什么主动配电网最优潮流需要MISOCP如果你正在研究电力系统优化尤其是分布式能源高渗透的配电网那么“最优潮流”这个词对你来说一定不陌生。传统的配电网最优潮流计算大多基于确定性模型和连续变量处理的是“潮流怎么流最经济”的问题。但随着光伏、风机、储能、电动汽车充电桩这些“主动”元素大规模接入问题就变得复杂了。调度中心不仅要决定发电机的出力还要决定这些分布式资源的开关状态比如电容器组投切、联络开关开合、运行模式储能是充电还是放电这些决策变量往往是“是”或“否”的二值选择。这就把一个连续的优化问题变成了一个混合了连续变量如功率、电压和整数变量如开关状态的混合整数规划问题。更棘手的是电力潮流方程本身是非线性的、非凸的。直接求解混合整数非线性规划计算复杂度是指数级的对于实时性要求高的配电网调度来说基本不可行。所以学术界和工业界一直在寻找一种既能保证一定精度又能高效求解的近似方法。二阶锥规划松弛技术就是将非凸的交流潮流方程松弛为一个凸的二阶锥约束从而将原问题转化为一个可高效求解的凸优化问题。而当我们把SOCP和整数变量结合起来就得到了混合整数二阶锥规划。所以这个项目的核心价值在于它提供了一个基于MISOCP的、可用于求解主动配电网最优潮流的、开源的、可复现的MATLAB代码框架。它不是为了发表论文而做的“玩具模型”而是力求贴近工程实际考虑了网损、电压约束、分布式电源出力限制、电容器组投切等混合整数控制变量。对于电力系统、运筹学的研究生、算法工程师或是电网公司的技术人员来说这份代码是一个极佳的“脚手架”。你可以直接用它来验证自己的模型也可以在其基础上增加新的约束比如考虑不确定性或者替换求解器进行性能对比。它把教科书上的理论变成了可以运行、可以调试、可以改进的活代码。2. MISOCP在主动配电网最优潮流中的建模精髓要理解这份代码必须先搞清楚它到底对什么问题做了怎样的“变形”。我们从一个最朴素的主动配电网最优潮流问题开始。2.1 从交流最优潮流到二阶锥松弛标准的交流最优潮流模型可以简述为在满足潮流方程基尔霍夫定律、节点电压上下限、支路功率传输极限、发电机出力上下限等约束的前提下最小化一个目标函数通常是总发电成本或总网损。其中潮流方程是“罪魁祸首”。对于一条连接节点i和j的支路其上的功率流P_ij, Q_ij与节点电压V_i, V_j以及相角差δ_ij之间的关系是非线性的。MISOCP方法的核心“魔术”在于引入一组变量替换。通常我们会定义新的变量l_ij I_ij^2(支路电流幅值平方)u_i V_i^2(节点电压幅值平方)。通过这组替换并将原始的功率方程进行平方和整理可以将每条支路上的功率平衡和电压降落关系精确地转化为一个二阶锥约束的形式。例如对于采用支路潮流模型的配电网通常为辐射状经过推导对于支路ij其约束可以写成(2*P_ij)^2 (2*Q_ij)^2 (l_ij - u_i)^2 (l_ij u_i)^2这个不等式正是一个旋转二阶锥约束的标准形式。它的可行域是一个凸集。关键在于这个转化在忽略网损或做特定假设时是精确的但在考虑网损的普遍情况下它是一种松弛。也就是说原非线性问题的解一定满足这个锥约束但满足锥约束的解不一定满足原方程。不过在配电网尤其是辐射状、高R/X比的实际运行点附近这种松弛通常是“紧”的即松弛后的最优解非常接近甚至就是原问题的最优解。这就用凸优化问题的求解难度换取了对非凸问题的逼近。2.2 “混合整数”部分的引入离散控制变量建模主动配电网中的离散控制变量是MISOCP中“MI”部分的来源。最常见的包括电容器组投切并联电容器组用于无功补偿其投切是整数步进的。例如一组容量为Q_c的电容其投入组数k可以是0, 1, 2, ... N。那么该节点注入的无功Q_c_inject k * Q_c其中k是整数变量。有载调压变压器分接头分接头位置t通常也是离散的整数档位它直接影响变压器变比从而影响潮流分布。网络重构开关联络开关和分段开关的状态0-开1-合是二值整数变量它们决定了网络的拓扑结构。在MISOCP模型中这些整数变量会直接参与到优化模型中。例如电容器投切组数k作为一个整数变量会出现在节点无功平衡方程中开关状态作为一个0-1变量会以“大M法”等形式与支路功率流变量耦合表示当开关断开时该支路上的功率必须为0。一个关键的建模技巧对于像电容器组这样的设备其投切组数k和产生的无功Q_c之间是线性关系。但如果我们考虑其投切动作次数限制比如一天内不能超过多少次或者考虑其动态调节过程就需要引入更复杂的整数规划约束如分段线性化或引入辅助状态变量。这份基础代码通常只处理静态的单时段优化因此模型相对直接。2.3 目标函数与整体模型架构目标函数通常是最小化总运行成本。在学术研究和本代码的语境下由于分布式电源如光伏的燃料成本为0总成本往往近似为从上级电网购电的成本加上网损的成本网损也需要向上级电网多购电来补偿。因此一个典型的目标函数是Minimize: C_grid * P_grid C_loss * Sum(P_loss)其中P_grid是根节点平衡节点从上级电网吸收的有功功率P_loss是各条支路上的有功损耗C_grid和C_loss是相应的成本系数。网损P_loss可以通过支路电阻和电流平方计算P_loss_ij r_ij * l_ij。将上述所有元素组合起来就得到了主动配电网最优潮流的MISOCP模型决策变量连续变量节点电压平方u_i 支路电流平方l_ij 支路功率P_ij/Q_ij 发电机出力P_g/Q_g等整数变量电容器组投切数k 开关状态s等。目标函数最小化总成本如购电成本网损成本。约束条件节点功率平衡约束考虑分布式电源注入和负荷需求。支路潮流二阶锥松弛约束。节点电压安全上下限约束u_min u_i u_max。支路功率或电流传输极限约束。分布式电源出力上下限约束。整数变量相关约束如上下限、与功率变量的耦合关系。这个模型是一个混合整数二阶锥规划问题可以使用专业的优化求解器如Gurobi, CPLEX, MOSEK进行求解。代码的核心工作就是使用MATLAB的优化建模工具如YALMIP或CVX将这个数学模型“翻译”成求解器能识别的形式。3. 代码框架解析与关键实现步骤由于提供的项目正文为空我将基于“基于混合整数二阶锥规划(MISOCP)的主动配电网最优潮流计算”这一典型课题构建一个合理的、可复现的MATLAB代码框架。这个框架假设使用YALMIP作为建模语言Gurobi作为求解器。3.1 环境准备与数据输入首先你需要一个清晰的配电网数据结构。通常我们会从一个标准测试系统开始比如IEEE 33节点、IEEE 69节点或PGE 69节点系统。% 1. 清空环境 clear; close all; clc; % 添加YALMIP路径假设已安装 addpath(genpath(你的YALMIP路径)); % 添加Gurobi的MATLAB接口路径假设已安装 addpath(genpath(你的Gurobi路径)); % 2. 读取配电网数据 % 假设有一个函数 load_case_ieee33() 返回一个结构体 case_data case_data load_case_ieee33(); % case_data 应包含以下字段 % bus: 节点数据表 [bus_i, type, Pd, Qd, Vmin, Vmax] Pd/Qd为负荷 % branch: 支路数据表 [fbus, tbus, r, x, rateA] r/x为电阻电抗rateA为容量 % gen: 发电机/分布式电源数据 [bus, Pg_max, Pg_min, Qg_max, Qg_min, cost] cost为成本系数 % cap: 并联电容器数据 [bus, Qc_max, steps, cost_step] steps为可投切组数 % baseMVA: 系统基准功率 % baseKV: 系统基准电压关键细节负荷数据Pd和Qd通常是标幺值。电压上下限Vmin/Vmax通常是实际值如0.95-1.05 p.u.但在建模时需要转换为平方值u_min/u_max。支路电阻r和电抗x也是标幺值。3.2 定义优化变量使用YALMIP的sdpvar命令定义连续和整数变量。% 提取网络维度 n_bus size(case_data.bus, 1); n_branch size(case_data.branch, 1); n_gen size(case_data.gen, 1); n_cap size(case_data.cap, 1); % 3. 定义连续变量 % 节点电压幅值平方 u sdpvar(n_bus, 1); % u_i V_i^2 % 支路电流幅值平方 l sdpvar(n_branch, 1); % l_ij I_ij^2 % 支路有功/无功功率流 (从母线fbus流向tbus) Pij sdpvar(n_branch, 1); Qij sdpvar(n_branch, 1); % 发电机有功/无功出力 Pg sdpvar(n_gen, 1); Qg sdpvar(n_gen, 1); % 根节点平衡节点假设为1号节点从上级电网吸收的有功 P_grid sdpvar(1, 1); % 4. 定义整数变量 % 电容器投切组数 (假设为整数非0-1变量) if n_cap 0 k_cap intvar(n_cap, 1); % 整数变量 else k_cap []; end % 注意如果考虑开关重构还需要定义二值变量表示开关状态这里暂不展开。3.3 构建约束条件这是代码最核心的部分需要将第2部分中的数学模型逐一实现。% 初始化约束集合 Constraints []; % 5.1 节点功率平衡约束 (对每个节点i) for i 1:n_bus % 找到所有以i为末端节点的支路 (流入i) in_branches find(case_data.branch(:, 2) i); % 找到所有以i为首端节点的支路 (流出i) out_branches find(case_data.branch(:, 1) i); % 计算节点i的净注入有功 P_injection 0; if ~isempty(in_branches) P_injection P_injection sum(Pij(in_branches)); end if ~isempty(out_branches) % 流出的功率是负的注入 P_injection P_injection - sum(Pij(out_branches)); % 还要减去这些流出支路上的损耗 for br out_branches r_br case_data.branch(br, 3); P_injection P_injection - r_br * l(br); % 减去损耗 end end % 节点i的发电机注入 (如果有) gen_at_bus find(case_data.gen(:, 1) i); P_gen 0; Q_gen 0; if ~isempty(gen_at_bus) % 假设一个节点最多有一个发电机 idx_gen gen_at_bus(1); P_gen Pg(idx_gen); Q_gen Qg(idx_gen); end % 节点i的电容器注入 (如果有) cap_at_bus find(case_data.cap(:, 1) i); Q_cap 0; if ~isempty(cap_at_bus) idx_cap cap_at_bus(1); Q_step case_data.cap(idx_cap, 2) / case_data.cap(idx_cap, 3); % 单组容量 Q_cap Q_step * k_cap(idx_cap); % 总补偿容量 end % 节点i的负荷 (吸收功率所以是负的注入) P_load case_data.bus(i, 3); Q_load case_data.bus(i, 4); % 有功平衡约束 Constraints [Constraints, P_injection P_gen - P_load]; % 无功平衡约束 (类似有功但需要考虑线路充电功率等简化起见此处略去) % 构建Q_injection的逻辑与P_injection类似 Q_injection ... % 类似P_injection的计算 Constraints [Constraints, Q_injection Q_gen Q_cap - Q_load]; end % 5.2 支路潮流二阶锥松弛约束 (对每条支路ij) for br 1:n_branch f case_data.branch(br, 1); % 首端节点 t case_data.branch(br, 2); % 末端节点 r case_data.branch(br, 3); x case_data.branch(br, 4); % 电压降落方程 (精确的欧姆定律形式经过松弛) % u(t) u(f) - 2*(r*Pij x*Qij) (r^2 x^2)*l Constraints [Constraints, ... u(t) u(f) - 2*(r*Pij(br) x*Qij(br)) (r^2 x^2)*l(br)]; % 二阶锥松弛约束: (2*Pij)^2 (2*Qij)^2 (l - u_f)^2 (l u_f)^2 % YALMIP中使用 cone 函数来定义二阶锥约束 % 形式 norm([A*x; b]) c*x d % 对于我们的约束可以写成 % norm([2*Pij(br); 2*Qij(br); l(br)-u(f)]) l(br) u(f) Constraints [Constraints, ... norm([2*Pij(br); 2*Qij(br); l(br)-u(f)], 2) l(br) u(f)]; end % 5.3 节点电压安全约束 Vmin_sq (case_data.bus(:, 5)).^2; % Vmin^2 Vmax_sq (case_data.bus(:, 6)).^2; % Vmax^2 Constraints [Constraints, Vmin_sq u Vmax_sq]; % 5.4 发电机出力上下限约束 Pg_min case_data.gen(:, 3); Pg_max case_data.gen(:, 2); Qg_min case_data.gen(:, 5); Qg_max case_data.gen(:, 4); Constraints [Constraints, Pg_min Pg Pg_max, Qg_min Qg Qg_max]; % 5.5 支路容量约束 (通过电流平方限制) l_max (case_data.branch(:, 5) / case_data.baseMVA).^2; % 假设rateA是视在功率限值转换为电流平方标幺值 Constraints [Constraints, 0 l l_max]; % 5.6 电容器整数约束 if n_cap 0 cap_steps case_data.cap(:, 3); % 最大可投组数 Constraints [Constraints, 0 k_cap cap_steps]; % 注意k_cap已经是intvar所以0kN自动意味着整数约束。 end % 5.7 平衡节点约束 (假设为节点1) % 通常平衡节点电压幅值和相角固定。这里我们固定其电压平方为1.0 p.u. slack_bus 1; Constraints [Constraints, u(slack_bus) 1.0]; % 平衡节点的有功注入P_grid就是上级电网购电功率 % 我们需要在目标函数中用到它并在节点1的功率平衡中将其作为发电机注入。3.4 构建目标函数并求解目标函数通常包含购电成本和网损成本。% 6. 构建目标函数 % 计算总网损 (所有支路电阻损耗之和) total_loss sum(case_data.branch(:, 3) .* l); % sum(r_ij * l_ij) % 购电成本系数和网损成本系数 (示例值) C_grid 100; % 元/MWh C_loss 80; % 元/MWh (可能低于购电成本) % 目标函数最小化总成本 Objective C_grid * P_grid C_loss * total_loss; % 7. 配置求解器并求解 % 指定使用Gurobi求解MISOCP问题 ops sdpsettings(verbose, 1, solver, gurobi); % Gurobi专门处理二阶锥和整数规划 ops.gurobi.TimeLimit 300; % 设置求解时间限制为300秒 ops.gurobi.MIPGap 1e-4; % 设置混合整数规划的间隙容差 % 调用YALMIP的optimize函数求解 sol optimize(Constraints, Objective, ops); % 8. 检查求解状态并获取结果 if sol.problem 0 disp(求解成功); % 获取优化变量值 u_opt value(u); l_opt value(l); Pij_opt value(Pij); Qij_opt value(Qij); Pg_opt value(Pg); Qg_opt value(Qg); P_grid_opt value(P_grid); if n_cap 0 k_cap_opt value(k_cap); disp([电容器投切方案, num2str(k_cap_opt)]); end total_loss_opt value(total_loss); total_cost_opt value(Objective); disp([总网损 (p.u.): , num2str(total_loss_opt)]); disp([总成本: , num2str(total_cost_opt)]); disp([平衡节点购电功率 (p.u.): , num2str(P_grid_opt)]); % 计算各节点电压幅值 (p.u.) V_opt sqrt(u_opt); disp(节点电压幅值 (p.u.):); disp(V_opt); else disp(求解出错); yalmiperror(sol.problem); end4. 核心难点、避坑指南与实战心得即使有了上面的代码框架在实际复现和扩展时你依然会遇到不少坑。下面是我在类似项目实践中总结的几个关键点。4.1 二阶锥松弛的“紧性”验证与间隙处理这是理论应用到实践的第一道坎。你求出的MISOCP解真的是原问题的一个可行解吗不一定。因为SOCP是原问题的松弛其解可能不满足原始的、非凸的交流潮流方程。你需要进行一个后验检验。检验方法将优化得到的变量Pij_opt,Qij_opt,u_opt,l_opt代入原始的、未松弛的潮流方程中看等式是否成立。一个常用的指标是计算每条支路的“松弛间隙”gap_ij (2*Pij_opt)^2 (2*Qij_opt)^2 (l_opt - u_opt_f)^2 - (l_opt u_opt_f)^2理论上如果松弛是紧的这个gap_ij应该是一个极小的负数因为约束是小于等于。如果gap_ij的绝对值很大比如大于1e-4说明松弛不紧MISOCP的解对于原问题不可行。怎么办检查模型首先确认你的二阶锥约束推导和代码实现是否正确。一个常见的错误是符号弄反或者电压降落方程写错。调整网络参数对于某些极端运行工况如重载、高R/X比线路松弛可能不紧。可以尝试轻微调整负荷或发电机出力看间隙是否变小。使用更精确的凸松弛基础的SOCP松弛DistFlow模型有时不够紧。可以考虑使用更复杂的凸松弛如半正定规划松弛或更精确的二次凸松弛但计算成本会上升。接受近似解并微调在工程实践中如果间隙很小可以将MISOCP的解作为初始点代入一个非线性潮流计算程序如MATPOWER的runpf进行精确潮流计算。通常经过少量迭代就能收敛到一个可行的、接近最优的运行点。4.2 整数变量带来的组合爆炸与求解技巧MISOCP是NP-hard问题。当电容器组、开关等整数变量增多时求解时间会急剧增加。一个33节点系统带几个电容器可能几秒就解完但一个123节点系统带几十个可控设备可能几个小时都求不出最优解。加速求解的策略设定合理的求解器参数如代码中设置的MIPGap混合整数规划间隙。默认可能是1e-4对于工程问题设置为1e-3甚至5e-3可以大幅缩短求解时间而得到的解仍然是高质量的近似最优解。TimeLimit是救命参数防止程序无限制运行。提供初始解如果你能通过经验或启发式方法如先求解连续松弛问题然后对整数变量四舍五入得到一个可行的初始解提供给Gurobi能显著加快其搜索过程。在YALMIP中可以使用assign函数为变量赋初值。分解与简化时间解耦对于多时段优化如果时段间耦合不强如储能能量约束可以尝试先分时段求解再协调。空间解耦对于大规模网络可以考虑基于社区发现或电气距离进行网络分区分别优化后再进行边界协调。减少整数变量对于投切组数很多的电容器可以将其近似为连续变量在结果出来后取整。虽然损失了最优性但换来了速度。利用问题特性配电网通常是辐射状的。一些求解器或算法如Benders分解、动态规划可以利用这种树状结构特性来设计更高效的求解策略。不过这在通用求解器如Gurobi中可能无法直接体现。4.3 与MATPOWER等成熟工具的对比与衔接你可能会问MATPOWER也能做最优潮流我为什么要自己写MISOCP两者定位不同。MATPOWER核心是求解连续变量、非线性的AC-OPF或DC-OPF。它功能强大、鲁棒性高是验证潮流结果和基准测试的黄金标准。但它原生不支持整数变量。虽然可以通过外部循环如主问题-子问题或将其近似为连续变量来处理但并非严格意义上的混合整数规划。自建MISOCP模型优势在于统一框架下处理混合整数非线性问题。你可以灵活地加入各种离散控制逻辑、复杂的成本函数、甚至机会约束。它是进行算法研究、方案对比、定制化控制策略验证的利器。一个实用的工作流是用MATPOWER进行基础数据验证和潮流计算。用自建的MISOCP模型研究含离散控制的新算法。最后将MISOCP得到的最优设定值如发电机出力、电容器组数作为已知量代入MATPOWER进行一轮精确的交流潮流计算以验证其可行性并得到精确的电压、网损数据。4.4 模型扩展从单时段到多时段与不确定性基础的单时段MISOCP模型是基石。真正的挑战在于扩展。多时段优化引入储能SOC状态约束、可调负荷如电动汽车、考虑可再生能源和负荷的时序特性。这会让变量和约束成倍增加模型变为混合整数二阶锥规划。关键在于对储能等设备的动态约束进行精确建模并利用求解器的增量求解功能。不确定性处理光伏、风电出力具有不确定性。简单的做法是采用鲁棒优化或机会约束规划。例如在鲁棒优化中将可再生能源出力描述在一个不确定集合内如区间[P_min, P_max]优化目标是在最坏情况下性能最优。这会将模型转化为一个min-max形式的MISOCP求解更为复杂。机会约束则允许以一定概率违反约束通常通过场景法或解析转化来处理。这些扩展会让代码复杂度陡增。建议在单时段确定性模型完全稳定后再逐步增加这些模块并做好版本管理和测试。5. 结果分析与可视化让数据说话求解完成后一堆数字变量缺乏直观性。好的可视化能帮你快速验证结果、发现问题和展示成果。% 假设已获得优化结果 u_opt, V_opt, Pij_opt 等 % 9.1 绘制节点电压分布图 figure(1); bus_ids 1:n_bus; plot(bus_ids, V_opt, bo-, LineWidth, 1.5, MarkerSize, 8, MarkerFaceColor, b); hold on; yline(1.05, r--, LineWidth, 1.2); % 电压上限 yline(0.95, r--, LineWidth, 1.2); % 电压下限 xlabel(节点编号); ylabel(电压幅值 (p.u.)); title(优化后节点电压分布); legend(电压幅值, 电压上限, 电压下限, Location, best); grid on; % 9.2 绘制支路功率流热力图 (以线宽表示功率大小) figure(2); % 需要网络的拓扑连接信息这里假设有一个函数get_branch_coords能返回支路绘图坐标 % [x1, y1, x2, y2] get_branch_coords(case_data); % 简化起见我们用支路索引和功率值做个条形图 branch_ids 1:n_branch; Pij_magnitude abs(Pij_opt); % 取绝对值表示功率大小 bar(branch_ids, Pij_magnitude); xlabel(支路编号); ylabel(有功功率流绝对值 (p.u.)); title(各支路有功功率流分布); grid on; % 9.3 输出关键指标表格 fprintf(\n 优化结果摘要 \n); fprintf(%-25s: %12.4f p.u.\n, 总网损, total_loss_opt); fprintf(%-25s: %12.4f $\n, 总运行成本, total_cost_opt); fprintf(%-25s: %12.4f p.u.\n, 根节点购电功率, P_grid_opt); fprintf(%-25s: %12.4f ~ %12.4f p.u.\n, 节点电压范围, min(V_opt), max(V_opt)); if n_cap 0 fprintf(%-25s: , 电容器投切方案); fprintf(%d , k_cap_opt); fprintf(\n); end fprintf(\n\n); % 9.4 (进阶) 绘制网络拓扑与潮流方向 % 这需要更复杂的绘图可以借助MATLAB的graph对象或第三方工具箱如GridLAB-D的绘图功能。 % 基本思路将节点作为顶点支路作为边边的粗细和颜色代表功率流大小和方向。分析要点电压分布是否所有节点电压都在安全范围内通常优化后电压曲线会变得更加平坦网损最小点往往对应电压接近额定值。功率流是否有支路接近传输极限优化可能会引导潮流减轻重载支路的压力。电容器动作投入的电容器是否在低电压或无功不足的节点这可以验证控制逻辑的合理性。成本与网损对比优化前后或对比不同控制策略下的总成本和网损量化优化效果。6. 性能调优与求解器实战经验代码跑起来了但可能很慢。除了前面提到的模型层面的技巧在求解器使用层面也有不少门道。Gurobi参数调优MIPFocus这个参数至关重要。如果追求快速得到一个可行解设为1如果确信有可行解想提升最优性证明速度设为2如果想努力寻找更优的解设为3。对于初次求解可以试试设为1。Heuristics启发式算法比例。调高它可以加快找到初始可行解的速度。Presolve预求解强度。Gurobi的预求解非常强大通常保持默认的激进设置-1即可。但有时对于数值不稳定的模型降低预求解强度可能有助于找到解。NumericFocus如果经常遇到数值不稳定警告如“约束违反”可以尝试将此参数设为1或2让求解器花更多精力处理数值问题。YALMIP建模注意事项避免重复创建约束在循环中拼接约束Constraints [Constraints, new_constraint]对于中小型问题没问题但对于大型问题这种动态扩展数组的方式效率较低。更高效的做法是预分配一个元胞数组来存储约束。使用向量化操作尽可能用矩阵和向量形式表示约束而不是在循环中对每个元素单独建模。例如节点功率平衡约束可以用关联矩阵一次性写出。这能极大减少YALMIP内部构建模型的时间也是YALMIP官方推荐的做法。检查模型稀疏性电力系统模型本质上是稀疏的。确保你的变量和约束定义方式不会破坏这种稀疏性。YALMIP和Gurobi都能很好地处理稀疏模型。一个常见错误排查流程求解失败首先看Gurobi返回的状态码和YALMIP的sol.info。如果是“不可行”用debug功能optimize(Constraints, Objective, ops, debug1)或检查约束冲突。解无意义如电压为0或极大检查变量上下限是否设置正确特别是电压平方u的下限不能为负。检查平衡节点约束是否正确施加。求解速度极慢尝试先求解连续松弛问题将intvar改为sdpvar如果连续问题都解得很慢那可能是模型本身或网络规模问题。如果连续问题很快而MIP很慢说明整数部分组合复杂需要调整MIP参数或寻找更好的初始解。最后分享一个我个人的习惯在开发这类优化代码时我会从一个极小规模的、手算可知结果的网络开始比如一个3节点的链式网络先验证模型和代码的正确性。然后再逐步扩展到标准测试系统。这样做虽然前期麻烦但能从根本上杜绝因模型错误导致的各种诡异问题长远来看效率最高。
返回列表