You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何预定义Gurobi模型实现迭代阶段多场景多进程并行求解

解决方案

首先明确:Gurobi的Model和Env对象属于C扩展实现的非序列化对象,无法直接通过multiprocessing的默认序列化机制传递给子进程,因此无法直接在主进程定义一次后直接分给多个子进程使用,但可以通过以下低成本方案实现「仅构建一次基础模型」的需求,避免每轮迭代/每个子进程重复定义模型逻辑:

方案1:基础模型预导出为MPS/LP文件(推荐,跨平台兼容)

这是最稳定高效的实现方式:

  • 主进程启动后先一次性构建好基础模型,导出为本地MPS格式文件(MPS是Gurobi支持的标准模型格式,读写速度极快)
  • 所有子进程求解场景时,直接读取该基础模型文件,再修改对应约束即可,无需重复编写模型构建逻辑
  • 基础模型文件仅需生成一次,后续所有迭代轮次都可以复用

示例代码

import multiprocessing as mp
import gurobipy as gp
import os

# 全局配置:基础模型路径,仅生成一次
BASE_MODEL_PATH = "base_model.mps"

def build_base_model():
    """主进程调用:一次性构建基础模型并导出"""
    with gp.Env() as env, gp.Model(env=env) as base_model:
        # 这里写你的基础模型定义逻辑,所有场景通用的部分都在这里实现
        # ......
        # 导出基础模型
        base_model.write(BASE_MODEL_PATH)

def solve_scene(input_data):
    """子进程调用:读取基础模型+修改约束+求解"""
    scene_id, constraint_params = input_data
    with gp.Env() as env, gp.read(BASE_MODEL_PATH, env=env) as model:
        # 根据当前场景参数调整对应约束,比如修改RHS、增减约束等
        # 示例:调整指定约束的右侧值
        # model.getConstrByName(f"constr_{scene_id}").RHS = constraint_params
        model.optimize()
        # 提取求解结果返回
        res = {
            "scene_id": scene_id,
            "obj_val": model.ObjVal if model.status == gp.GRB.OPTIMAL else None
            # 其他需要的结果字段
        }
        return res

if __name__ == '__main__':
    # 第一步:仅启动时运行一次,构建并导出基础模型
    if not os.path.exists(BASE_MODEL_PATH):
        build_base_model()
    
    # 迭代流程示例
    for iter_num in range(10): # 你的迭代轮次
        print(f"开始第{iter_num}轮迭代")
        # 组装当前轮次的9个场景输入参数
        scene_inputs = [(i, f"param_{i}") for i in range(9)]
        # 多进程并行求解
        with mp.Pool(processes=9) as pool:
            iter_results = pool.map(solve_scene, scene_inputs)
        # 处理当前轮次的求解结果
        # ......

方案2:使用Gurobi原生多场景特性

如果你的9个场景仅涉及约束右端值、变量上下界、目标系数的调整,可以直接使用Gurobi内置的Multi-Scenario功能,无需自己实现多进程逻辑,Gurobi会自动并行求解所有场景,代码实现更简洁:

import gurobipy as gp

with gp.Env() as env, gp.Model(env=env) as model:
    # 构建基础模型
    # ......
    # 设置场景数为9
    model.NumScenarios = 9
    for scene_id in range(9):
        model.params.ScenarioNumber = scene_id
        # 给当前场景设置对应约束/变量参数
        # model.getConstrByName("xxx").ScenNRHS = xxx
    # 一次性并行求解所有场景
    model.optimize()
    # 逐个读取场景结果
    for scene_id in range(9):
        model.params.ScenarioNumber = scene_id
        print(f"场景{scene_id}目标值:{model.ObjVal}")

注意事项

  • 禁止多个进程共用同一个GurobiEnv或Model实例,会引发内存错误、许可冲突等异常
  • 若使用Linux/macOS系统的fork模式多进程,理论上可以继承主进程的模型对象,但容易出现Gurobi内部状态冲突问题,稳定性远低于预导出MPS的方案,不推荐使用

内容的提问来源于stack exchange,提问作者Sanjeev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 00:39:04