解决数值问题的求解器参数#
重新制定模型可能并不总是可行的,或者它可能无法完全解决数值问题。当你必须解决一个有数值问题的模型时,一些Gurobi参数可能会有所帮助。我们现在按相关性降序讨论这些参数。
预处理#
Gurobi 预解算法旨在使模型更小且更易于解决。然而,在某些情况下,预解可能会导致数值问题。以下 Python 代码可以帮助您确定是否发生了这种情况。首先,读取模型文件并打印预解模型的摘要统计信息:
m = gp.read('gurobi.rew')
p = m.presolve()
p.printStats()
如果数值范围看起来比原始模型差很多,请尝试参数 聚合=0:
m.reset()
m.Params.Aggregate = 0
p = m.presolve()
p.printStats()
如果生成的模型在数值上仍然存在问题,您可能需要使用参数Presolve=0完全禁用预求解;尝试使用上述步骤
m.reset()
m.Params.Presolve = 0
p = m.presolve()
p.printStats()
如果统计数据在使用聚合=0或预解=0时看起来更好,你应该进一步测试这些参数。对于连续(LP)模型,你可以直接测试它们。对于MIP,你应该比较使用和不使用这些参数的LP松弛。以下Python命令创建了三个LP松弛:没有预处理的模型,有预处理的模型,以及使用聚合=0的模型:
m = gp.read('gurobi.rew')
r = m.relax()
r.write('gurobi.relax-nopre.rew')
p = m.presolve()
r = p.relax()
r.write('gurobi.relax-pre.rew')
m.reset()
m.Params.Aggregate = 0
p = m.presolve()
r = p.relax()
r.write('gurobi.relax-agg0.rew')
使用这三个文件,应用之前提到的技术来确定预解=0或聚合=0是否改善了LP松弛的数值。
最后,如果Aggregate=0有助于数值计算但使模型运行过慢,可以尝试使用AggFill=0。
选择合适的算法#
Gurobi Optimizer 提供了两种主要算法来解决连续模型和混合整数模型的连续松弛问题:barrier 和 simplex。
对于大型、复杂的模型,障碍算法通常是最快的。然而,它在数值上也更为敏感。即使障碍算法收敛,通常随后进行的交叉算法也可能由于数值问题而停滞。
单纯形法通常是一个很好的替代方案,因为它通常对数值问题不太敏感。要使用对偶单纯形法或原始单纯形法,请分别将方法参数设置为1或0。
请注意,在许多优化应用中,并非所有问题实例都存在数值问题。因此,仅选择单纯形法可能会阻止您在数值表现良好的实例上利用障碍算法的性能优势。在这种情况下,您应该使用并发优化器,它同时使用多种算法,并返回第一个完成的算法的解。并发优化器是LP模型的默认设置,并且可以通过将方法参数设置为3或4来选择用于MIP。
为了详细控制并发优化器,您可以创建并发环境,在其中可以为每个并发求解设置特定的算法参数。例如,您可以创建一个使用Method=0的并发环境和另一个使用Method=1的并发环境,以同时使用原始和对偶单纯形法。最后,您可以使用分布式优化在多台不同的计算机上进行并发优化。在单台计算机上,不同的算法在多个线程上运行,每个线程使用不同的处理器核心。通过分布式优化,独立的计算机运行不同的算法,这可能会更快,因为计算机不会竞争内存访问。
使算法不那么敏感#
当所有其他方法都失败时,尝试以下参数以使算法更加稳健:
- ScaleFlag, ObjScale (All models)
最好是自己重新制定模型。然而,在不可能的情况下,这两个参数提供了一些相同的优势。设置ScaleFlag=2以进行系数矩阵的积极缩放。ObjScale重新缩放目标行;负值将使用最大的目标系数来选择缩放。例如,ObjScale=-0.5将把所有目标系数除以最大目标系数的平方根。
- NumericFocus (All models)
NumericFocus 参数控制求解器如何处理数值问题。设置1-3逐渐将重点转向更谨慎的数值计算,这可能会影响性能。NumericFocus 参数采用多种策略来改善数值行为,包括使用四倍精度和更严格的Markowitz容差。通常尝试不同的NumericFocus 值就足够了。然而,当NumericFocus 有助于数值计算但使一切变得非常慢时,您可以尝试将Quad 设置为1和/或将MarkowitzTol 设置为较大的值,例如0.1或0.5。
- NormAdjust (Simplex)
在某些情况下,求解器在使用不同的单纯形定价范数值时可能更加稳健。尝试将NormAdjust设置为0、1、2或3。
- BarHomogeneous (Barrier)
对于不可行或无界的模型,默认的障碍算法可能存在数值问题。尝试设置BarHomogeneous=1。
- CrossoverBasis (Barrier)
设置 CrossoverBasis=1 需要更多时间,但在创建初始交叉基础时可能更稳健。
- GomoryPasses (MIP)
在某些MIP模型中,Gomory割平面可能会导致数值问题。设置GomoryPasses=0可能有助于改善数值稳定性,但这可能会使MIP更难求解。
- 切割 (MIP)
在某些MIP模型中,各种切割可能会导致数值问题。设置Cuts=1或Cuts=0可能有助于数值稳定性,但可能会使MIP更难解决。
容差值(FeasibilityTol, OptimalityTol, IntFeasTol)通常对于解决数值问题没有帮助。数值问题最好通过模型重构来处理。