求解日志
杉数求解器COPT在求解过程中会输出日志,用户可以从其中获取求解结果信息,追踪优化求解的处理过程和迭代步骤。 本章将会分别对不同算法的求解日志进行解读,内容构成如下:
求解日志相关参数和函数
用户可以通过设置求解日志相关参数,来控制是否显示求解日志,以及打印求解日志的详细程度。
Logging整数参数
是否显示求解日志
默认值 1
可选值
0: 不显示求解日志。
1: 显示求解日志。
LogLevel整数参数。
控制打印求解日志的详细程度。
默认值 2
可选值
2: 打印基础的求解日志信息。
3: 除基础求解信息外,额外打印内存消耗信息(适用于MIP问题)。
LogToConsole整数参数
是否显示求解日志到控制台
默认值 1
可选值
0: 不显示求解日志到控制台。
1: 显示求解日志到控制台。
杉数求解器COPT提供的和求解日志相关操作有:设置求解日志文件等。
COPT提供设置求解日志文件的相关函数,将求解日志写入至指定的文件(文件名后缀为 .log )中,以便用户对日志进行保存。不同编程接口的函数如 表 51 所示:
编程接口 |
设置求解日志文件函数 |
|---|---|
C |
|
C++ |
|
C# |
|
Java |
|
Python |
|
注意: 在调用该函数时,用户需通过参数 logfile 指定保存求解日志的文件名。
求解日志基础信息部分
求解日志基础信息部分展示了求解模型的整体概览、模型规模及预处理情况,以及模型数值特征统计等基本信息,帮助用户快速了解问题结构与数值状况。
求解模型概览
在求解日志开头,杉数求解器COPT会输出求解环境与求解模型的整体概览,包括模型指纹( fingerprint )、调用的COPT版本号、运行平台以及求解问题类型等信息。
示例如下:
Using Cardinal Optimizer v8.0.1 on Windows Model fingerprint: 2c27ab28 Hardware has 64 cores and 128 threads. Using instruction set X86_AVX512_E1 (14) Minimizing a MIP problem
其中, Model fingerprint 当前求解模型的唯一编码;求解所使用的硬件信息包括:CPU核数( cores )和线程数( threads )等;此外,
COPT会自动识别问题类型和优化方向,并且后续会选择合适的算法进行求解,例如:
Minimizing an LP problem 、 Minimizing a MIP problem 、 Minimizing an SDP problem 等。
模型规模描述与预求解情况
首先,这部分会打印原始模型的规模情况,示例如下:
The original problem has:
404 rows, 1200 columns and 2598 non-zero elements
200 binaries and 1000 integers
对于线性规划模型,规模描述会包括以下信息项:
约束(
rows)变量(
columns)系数矩阵非零元素(
non-zero elements)
对于整数规划模型,还会包含对于整数变量的统计:
0-1变量(
binaries)整数变量(
integers)
注意
整数规划模型的变量数目(
columns)统计的是模型中全部变量的个数,包括连续性变量、整数型变量和0-1变量;在理论上来说,0-1变量属于特殊的整数型变量,但是此处二者是分开统计的。
对于不同类型的非线性规划模型,还会包含对应非线性项的统计,例如:
半定变量(
PSD columns)目标函数中二次项(
quadratic objective elements)二次约束(
quadratic constraints)二阶锥(
SOC rows)指数锥(
exponential cones)
在默认参数设置下,在开启算法对模型进行求解前,COPT会进行预求解,对原始模型进行变换或缩减等处理,以改善模型质量,传递给后续算法的是预处理后的模型。 日志的预求解(Presolve)部分会输出预求解前后模型规模的变化。示例如下:
Presolving the problem
The presolved problem has:
373 rows, 1169 columns and 2505 non-zero elements
369 binaries and 800 integers
模型数值特征统计
这部分日志会打印模型的关键数值特征统计,以帮助评估模型的数值情况(例如系数量级跨度是否过大),包含信息条目及含义如下:
Range of matrix coefficients: 系数矩阵的取值范围Range of rhs coefficients: 约束边界的取值范围Range of bound coefficients: 变量边界的取值范围Range of cost coefficients: 目标函数系数的取值范围Density of cost: 目标函数系数的稠密程度(非零元素的比例)
具体示例如下:
Problem info:
Range of matrix coefficients: [5e-01,4e+00]
Range of rhs coefficients: [7e+02,2e+04]
Range of bound coefficients: [8e+02,3e+03]
Range of cost coefficients: [6e-02,3e-01]
单纯形法(Simplex)求解日志
按照求解过程的不同阶段,单纯形法求解日志可以划分为以下 2 个部分:
单纯形法求解过程
求解结果汇总
这里将会以 afiro.mps 算例的求解日志为例,对单纯形法求解日志中的信息进行解读。
单纯形法求解过程
此部分日志提供运用单纯形法求解迭代过程的相关信息。
Starting the simplex solver using up to 8 threads
Method Iteration Objective Primal.NInf Dual.NInf Time
Dual 0 -4.8553789460e+02 3 0 0.00s
Dual 3 -4.6476735494e+02 0 0 0.00s
Postsolving
Dual 3 -4.6475314286e+02 0 0 0.00s
其中,首行信息输出显示当前求解算法为单纯形法,使用了8线程( threads )进行计算。
接下来是求解迭代过程,由6列信息项构成:
Method:使用的求解算法,"Dual"表示对偶单纯形法(Dual Simplex)Iteration:迭代次数Objective:目标函数值Primal.NInf: 原始问题中不可行个数Dual.NInf:对偶问题中不可行个数Time:求解使用时间(单位:秒)
求解结果汇总
此部分日志是在求解完毕后,对模型求解结果和内点法迭代过程进行总结。
Solving finished
Status: Optimal Objective: -4.6475314286e+02 Iterations: 3 Time: 0.00s
包括的信息项有:
求解状态(
Status):若模型有最优解,则为Optimal目标函数值(
Objective):若模型有最优解,Objective则显示最优目标函数值总迭代数目(
Iterations)总求解时间(
Time)
若模型不可行,对应日志输出如下:
Solving finished
Status: Infeasible Objective: - Iterations: 2 Time: 0.00s
内点法(Barrier)求解日志
按照求解过程的不同阶段,内点法求解日志可以划分为以下 2 个部分:
内点法求解过程
求解结果汇总
注意: 通过设置优化参数 "LpMethod = 2",可以选择求解线性规划问题的算法为内点法。
同样,以 afiro.mps 算例的求解日志为例,对内点法求解LP问题日志中的信息进行解读。
内点法求解过程
首先,日志会打印内点法求解模型的相关数值信息:
Starting barrier solver using 64 threads
Problem info:
Dualized in presolve: No
Range of matrix coefficients: [4e-01,4e+00]
Range of rhs coefficients: [8e+01,3e+02]
Range of bound coefficients: [4e+01,1e+02]
Range of cost coefficients: [2e-01,2e+00]
Factor info:
Number of free columns: 0
Number of dense columns: 0
Number of matrix entries: 2.800e+01
Number of factor entries: 2.800e+01
Number of factor flops: 1.140e+02
其中,首行信息输出显示当前求解算法为内点法,使用了64线程( threads ),其中:
Problem info输出信息包括:是否求解对偶化模型、模型系数矩阵范围、右端项范围、约束变量边界范围和目标函数系数范围;Factor info输出信息包括:无边界变量数目、致密列数目、线性系统矩阵分解相关信息。
接下来,日志内容呈现了杉数求解器COPT运用内点法求解的迭代过程,包含的信息项有:迭代( Iter )次数、目标函数值、求解时间( Time )等。
各信息项的解释如下:
Iter: 迭代次数Primal.Obj:原始问题目标函数值Dual.Obj: 对偶问题目标函数值Compl:互补性冲突值(Complementarity violation)Primal.Inf: 原始问题不可行的程度Dual.Inf: 对偶问题不可行的程度Time: 求解使用时间(s)
Iter Primal.Obj Dual.Obj Compl Primal.Inf Dual.Inf Time
0 +2.07010046e+01 -4.97632246e+02 5.89e+03 4.50e+02 2.65e+00 0.02s
1 -1.18912241e+02 -5.91808560e+02 7.58e+02 3.36e+01 1.61e-01 0.02s
2 -3.98096520e+02 -4.77597371e+02 2.28e+02 9.32e+00 7.45e-02 0.02s
3 -4.55223227e+02 -4.68222895e+02 1.86e+01 3.60e-01 2.63e-03 0.02s
4 -4.64587726e+02 -4.64803786e+02 2.52e-01 7.80e-03 7.93e-06 0.02s
5 -4.64753143e+02 -4.64753143e+02 3.11e-07 7.80e-09 1.56e-11 0.02s
内点法(Barrier)求解总结
主要信息包括:求解状态、原始和对偶问题最优目标函数值等。
Barrier status: OPTIMAL
Primal objective: -4.64753143e+02
Dual objective: -4.64753143e+02
Duality gap (abs/rel): 2.61e-07 / 5.63e-10
Primal infeasibility (abs/rel): 7.80e-09 / 2.60e-11
Dual infeasibility (abs/rel): 1.56e-11 / 6.99e-12
Crossover过程
Starting crossover using up to 8 threads
1 primal pushes remaining 0.03s
0 primal pushes remaining 0.03s
1 dual pushes remaining 0.03s
0 dual pushes remaining 0.03s
Method Iteration Objective Primal.NInf Dual.NInf Time
Dual 1 -4.6475314286e+02 0 0 0.03s
Postsolving
Dual 1 -4.6475314286e+02 0 0 0.03s
求解结果汇总
此部分日志是在求解完毕后,对模型求解结果和内点法迭代过程进行总结。
Solving finished
Status: Optimal Objective: -4.6475314286e+02 Iterations: 1 Time: 0.03s
和单纯形法求解日志一样,此处包括的信息项有:
求解状态(
Status):若模型有最优解,则为Optimal目标函数值(
Objective):若模型有最优解, 则Objective显示最优目标函数值总迭代数目(
Iterations)总求解时间(
Time)
分支切割法(Branch-and-Cut)求解日志
按照求解过程的不同阶段,分支切割法求解日志的内容可划分为2个部分:
分支切割法搜索求解过程
结果汇总
这里将会以 cutstock.mps.gz 算例的求解日志为例,对MIP求解日志中的信息进行解读,该算例在COPT安装包 "/examples/data" 目录下。
求解过程
此部分日志输出了分支切割法(Branch-and-Cut)搜索求解的过程。
Starting the MIP solver with 8 threads and 32 tasks
Nodes Active LPit/n IntInf BestBound BestSolution Gap Time
0 1 -- 0 3.100000e+01 -- Inf 0.05s
H 0 1 -- 0 3.100000e+01 6.800000e+01 54.4% 0.70s
H 0 1 -- 0 3.100000e+01 6.600000e+01 53.0% 0.70s
H 0 1 -- 0 3.100000e+01 6.500000e+01 52.3% 0.71s
0 1 -- 86 5.591304e+01 6.500000e+01 14.0% 0.72s
H 0 1 -- 86 5.591304e+01 6.200000e+01 9.82% 0.74s
1 2 0.0 86 5.591304e+01 6.200000e+01 9.82% 0.76s
H 1 1 2129 6 6.000000e+01 6.000000e+01 0.00% 0.87s
2 0 1064 6 6.000000e+01 6.000000e+01 0.00% 0.87s
2 0 1064 6 6.000000e+01 6.000000e+01 0.00% 0.87s
注:由于篇幅限制,此处只呈现求解日志的部分内容,目的是为了日志内容解读的需要。
按照信息项的含义,可将求解过程日志分为以下三部分内容,下面会分别解读各信息项含义:
节点(
Nodes)搜索信息(1-4列)可行解区间信息(5-7列)
求解时间信息(第8列)
节点搜索信息(1-4列):
Nodes:已搜索过的节点个数
Active:尚未被搜索的叶子节点个数
LPit/n:每个节点单纯形法(Simplex)迭代平均次数
IntInf:当前线性松弛(LP relaxtion)的解中尚未取到整数值的整数变量个数
可行解区间信息(5-7列):
BestBound:当前最优的目标边界
BestSolution:当前最优的目标函数值
Gap:上下界之间的相对容差,若小于参数RelGap的值,将会停止求解
求解时间信息(第9列):
Time:求解所用时间
注意:
Nodes第1列前的标记(H/*)表示找到了一个新的可行解。H:通过启发式(heuristic)方法找到;*:通过分支(branching)求解子问题的方法找到。
有时会看到
Nodes(已搜索过的节点个数)长时间为0,这说明COPT在处理根节点。在根节点做的工作主要有:产生割平面以及尝试多种启发式方法,以获取最优可行解,目的是减小后续搜索的规模。
求解结果汇总
这部分是求解完毕后,对MIP问题的最终求解状态和分支切割法的搜索过程进行总结,主要包括:模型求解结果和求解搜索工作量两部分内容。
Best solution : 60.000000000
Best bound : 60.000000000
Best gap : 0.0000%
Solve time : 0.87
Solve node : 2
MIP status : solved
Solution status : integer optimal (relative gap limit 0.0001)
Violations : absolute relative
bounds : 0 0
rows : 0 0
integrality : 0
求解结果:
最优目标函数值(
Best solution)最优下界(
Best bound)最优容差(
Best gap)求解状态(
Solution status)
求解搜索工作量:
求解时间(
Solve time)搜索节点个数(
Solve node)
其中 Violations 部分表示最优解对模型约束和变量范围的满足程度,其中包括:
变量(
bounds)和约束(rows)的冲突值变量整数解(
integrality)冲突值
一阶算法(PDLP)GPU求解日志
对于线性规划问题,如果选择PDLP算法(设置参数 LpMethod=6 )进行求解,则可以使用GPU求解模式(运行机器需要配置支持的GPU型号,并且部署所需的CUDA函数库)。
GPU求解模式的日志可以划分为以下几个部分,和CPU求解器略有不同,主要区别点在第2部分:
机器GPU硬件信息
一阶算法PDLP求解过程
Crossover部分
求解结果汇总部分
以LP公开测评集中 "thk_63" 这一算例为例,以下GPU求解模式的求解日志:
机器GPU硬件信息
这一部分日志会输出当前运行机器的GPU硬件信息,以及CUDA版本信息。
Hardware has 1 supported GPU device with CUDA 12.3
GPU 0: NVIDIA GeForce RTX 4090 (CUDA capability 8.9)
注意:
日志中的CUDA 12.3指的是当前安装的CUDA driver所能支持的最高版本的CUDA Toolkit。
COPT的GPU求解模式对CUDA库的最低版本要求是12.0.1。 具体请参考 常见问题章节:GPU使用相关 。
一阶算法PDLP求解过程
这一部分日志会输出PDLP算法的求解迭代过程,以及求解完成后的总结部分,包括PDLP的迭代次数,以及原问题和对偶问题的最优目标值、对偶间隙等。
Starting PDLP solver on GPU 0
Iterations Primal.Obj Dual.Obj Gap Primal.Inf Dual.Inf Time
0 +6.00000000e+00 +6.00000000e+00 +0.00e+00 7.87e+00 0.00e+00 21.63s
4000 +1.95436674e+03 -1.77166004e+03 +3.73e+03 2.09e-02 0.00e+00 33.37s
8000 +1.90433201e+03 +1.55817851e+03 +3.46e+02 1.51e-02 0.00e+00 44.75s
12000 +1.87801607e+03 +1.85689627e+03 +2.11e+01 1.74e-02 0.00e+00 56.27s
16000 +1.86810632e+03 +1.86897715e+03 +8.71e-01 4.92e-03 0.00e+00 67.72s
20000 +1.87022842e+03 +1.86994685e+03 +2.82e-01 3.42e-03 0.00e+00 79.18s
23640 +1.87099459e+03 +1.87099144e+03 +3.15e-03 4.69e-05 0.00e+00 89.68s
PDLP status: OPTIMAL
PDLP iterations: 23640
Primal objective: 1.87099459e+03
Dual objective: 1.87099144e+03
Primal infeasibility (abs/rel): 4.69e-05 / 6.20e-07
Dual infeasibility (abs/rel): 0.00e+00 / 0.00e+00
Duality gap (abs/rel): 3.15e-03 / 8.43e-07
Experimental: using crossover to find a basic solution after PDLP
Please set parameter Crossover to 0 if the basic solution is not required
Please set parameter PDLPTol to a smaller value if the crossover cleanup takes too long
Starting crossover using up to 8 threads
50320 primal pushes remaining 92.09s
12495 primal pushes remaining 97.71s
4124 primal pushes remaining 102s
202 primal pushes remaining 104s
0 primal pushes remaining 104s
1480858 dual pushes remaining 104s
589582 dual pushes remaining 106s
0 dual pushes remaining 107s
Method Iteration Objective Primal.NInf Dual.NInf Time
Dual 986011 1.8710000000e+03 0 0 107.97s
Postsolving
Dual 986011 1.8710000000e+03 0 0 110.56s
Unfolding
Dual 1036742 1.8710000000e+03 0 0 157.25s
Solving finished
Status: Optimal Objective: 1.8710000000e+03 Iterations: 1036742 Time: 157.69s
注意:使用一阶算法(PDLP)求解后,如果求解至最优( Status: Optimal ),会默认执行Crossover过程至基解,
也可设置 参数 Crossover 为0关闭)。