【问题标题】:Why is this mixed integer program so inefficient to solve?为什么这个混合整数程序求解效率如此之低?
【发布时间】:2017-05-26 18:42:39
【问题描述】:

我正在尝试使用 GLPK 和 CBC 求解 MIP,但两个求解器都无法有效地找到解决方案。 GLPK 求解器日志显示,它可以快速找到与真正最优值相差 0.1% 以内的解决方案,但随后会花费很长时间才能找到真正的最优值。

我知道我可以使用miptol arg 来设置容差——我的问题是,这个问题会导致求解器在寻找真正的最优值时效率低下吗?我通常会用稍微不同的输入来解决这个问题的不同版本,它们会在不到一秒的时间内解决。

这是一个file with my problem specification,可以使用glpsol --cpxlp anonymizedlp.lp在GLPK中运行。

下面是一些 GLPK 日志——您会看到在 54K 次迭代中找到了一个接近最优的 MIP 解决方案,然后分支树开始不断增长:

GLPSOL: GLPK LP/MIP Solver, v4.61
Parameter(s) specified in the command line:
 --cpxlp /var/folders/g6/fs71g8j575v4_whqythqw7h40000gn/T/11446-pulp.lp -o
 /var/folders/g6/fs71g8j575v4_whqythqw7h40000gn/T/11446-pulp.sol
Reading problem data from '/var/folders/g6/fs71g8j575v4_whqythqw7h40000gn/T/11446-pulp.lp'...
664 rows, 781 columns, 2576 non-zeros
443 integer variables, 338 of which are binary
3195 lines were read
GLPK Integer Optimizer, v4.61
664 rows, 781 columns, 2576 non-zeros
443 integer variables, 338 of which are binary
Preprocessing...
213 constraint coefficient(s) were reduced
524 rows, 652 columns, 2246 non-zeros
318 integer variables, 213 of which are binary
Scaling...
 A: min|aij| =  1.282e-01  max|aij| =  1.060e+07  ratio =  8.267e+07
GM: min|aij| =  7.573e-01  max|aij| =  1.320e+00  ratio =  1.744e+00
EQ: min|aij| =  6.108e-01  max|aij| =  1.000e+00  ratio =  1.637e+00
2N: min|aij| =  3.881e-01  max|aij| =  1.355e+00  ratio =  3.491e+00
Constructing initial basis...
Size of triangular part is 524
Solving LP relaxation...
GLPK Simplex Optimizer, v4.61
524 rows, 652 columns, 2246 non-zeros
      0: obj =  -0.000000000e+00 inf =   2.507e+02 (195)
    238: obj =  -5.821025664e+06 inf =   0.000e+00 (0)
*   363: obj =  -7.015287886e+04 inf =   0.000e+00 (0) 1
OPTIMAL LP SOLUTION FOUND
Integer optimization begins...
+   363: mip =     not found yet <=              +inf        (1; 0)
+  8606: mip =     not found yet <=  -7.015289436e+04        (8239; 0)
+ 13027: mip =     not found yet <=  -7.015289436e+04        (12660; 0)
+ 16367: mip =     not found yet <=  -7.015289436e+04        (16000; 0)
+ 19135: mip =     not found yet <=  -7.015289436e+04        (18768; 0)
+ 21523: mip =     not found yet <=  -7.015289436e+04        (21156; 0)
+ 23667: mip =     not found yet <=  -7.015289436e+04        (23300; 0)
+ 25415: mip =     not found yet <=  -7.015289436e+04        (25048; 0)
+ 27260: mip =     not found yet <=  -7.015289436e+04        (26893; 0)
+ 29055: mip =     not found yet <=  -7.015289436e+04        (28688; 0)
+ 30770: mip =     not found yet <=  -7.015289436e+04        (30403; 0)
+ 32362: mip =     not found yet <=  -7.015289436e+04        (31995; 0)
Time used: 60.0 secs.  Memory used: 14.1 Mb.
+ 33876: mip =     not found yet <=  -7.015289436e+04        (33509; 0)
+ 35338: mip =     not found yet <=  -7.015289436e+04        (34971; 0)
+ 36721: mip =     not found yet <=  -7.015289436e+04        (36354; 0)
+ 38080: mip =     not found yet <=  -7.015289436e+04        (37713; 0)
+ 39372: mip =     not found yet <=  -7.015289436e+04        (39005; 0)
+ 40601: mip =     not found yet <=  -7.015289436e+04        (40234; 0)
+ 41837: mip =     not found yet <=  -7.015289436e+04        (41470; 0)
+ 43036: mip =     not found yet <=  -7.015289436e+04        (42669; 0)
+ 44192: mip =     not found yet <=  -7.015289436e+04        (43825; 0)
+ 45350: mip =     not found yet <=  -7.015289436e+04        (44983; 0)
+ 46374: mip =     not found yet <=  -7.015289436e+04        (46007; 0)
+ 47281: mip =     not found yet <=  -7.015289436e+04        (46914; 0)
Time used: 120.0 secs.  Memory used: 20.4 Mb.
+ 48220: mip =     not found yet <=  -7.015289436e+04        (47853; 0)
+ 49195: mip =     not found yet <=  -7.015289436e+04        (48828; 0)
+ 50131: mip =     not found yet <=  -7.015289436e+04        (49764; 0)
+ 51110: mip =     not found yet <=  -7.015289436e+04        (50743; 0)
+ 52131: mip =     not found yet <=  -7.015289436e+04        (51764; 0)
+ 53092: mip =     not found yet <=  -7.015289436e+04        (52725; 0)
+ 53901: >>>>>  -7.015398607e+04 <=  -7.015289436e+04 < 0.1% (53532; 0)
+ 61014: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (57365; 3302)
+ 64785: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (61136; 3302)
+ 67671: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (64022; 3302)
+ 70330: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (66681; 3302)
+ 72613: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (68964; 3302)
+ 74731: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (71082; 3302)
Time used: 180.0 secs.  Memory used: 29.9 Mb.
+ 76685: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (73036; 3302)
+ 78508: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (74859; 3302)
+ 80220: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (76571; 3302)
+ 81852: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (78203; 3302)
+ 83368: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (79719; 3302)
+ 84815: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (81166; 3302)
+ 86126: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (82477; 3302)
+ 87358: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (83709; 3302)
+ 88612: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (84963; 3302)
+ 89821: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (86172; 3302)
+ 90989: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (87340; 3302)
+ 92031: mip =  -7.015398607e+04 <=  -7.015290061e+04 < 0.1% (88382; 3302)

【问题讨论】:

    标签: linear-programming glpk integer-programming coin-or-cbc


    【解决方案1】:

    SCIP 能够在几分之一秒内解决问题。三种启发式方法(锁、移位和单选)产生越来越好的解决方案,直到达到双重界限。它是在根节点解决的,没有任何切割面。

    如果没有预求解,即删除了一半的约束和一半的二进制变量,SCIP 需要更长的时间来求解它。它仍然在根节点中解决,只添加了很少的切割平面,并且相同的启发式方法找到了 3 个整数可行解,包括最优解。

    虽然这并不能回答您关于为什么这个问题对于 GLPK 或 CBC 来说很难,但至少对于 SCIP 来说并不难,它也是开源的并且对学术界免费。很可能其中一个启发式算法没有在其他求解器中实现,因为在 SCIP 中禁用启发式算法会使找到解决方案变得更加困难 - 分支根本无法解决这个问题。

    你需要有正确的启发式。

    【讨论】:

      【解决方案2】:

      理论

      偶数0-1integer-programmingNP-hard,这基本上意味着,没有有效的算法(对于一般问题),除非P=NP

      这对您的问题意味着什么:

      这意味着,存在可以建模为 MIP 的问题,仅包含 100 个和更少的变量,并且您的求解器无法解决它(优化)。让我更清楚一点:对于你给我的每个 MIP 求解器,我可以构造一个可能有 100 个变量的实例,而你的求解器无法解决(这可以针对每个 NP 难的问题完成,尽管我们谈论的是一般这里是整数编程)。

      解决 NP-hard 问题就是使用关于您的问题和数据的假设,以便能够修剪成指数级大的搜索空间(对于每个 NP-hard 问题都需要遍历)。但是:P!=NP 的意思是,对于所有一般问题(部分相关:No free lunch theorem),没有算法可以做到这一点(利用特定于问题的东西)!结果:所有优秀的 MIP 求解器都是为解决常见问题而构建的,这对许多人来说很重要,并且由于这种良好且有用的启发式算法(例如切割平面)而被开发出来。

      所以现在我们知道,所有成功的 MIP 求解器都是启发式算法,经过调整可以更快地解决更常见的问题,并且可能在其他问题上失败(同样:没有免费午餐定理)。鉴于上述假设,这不会消失。尝试不同的求解器并调整不同的参数会有所帮助(夸张地说:不同的参数 = 不同的求解器)!

      至少还有一件事要说:

      即使我们将自己限制在一个简单的装箱问题上,也有简单的实例和困难的实例。其中一些将立即解决,而另一些则永远不会停止。 很难分析哪些实例是困难的,哪些不是。但是这些差异会在求解时间方面产生非常高的差异,这是 NP 硬度的自然结果!

      关于SAT-problem 存在一些有趣的(基于统计物理学的)研究,其中研究人员发现并量化了一个相变现象,它告诉我们,什么问题(在变量/子句比率)对于随机公式来说很难。

      (一些介绍性的博客条目涵盖了其中的一些内容:SAT Solvers: Is SAT Hard or Easy?

      练习(仅备注)

      Gurobi 和 CPLEX 等商业求解器比 CBC 和 co 强大得多。 (而且 CBC 已经是一个非常好的求解器)并且它们都为学术工作提供免费许可证。但是他们遇到了这篇文章中提到的同样的问题。

      在参数方面,应该提到的是,通常可以将参数调整为:

      • 快速找到好的解决方案(启发式高频)
      • 获得良好的边界(切割平面的高频)
      • 证明是最优的(我再次假设切割平面的 h-f,但我不确定)

      这些调音在within this excellent paper: "Practical Guideline for Solving Difficult Mixed Integer Linear Programs 有解释,你应该阅读它。

      也许还可以查看完整与不完整方法(SAT 世界中的示例:DPLL/CDCL 与随机搜索)来解决优化问题,以了解为什么某些调整更擅长一些进步 = 获得更好的目标,而另一些则更好地证明我们达到了最低限度

      【讨论】:

        猜你喜欢
        • 2010-10-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-09
        • 1970-01-01
        • 1970-01-01
        • 2015-06-30
        • 2014-09-09
        • 2013-12-18
        相关资源
        最近更新 更多