Matlab+Gurobi遇MEX限制,如何实现每线程求解一个Simplex LP并行?
解决方案:多独立LP并行求解(绕开Matlab+Gurobi MEX限制)
方案1:Matlab内改用进程式并行池
Matlab的线程型worker不支持MEX,但进程型worker完全兼容Gurobi的MEX接口,每个worker是独立进程,不会触发MEX使用限制:
- 操作步骤:
- 创建进程并行池:
parpool('Processes', N),N设为你需要的并行数(比如CPU核心数) - 在
parfor循环中正常调用Gurobi求解每个LP,每个迭代对应一个独立LP - 提前确保所有worker能访问Gurobi路径:可以在创建池前执行
addpath(gurobi_root),或者在parfor内先调用gurobi_setup
- 创建进程并行池:
方案2:换用Python/C++原生实现并行
如果Matlab的限制难以适配,直接用Gurobi原生支持更好的语言实现:
Python版本
用进程池并行,每个进程独立求解一个LP,完全避开MEX限制:
from gurobipy import Model from concurrent.futures import ProcessPoolExecutor def solve_single_lp(lp_config): # lp_config包含单个LP的目标、约束、变量边界等数据 model = Model() # 构建LP模型(添加变量、约束、设置目标) model.optimize() # 返回结果:目标值、变量解、可行性状态 return { "obj_val": model.objVal if model.status == Model.OPTIMAL else None, "solution": model.getAttr("x") if model.status == Model.OPTIMAL else None, "is_feasible": model.status in [Model.OPTIMAL, Model.FEASIBLE] } # 假设lp_configs是所有待求解LP的配置列表 with ProcessPoolExecutor(max_workers=4) as executor: results = list(executor.map(solve_single_lp, lp_configs))
C++版本
用线程或线程池实现,每个线程独立创建Gurobi环境和模型(注意Env不能跨线程共享):
#include <gurobi_c++.h> #include <vector> #include <thread> struct LPResult { double obj_val; std::vector<double> solution; bool is_feasible; }; LPResult solve_single_lp(const LPConfig& config) { GRBEnv env = GRBEnv(true); env.start(); GRBModel model(env); // 构建LP模型:添加变量、约束、设置目标 model.optimize(); LPResult res{}; int status = model.get(GRB_IntAttr_Status); res.is_feasible = (status == GRB_OPTIMAL || status == GRB_FEASIBLE); if (res.is_feasible) { res.obj_val = model.get(GRB_DoubleAttr_ObjVal); int var_count = model.get(GRB_IntAttr_NumVars); res.solution.resize(var_count); model.getVars(res.solution.data(), var_count); } return res; } int main() { std::vector<LPConfig> lp_configs; // 填充所有LP的配置数据 std::vector<std::thread> threads; std::vector<LPResult> results(lp_configs.size()); for (size_t i = 0; i < lp_configs.size(); ++i) { threads.emplace_back([&, i]() { results[i] = solve_single_lp(lp_configs[i]); }); } for (auto& t : threads) { t.join(); } // 处理results中的求解结果 return 0; }
方案3:Gurobi批量求解模式
用Gurobi的命令行批量工具,无需修改太多Matlab代码:
- 将每个LP模型导出为
.mps或.lp文件(Matlab中用gurobi_write函数) - 调用Gurobi命令行工具
gurobi_cl,用--batch参数批量处理,同时指定每个求解用1线程:% 假设lp_files是所有LP文件路径的单元格数组 file_list = strjoin(lp_files, ' '); % 执行批量求解,每个LP用1线程,并行处理 system(['gurobi_cl --batch Threads=1 ' file_list]); - 读取每个LP对应的
.sol结果文件,解析求解状态和结果
内容的提问来源于stack exchange,提问作者Alekzei Vallarfax
相关产品推荐
相关产品推荐

