【问题标题】:Error reported while running pyomo optimization with cbc solver and using timelimit使用 cbc 求解器运行 pyomo 优化并使用 timelimit 时报告错误
【发布时间】:2017-11-16 16:08:52
【问题描述】:

我正在尝试使用 CBC 求解器(版本)解决 pyomo 的优化问题(Pyomo 5.3(Linux 3.10.0-514.26.2.el7.x86_64 上的 CPython 2.7.13)) : 2.9.8) 并在求解器中指定 60 秒的时间限制。求解器得到了一个可行的解决方案 (-1415.8392),但显然还不是最优的 (-1415.84),如下所示。

时间限制结束后,模型似乎退出并显示错误代码。我想在指定的时间限制内使用 CBC 打印或获取可行解决方案的所有变量的值。或者是否有其他方法可以设置,如果模型获得 99% 的最优解值,则退出并打印可行解。

错误代码贴在下面。

Cbc0004I 在 357760 次迭代和 29278 个节点(47.87 秒)后找到 -1415.8392 的整数解 Cbc0010I 在 30000 个节点之后,树上 6350 个,-1415.8392 最佳解决方案,最佳可能 -1415.84(48.87 秒) Cbc0010I 在 31000 个节点之后,树上 6619 个,-1415.8392 最佳解决方案,最佳可能 -1415.84(50.73 秒) Cbc0010I 在 32000 个节点之后,树上 6984 个,-1415.8392 最佳解决方案,最佳可能 -1415.84(52.49 秒) Cbc0010I 在 33000 个节点之后,树上 7384 个,-1415.8392 最佳解决方案,最佳可能 -1415.84(54.31 秒) Cbc0010I 在 34000 个节点之后,树上 7419,-1415.8392 最佳解决方案,最佳可能 -1415.84(55.73 秒) Cbc0010I 在 35000 个节点之后,树上 7824 个,-1415.8392 最佳解决方案,最佳可能 -1415.84(57.37 秒) 回溯(最近一次通话最后): 文件“model_final.py”,第 392 行,在 solver.solve(模型,时间限制= 60 * 1,三通=真) 文件“/home/aditya/0r/lib/python2.7/site-packages/pyomo/opt/base/solvers.py”,第 655 行,在求解 default_variable_value=self._default_variable_value) 文件“/home/aditya/0r/lib/python2.7/site-packages/pyomo/core/base/PyomoModel.py”,第 242 行,在 load_from % str(results.solver.status)) ValueError:无法加载状态不佳的 SolverResults 对象:错误

当我使用与 pyomo /usr/bin/cbc -sec 60 -printingOptions all -import /tmp/tmpJK1ieR.pyomo.lp -import -stat=1 -solve -solu /tmp/tmpJK1ieR.pyomo.soln 相同的命令行参数手动运行 pyomo 生成的模型时,它似乎正常退出并且还编写了如下所示的解决方案。

Cbc0010I 在 35000 个节点之后,树上 7824 个,-1415.8392 最佳解决方案,最佳可能 -1415.84(57.06 秒) Cbc0038I 完全问题 205 行 289 列,减少到 30 行 52 列 Cbc0010I 在 36000 个节点之后,树上 8250 个,-1415.8392 最佳解决方案,最佳可能 -1415.84(58.73 秒) Cbc0020I 以最长时间退出 Cbc0005I 部分搜索 - 最佳目标 -1415.8392(最佳可能 -1415.84),进行了 464553 次迭代和 36788 个节点(60.11 秒) Cbc0032I 强分支完成 15558 次(38451 次迭代),测算 350 个节点并固定 2076 个变量 Cbc0035I 最大深度 203、5019 个变量固定在降低的成本上 Cbc0038I 探测尝试了 31933 次并创建了 138506 个切割,其中 0 个在添加切割轮次后处于活动状态(4.431 秒) Cbc0038I Gomory 尝试了 30898 次并创建了 99534 个剪辑,其中 0 个在添加轮次剪辑后处于活动状态(4.855 秒) Cbc0038I 背包尝试了 30898 次并创建了 12926 个剪辑,其中 0 个在添加几轮剪辑后处于活动状态(8.271 秒) Cbc0038I Clique 尝试了 100 次并创建了 0 个剪辑,其中 0 个在添加几轮剪辑后处于活动状态(0.000 秒) Cbc0038I MixedIntegerRounding2 尝试了 30898 次并创建了 13413 个切割,其中 0 个在添加切割轮后处于活动状态(3.652 秒) Cbc0038I FlowCover 尝试了 100 次并创建了 4 个剪辑,其中 0 个在添加几轮剪辑后处于活动状态(0.019 秒) Cbc0038I TwoMirCuts 尝试了 30898 次并创建了 15292 个剪辑,其中 0 个在添加几轮剪辑后处于活动状态(2.415 秒) Cbc0038I 从第一个开始存储已尝试 30898 次并创建了 15734 个剪辑,其中 0 个在添加剪辑轮次后处于活动状态(0.000 秒) Cbc0012I 在 467825 次迭代和 36838 个节点(60.12 秒)后通过缩减搜索找到 -1411.9992 的整数解 Cbc0020I 以最长时间退出 Cbc0005I 部分搜索 - 最佳目标 -1411.9992(可能的最佳 -1415.4522),进行了 467825 次迭代和 36838 个节点(60.12 秒) Cbc0032I 强分支完成 476 次(1776 次迭代),测透 1 个节点并固定 18 个变量 Cbc0035I 最大深度 21,39 个变量固定在降低的成本上 根节点处的切割将目标从 -1484.12 更改为 -1415.45 探测尝试了 133 次并创建了 894 个切割,其中 32 个在添加多轮切割后处于活动状态(0.060 秒) Gomory 被尝试了 133 次并创建了 1642 次剪辑,其中 0 次在添加轮次后处于活动状态(0.047 秒) 背包尝试了 133 次并创建了 224 次切割,其中 0 次在添加轮次切割后处于活动状态(0.083 秒) Clique 尝试了 100 次并创建了 0 个剪辑,其中 0 个在添加几轮剪辑后处于活动状态(0.001 秒) MixedIntegerRounding2 尝试了 133 次并创建了 163 个剪辑,其中 0 个在添加几轮剪辑后处于活动状态(0.034 秒) FlowCover 尝试了 100 次并创建了 5 个剪辑,其中 0 个在添加几轮剪辑后处于活动状态(0.026 秒) TwoMirCuts 尝试了 133 次并创建了 472 个剪辑,其中 0 个在添加轮次剪辑后处于活动状态(0.021 秒) ImpplicationCuts 尝试了 25 次并创建了 41 个剪辑,其中 0 个在添加轮次剪辑后处于活动状态(0.003 秒) 结果 - 按时停止 目标值:-1411.99922848 下限:-1415.452 差距:0.00 枚举节点:36838 总迭代次数:467825 时间(CPU 秒):60.13 时间(挂钟秒):60.98 总时间(CPU 秒):60.13(Wallclock 秒):61.01

CBC 解决方案文件的前几行是:

准时停止 - 目标值 -1411.99922848 0 c_e_x1454_ 0 0 1 c_e_x1455_ 0 0 2 c_e_x1456_ 0 0 3 c_e_x1457_ 0 0 4 c_e_x1458_ 0 0 5 c_e_x1459_ 0 0 6 c_e_x1460_ 0 0 7 c_e_x1461_ 0 0 8 c_e_x1462_ 0 0

谁能告诉我如何在不产生任何错误的情况下获取这些值?

提前致谢。

【问题讨论】:

    标签: python-2.7 pyomo coin-or-cbc


    【解决方案1】:

    您可以尝试设置边界间隙容差,使其接受其他答案。如果找到可行的解决方案,我很惊讶求解器状态会返回错误。你能打印出整个结果对象吗?

    【讨论】:

    • 谢谢齐。使用绑定间隙我可以让 pyomo 打印解决方案。事实上,间隙为 0.001 的解决方案只需 10 秒的运行时间即可打印出来。但是,对于适当的关闭,我仍然想处理模型无法在合理时间内达到足够接近的解决方案的情况。您对此还有其他建议吗?
    • 看起来 CBC 插件可能无法正确处理此终止条件,或者 CBC 可能在由于时间限制而停止时更改了打印内容。 github.com/Pyomo/pyomo/blob/master/pyomo/solvers/plugins/…SolutionStatus.stoppedByLimit 的测试可能不会被触发。
    • 我为您打开了一个问题。欢迎您填写您想要的更多详细信息:github.com/Pyomo/pyomo/issues/256
    【解决方案2】:

    创建了一个拉取请求https://github.com/Pyomo/pyomo/pull/265 来解决这个问题。

    对于那些立即想要补丁的人:

    在文件 pyomo/solvers/plugins/solvers/CBCplugin.py

    @@ -264,7 +264,8 @@ def _check_and_escape_options(options):
                 cmd.append('-AMPL')
    
                 if self._timelimit is not None and self._timelimit > 0.0:
    -                cmd.extend(['-sec', str(self._timelimit)])
    +                cmd.extend(['-sec', str(self._timelimit - 1 )])
    +                cmd.extend(['-timeMode', "elapsed"])
                 if "debug" in self.options:
                     cmd.extend(["-log","5"])
                 for key, val in _check_and_escape_options(self.options):
    @@ -276,7 +277,8 @@ def _check_and_escape_options(options):
                             #"-stat"])
             else:
                 if self._timelimit is not None and self._timelimit > 0.0:
    -                cmd.extend(['-sec', str(self._timelimit)])
    +                cmd.extend(['-sec', str(self._timelimit - 1 )])
    +                cmd.extend(['-timeMode', "elapsed"])
                 if "debug" in self.options:
                     cmd.extend(["-log","5"])
                 # these must go after options that take a value
    

    时间限制设置为比提供的选项低 1 秒,以确保 CBC 进程有时间在 pyutilib.subprocess.processmngr 检查退出代码之前正确退出。在我的测试运行中,进程管理器在 T+0.02 秒时检查了退出状态,而 CBC 进程通常在 T+0.1 秒后退出。

    还更改了 CBC 代码以使用默认 CPU 秒数的挂钟秒数,因为进程管理器也在检查相同的时间。

    【讨论】:

      猜你喜欢
      • 2020-03-09
      • 1970-01-01
      • 2018-12-23
      • 1970-01-01
      • 1970-01-01
      • 2018-03-17
      • 1970-01-01
      • 2018-11-29
      • 2021-09-23
      相关资源
      最近更新 更多