Сообщение об ошибке при выполнении оптимизации Pyomo с помощью решателя cbc и использования ограничения по времени

Я пытаюсь решить проблему оптимизации с pyomo (Pyomo 5.3 (CPython 2.7.13 в Linux 3.10.0-514.26.2.el7.x86_64)) с помощью решателя CBC (Версия: 2.9.8) и указанием ограничения времени в решателе 60 сек Решатель получает выполнимое решение (-1415,8392), но, видимо, еще не оптимально (-1415,84), как вы можете видеть ниже.

После истечения срока модель, похоже, выходит с кодом ошибки. Я хочу напечатать или получить значения всех переменных допустимого решения с использованием CBC в указанный срок. Или есть какой-то другой способ, которым я могу установить, если Модель получает 99% -ное значение Оптимального решения, чтобы выйти и напечатать выполнимое решение.

Код ошибки размещен ниже.

Cbc0004I Целочисленное решение -1415,8392, найденное после 357760 итераций и 29278 узлов (47,87 секунды)
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 секунды)
Traceback (последний вызов был последним):
  Файл "model_final.py", строка 392, в 
    solver.solve(модель, ограничение по времени = 60*1, тройник =True)
  Файл "/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 вручную, используя те же параметры командной строки, что и pyomo /usr/bin/cbc -sec 60 -printingOptions all -import /tmp/tmpJK1ieR.pyomo.lp -import -stat=1 -solve -solu /tmp/tmpJK1ieR.pyomo.soln кажется, что он завершается нормально, а также записывает решение, как показано ниже.

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 Клика была опробована 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 Целочисленное решение -1411,9992, найденное с помощью сокращенного поиска после 467825 итераций и 36838 узлов (60,12 секунд). Cbc0020I Выход по максимуму время Cbc0005I Частичный поиск - лучшая цель -1411,9992 (наилучшая возможная -1415,4522), потребовалось 467825 итераций и 36838 узлов (60,12 секунды)
Cbc0032I Сильное ветвление выполнено 476 times (1776 итераций), 1 узел и фиксированные 18 переменных. Cbc0035I Максимальная глубина 21, 39 переменных, фиксированная по сниженной стоимости. Сокращения в корневом узле изменили цель с -1484.12 на -1415.45. Зондирование было опробовано 133 раза и создало 894 среза, 32 из которых были активными. после добавления раундов срезов (0,060 секунд) Гомори был опробован 133 раза и создал 1642 среза, из которых 0 были активны после добавления раундов срезов (0,047 секунд). Рюкзак был опробован 133 раза и создал 224 среза, из которых 0 были активны после добавления раундов срезы (0,083 секунды) Клика была пробована 100 раз и создала 0 срезов, из которых 0 были активны после добавления раундов срезов (0,001 секунды). MixedIntegerRounding2 был пробован 133 раза и создал 163 среза, из которых 0 были активными после добавления раундов срезов (0,034 секунды)
FlowCover был опробован 100 раз и создал 5 срезов, из которых 0 были активны после добавления раундов срезов (0,026 секунды)
TwoMirCuts был опробован 133 раза и создал 472 среза, из которых 0 были активны после добавления раундов срезов (0,021 секунд)
ImplicationCuts пробовали 25 раз и создали 41 срез, из которых 0 были активны после добавления раундов срезов (0,003 секунды). Результат - остановлен по времени. Целевое значение:                -1411,99922848 Нижняя граница:                    -1415,452 Разрыв:                            0,00 Перечисленные узлы:               36838 Всего итерации:               467825 Время (секунды ЦП):             60,13 Время (секунды настенных часов):             60,98 Общее время (секунды ЦП):             60,13   (секунды настенных часов):       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

Может кто-нибудь сказать мне, как я могу получить эти значения без каких-либо ошибок?

Заранее спасибо.

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, чтобы использовать секунды настенных часов по умолчанию из секунд ЦП, поскольку диспетчер процессов также проверяет то же самое.

Вы можете попытаться установить допустимый предел допуска, чтобы он принимал другой ответ. Я удивлен тем, что статус решателя возвращается с ошибкой, если найдено приемлемое решение. Не могли бы вы распечатать весь объект результатов?

Другие вопросы по тегам