导读:优化领域存在诸多开源或者商业的 MIP 求解器,作为解决优化问题的底层核心工具,各类求解器针对不同编程语言提供了对应的建模求解接口。然而,不同求解器的建模求解接口存在差异,如果要切换求解器,还需要从头学习另一套 API 设计和编写代码,本着 DRY(Don’t Repeat Yourself)原则,本文调研了各类求解器的命令行调用方式,并以CDN布局规划问题为例,实现了一键运行,完成多案例、多求解器的自动化求解。
作者 1:向杜兵,算法专家,某制造业龙头
作者 2:张哲铭,算法专家,某互联网大厂
- 明人不说暗话,【运筹匠心】想要大家的赞!赞!赞!。先赞后看,多多益善(* ̄︶ ̄)~~~
- 本期推文代码获取方式,将推文转发朋友圈获20赞,添加管理员微信,管理员会定期回复数据代码链接哈~~~
- 各个系列的开源资料会定期整理发放,大家可以加粉丝群领取哦~~~
请加管理员微信:IndustryOR
大家好!我们是IndustryOR 团队,致力于分享业界落地的算法技术。欢迎关注微信公众号/知乎【运筹匠心】 。本期我们来谈一谈《CDN布局规划的算法技术》。本期案例共分 3 篇文章依次讲解:(1)业务问题拆解;(2)模型算法实现;(3)多求解器批量求解对比。
本篇文章讲解(3)多求解器批量求解对比。
目前,市面上有众多商业和开源的 MIP 求解器可供选择,大多都支持不同的编程语言,且提供了丰富的建模求解接口。然而,如果我们想要更换求解器,或者想对不同求解器进行对比验证,调用不同求解器的 API 从头编写代码的方式需要重新学习各类求解器的 API,时间成本相对较高。
值得庆幸的是,大多数求解器都支持通过读取模型文件的方式进行求解,这意味着我们可以将问题建模后的模型数据保存到文件中,然后通过求解器的命令行进行求解,无需从头开始学习每种求解器的诸多接口,大大减少重复工作。
然而,不同求解器的命令行调用命令也存在差异。因此,我们对各类求解器的命令行调用方式进行了调研,并以前几期的 CDN 布局规划问题为例,对目前常见的 4 个求解器(Gurobi、CPLEX、COPT、MindOpt)进行了对比测试。
本文主要结构如下:
1. 各求解器命令行调用模式
2. 批量求解 Python 代码设计
3. CDN 布局规划问题求解对比分析
1.各求解器命令行调用模式
Gurobi
方式1:单行命令执行
gurobi_cl model.mps
方式2:交互执行
m=read("model.mps")
m.optimize()
CPLEX
交互式执行
read model.mps
optimize
COPT
方式1:交互式执行
read model.mps
optimize
方式2:读取命令文件
copt_cmd -i config.in
MindOpt
单行命令执行
mindopt model.mps
最终,确定各个求解器的调用模式,如下表所示:
求解器 | 调用模式 |
---|---|
Gurobi | ‘gurobi_cl model.mps’ |
CPLEX | ‘read model.mps’, ‘optimize’ |
COPT | ‘copt_cmd -i config.in’ |
MindOpt | ‘mindopt model.mps’ |
注:在后文所述的利用Python脚本对这些求解器进行命令行调用的过程中,部分求解器的某些方式调用失败,暂时没有解决,如果有读者有相关经验,我们可以互相交流
那么,了解了怎么通过这些求解器的命令行求解模型文件,就足够了吗?
命令行调用的方式多数是交互模式,即需要在命令行窗口交互式地输入命令才能向下执行,如果我们想要批量自动化求解多个模型,则可以通过编写自动化脚本的方式实现。
接下来将介绍如何编写 Python 脚本,实现对不同求解器的命令行调用,并自动化求解多个模型数据文件。该脚本通过读取模型文件、设置参数和调用相应的求解器命令,实现了自动化求解的过程。使用时只需准备好模型文件,然后一键运行,即可求解多个模型数据文件。
2.批量求解 Python 代码设计
由于不同求解器的调用方式存在差异,而对于自动化批量求解来说,我们不关心采用哪种求解器完成求解这个操作,我们又不想把各个求解器的调用逻辑混在一块,然后通过丑陋的if else判断,同时还得考虑后续可能需要扩展其他的求解器。因此,本着开闭原则,我们决定采用继承的方式来实现这个功能。这样,每个求解器的调用实现完全独立,扩展其他求解器也无需修改已有代码。
基类:SolverCaller
子类:GurobiCaller、CplexCaller、CoptCaller、MindOptCaller
3.CDN布局规划问题求解分析
借助该脚本,对 4 个商业求解器(经小案例测试,开源求解器 SCIP、OR-Tools 等在该问题上求解速度与商业求解器差距较大,不再对比)进行了对比,求解了 3*10 共30个案例(数据来源:某公开比赛数据集),以下为求解结果:
求解时间对比图
横轴:案例编号
纵轴:各求解器的求解时长(秒)
注:除了求解时长限制为 3600s 外,所有求解器均采用默认参数。
结论:
30 个案例中,solver_1、solver_2、solver_3、solver_4 在 1 小时内达到时长限制的案例数量分别为:3、4、15、12。
另外,对于 solver_3 和 solver_4 均达到时长限制(1小时)的案例,统计各自最终的 Gap,如下图所示:
求解 Gap对比图
横轴:案例的编号
纵轴:Gap(%)
结语
本篇:介绍了使用命令行调用求解器进行自动化批量求解的方法,并通过对CDN布局规划问题的多个实例进行比较分析,提供了对不同求解器求解性能的初步了解。需要强调的是,本文的对比结果只是针对这一特定问题的特定数据集,在其他数据,其他不同问题上,各个求解器的表现可能与本文中的存在差异。
本系列文章:在该系列中,我们一起从问题拆解、模型刻画、批量求解等方面研究了CDN布局规划问题,并沉淀了一套多求解器、批量求解、可扩展的自动化方案。完结撒花~~~
值得一提的是,如果我们不追求最优解,而是想要在更短的时间内得到一个不错的规划方案,那么可以设计启发式算法来对该问题求解,这也是在本次案例对应比赛中的主流技术方案。得益于灵活、高效等特点,启发式算法在工业界的应用更加广泛,且在更前沿的应用中,会与机器学习、深度学习、强化学习等 AI 技术相结合。后续我们也将分享在业界落地的诸多技术方案,期待我们下一次的相遇。
请大家多多点赞、评论、转发、关注!大家的支持是我们持续创作的动力。我们是【运筹匠心】 ,咱们下期见~~~
参考文献:
[1]Gurobi Optimizer Reference Manual
[2]启动 CPLEX
[2]COPT交互式命令行工具
[3]命令行调用 MindOpt