或日志提取器
orloge的Python项目详细描述
奥利奇
什么和为什么
这个项目的想法是允许快速而简单地解析来自不同解算器的日志文件,特别是“运筹学”(或)日志。
存在较大的、更健壮的库。尤其是IPET我遇到的麻烦是它处理太多基准测试和gui的事情,我想要一些简单的东西,我可以修改和建立在上面。
不管怎样,很多思想和解析字符串都是从IPET中获得或改编的,我对IPET很在行
目前支持的解算器有:gurobi、cplex和cbc。特别是前两个
如何
其基本思想是提供如下独特的接口功能:
import orloge as ol
ol.get_info_log_solver(path_to_solver_log, solver_name)
这将返回一个python字典,其中包含来自日志的大量信息(请参见下面的Examples)
安装
pip install orloge
或者,对于开发版本:
pip install https://github.com/pchtsp/orloge/archive/master.zip
测试
运行命令
python -m unittest test
如果输出显示OK,则所有测试都通过。
参考
主要参数
最常见的提取参数是:best_bound
、best_solution
和time
。这三个参数是在求解过程结束时获得的,它们总结了获得的最佳松弛目标值、获得的最佳整数目标值以及求解所需的时间。
切割
切割信息可以通过cuts_info
键访问它提供了切割阶段结束后的最佳已知界限、切割后的最佳解决方案(如果有)以及每种类型的切割次数
矩阵
提供了两个矩阵在解算器预处理之前,matrix
键返回变量数、约束和非零值。在预处理完成后,matrix_post
键返回这些相同的值。
进展
progress
键返回一个原始pandas数据框,其中包含解算器提供的所有进度信息。包括时间、间隔、最佳边界、最佳解、迭代、节点等此表在解算器之间的列数可能不同,但列的名称是规范化的,以便对相同的信息使用相同的名称。
状态
状态有几种方式。首先,在status
中返回原始字符串提取。然后,通过sol_code
和status_code
键给出了一个使用代码的规范化的。sol_code
提供有关所获得溶液质量的信息status_code
给出了完成后解算器状态的详细信息(主要是它停止的原因)。
其他
还有关于预解阶段、第一界和第一解的信息另外,还有关于解决根节点所需时间的信息
示例
import orloge as ol
ol.get_info_log_solver('tests/data/cbc298-app1-2.out', 'CBC')
会产生以下结果:
{'best_bound': -96.111283,
'best_solution': None,
'cut_info': {'best_bound': -210.09571,
'best_solution': 1e+50,
'cuts': None,
'time': None},
'first_relaxed': -210.09571,
'first_solution': 1e+50,
'gap': None,
'matrix': {'constraints': 53467, 'nonzeros': 199175, 'variables': 26871},
'matrix_post': {'constraints': 26555, 'nonzeros': 195875, 'variables': 13265},
'nodes': 31867,
'presolve': None,
'progress':
Node NodesLeft BestInteger CutsBestBound Time
0 0 1 1e+50 -210.09571 32.83
1 100 11 1e+50 -210.09571 124.49
.. ... ... ... ... ...
[319 rows x 5 columns],
'rootTime': None,
'sol_code': 0,
'solver': 'CBC',
'status': 'Stopped on time limit',
'status_code': -4,
'time': 7132.49,
'version': '2.9.8'}
还有一个例子,这次使用gurobi:
import orloge as ol
ol.get_info_log_solver('tests/data/gurobi700-app1-2.out', 'GUROBI')
创建以下输出:
{'best_bound': -41.0,
'best_solution': -41.0,
'cut_info': {'best_bound': -167.97894,
'best_solution': -41.0,
'cuts': {'Clique': 1,
'Gomory': 16,
'Implied bound': 23,
'MIR': 22},
'time': 21.0},
'first_relaxed': -178.94318,
'first_solution': -41.0,
'gap': 0.0,
'matrix': {'constraints': 53467, 'nonzeros': 199175, 'variables': 26871},
'matrix_post': {'constraints': 35616, 'nonzeros': 149085, 'variables': 22010},
'nodes': 526.0,
'presolve': {'cols': 4861, 'rows': 17851, 'time': 3.4},
'progress':
Node NodesLeft Objective Depth ... CutsBestBound Gap ItpNode Time
0 0 0 -178.94318 0 ... -178.94318 336% None 4s
1 0 0 -171.91701 0 ... -171.91701 319% None 15s
2 0 0 -170.97660 0 ... -170.97660 317% None 15s
[26 rows x 10 columns],
'rootTime': 0.7,
'sol_code': 1,
'solver': 'GUROBI',
'status': 'Optimal solution found',
'status_code': 1,
'time': 46.67,
'version': '7.0.0'}
分析完整的进度表有助于以后分析原始解决方案流程的任何人。我试图使用PuLP中的状态代码和解决方案代码。