如何从Python调用含CPLEX的Matlab规划程序?打包调用返回NaN异常
Matlab打包为Python包后调用返回全NaN故障排查与解决
我用Matlab编写了基于CPLEX的配电网规划优化程序,在Matlab环境中运行正常,但通过Matlab Library Compiler将M函数打包为Python包并安装后,用Python调用返回全NaN结果(预期为特定优化矩阵),求解决该异常的方法。
原始Matlab程序
function P = wenti3() clc; clear; %% 三个时间段 三台机组 a = [0.001562,0.00194,0.005784]; b = [7.92,7.85,9.56]; c = [561,310,93.6]; load = [650,1000,700]; Pmin = [150 100 50]; Pmax = [600 400 200]; J = 3; % 机组数量 T = 3; % 时间段 %% 定义未知量 P = sdpvar(J,T,'full'); % 定义矩阵必须加 'full' ccost = sdpvar(J,T,'full'); for t = 1:T for j =1:J ccost(j,t) = a(j).*P(j,t).^2 + b(j).*P(j,t) + c(j) ; end end CCOST = sum(sum(ccost)); %% 建立约束 cons = []; for t = 1:T cons = [cons , sum(P(:,t)) == load(t)]; %负荷需求相等 end for t = 1:T for j =1:J cons = [cons , P(j,t) >= Pmin(j) ]; cons = [cons , P(j,t) <= Pmax(j) ]; % cons = [cons , Pmin(j) <= P(j,t) <= Pmax(j) ]; end end %% 爬坡约束 for t = 2:T for j =1:J cons = [ cons , P(j,t) - P(j,t-1) >= - 0.3*Pmax(j)]; cons = [ cons , P(j,t) - P(j,t-1) <= 0.3*Pmax(j)]; % cons = [ cons , - 0.3*Pmax(j) <= P(j,t) - P(j,t-1) <= 0.3*Pmax(j)]; end end %% 设置求解器参数 options = sdpsettings('verbose',0,'solver' ,'cplex'); % ops.cplex.mip.tolerance.mipgap = 0.001 ; options.showprogress = 0; yalmip_message = optimize(cons, CCOST ); disp( yalmip_message ); %% 输出结果 pp = P; P = value(P) ; end
Python调用代码
import wenti3 mat_obj = wenti3.initialize() result1 = mat_obj.wenti3()
预期结果
ans = 320.0000 500.0000 350.0857 280.0000 400.0000 299.9143 50.0000 100.0000 50.0000
故障排查与解决方法
1. 删除clear和clc命令
Matlab函数中的clear会清空工作区变量,包括YALMIP和CPLEX的初始化状态,在打包后的非交互环境中会直接导致求解器无法正常工作。直接删除代码开头的clc;和clear;行。
2. 确保打包时包含所有依赖库
打包过程中必须将YALMIP和CPLEX的相关工具箱文件一同打包:
- 在Matlab Library Compiler的「Add Files」界面,手动添加YALMIP的核心文件和CPLEX工具箱的依赖文件;
- 在「Settings」中勾选「Include all required toolboxes」,确保所有依赖被包含。
3. 显式检查求解状态并处理
在Matlab函数中添加求解状态判断,避免优化失败时返回NaN:
if yalmip_message.problem == 0 P = double(value(P)); % 转换为标准数值矩阵 else error('优化失败,错误码:%d', yalmip_message.problem); end
4. 启用求解器日志排查问题
修改sdpsettings打开 verbose 日志,查看求解器运行细节:
options = sdpsettings('verbose',1,'solver','cplex');
在Python调用时查看控制台输出,确认CPLEX是否正常启动、约束是否可行、是否存在求解错误。
5. 验证环境版本一致性
确保打包时使用的Matlab、YALMIP、CPLEX版本与开发环境完全一致,避免版本不兼容导致求解失败。
内容的提问来源于stack exchange,提问作者hengyang
相关产品推荐
相关产品推荐

