如何将IBM CPLEX Studio编写的.mod线性规划文件导入Python求解?
复用CPLEX .mod模型在Python中求解的可行方案
问题描述
我用IBM CPLEX Studio编写了如下线性规划模型并保存为.mod文件:
int I = ...; int J = ...; int ds[1..I]=...; int maxnint[1..J]=...; dvar int E[1..I][1..J][1..6]; dvar boolean V[1..I]; minimize sum(i in 1..I)(E[i,J,maxnint[J]]-ds[i]*V[i]); subject to{ forall(i in 1..I, j in 1..J, mu in 1..maxnint[j]) E[i,j,mu]>=0; forall(i in 1..I)( t_max*V[i] >=E[i,J,maxnint[J]]-ds[i]); forall(i in 1..I)(-t_max*(1-V[i]) <=E[i,J,maxnint[J]]-ds[i]); }希望将该文件导入Python,并用Python中读取的如下数据求解,同时避免在Python中重写约束:
import numpy as np I = range(10) J = range(6) ra = np.array([240, 400, 264, 390, 200, 440]) maxnint = np.array([1, 1, 3, 3, 1, 4]) ds = np.array([14, 19, 16, 21, 28, 14, 21, 19, 15, 14 ])
可行性结论
完全可行,无需在Python中重写约束,直接复用已有的.mod模型文件即可,通过CPLEX Python API注入数据并求解。
操作步骤
1. 修正.mod模型文件
原模型中未定义t_max参数,需在文件开头添加定义,否则求解时会报错:
int I = ...; int J = ...; int t_max = ...; // 新增参数定义,需后续在Python中赋值 int ds[1..I]=...; int maxnint[1..J]=...; dvar int E[1..I][1..J][1..6]; dvar boolean V[1..I]; minimize sum(i in 1..I)(E[i,J,maxnint[J]]-ds[i]*V[i]); subject to{ forall(i in 1..I, j in 1..J, mu in 1..maxnint[j]) E[i,j,mu]>=0; forall(i in 1..I)( t_max*V[i] >=E[i,J,maxnint[J]]-ds[i]); forall(i in 1..I)(-t_max*(1-V[i]) <=E[i,J,maxnint[J]]-ds[i]); }
2. Python中读取模型并注入数据
使用CPLEX Python API读取.mod文件,将Python中的数据注入模型参数,然后求解:
import cplex import numpy as np # 定义求解所需数据 I_val = 10 # 对应ds数组的长度 J_val = 6 t_max_val = 100 # 替换为你实际的t_max取值 maxnint = np.array([1, 1, 3, 3, 1, 4]) ds = np.array([14, 19, 16, 21, 28, 14, 21, 19, 15, 14]) # 初始化CPLEX模型并读取.mod文件 model = cplex.Cplex() model.read("your_model.mod") # 替换为你的.mod文件路径 # 注入参数值到模型 # CPLEX .mod使用1-based索引,因此数组需补占位符对齐索引 model.parameters.advance.set("I", I_val) model.parameters.advance.set("J", J_val) model.parameters.advance.set("t_max", t_max_val) model.parameters.advance.set("ds", [0] + ds.tolist()) # 索引0占位,1~10对应1..I model.parameters.advance.set("maxnint", [0] + maxnint.tolist()) # 索引0占位,1~6对应1..J # 求解模型 model.solve() # 输出结果 print("目标函数值:", model.solution.get_objective_value()) # 获取布尔变量V的取值 V_values = model.solution.get_values("V") print("V变量取值:", V_values) # 示例:获取E[i,J,maxnint[J]]的取值 for i in range(1, I_val + 1): j = J_val mu = maxnint[j - 1] # Python为0-based,对应.mod中的maxnint[j] e_val = model.solution.get_values(f"E[{i}][{j}][{mu}]") print(f"E[{i}][{j}][{mu}] = {e_val}")
3. 注意事项
- 确保已安装CPLEX Python库,且拥有合法的CPLEX许可证
- .mod文件中的参数名需与Python中注入的参数名完全一致
- 索引对齐:CPLEX .mod使用1-based索引,Python为0-based,传递数组时需补占位符(如
[0] + 数组.tolist())让索引从1开始匹配 t_max必须赋值,否则模型无法完成约束定义
内容的提问来源于stack exchange,提问作者Ali Fradi
相关产品推荐
相关产品推荐

