Почему эта смешанная целочисленная программа так неэффективна?
Я пытаюсь решить MIP, используя GLPK и CBC, и ни один решатель не может найти эффективное решение. Журнал GLPK-решателя показывает, что он быстро находит решение, которое находится в пределах 0,1% от истинного оптимума, но затем он всегда пытается найти этот истинный оптимум.
Я знаю, что могу использовать miptol
Чтобы установить допуск - мой вопрос таков: что из-за этой проблемы решатель становится настолько неэффективным в поиске истинного оптимума? Я обычно решаю версии этой проблемы с немного разными входами, и они решаются менее чем за секунду.
Вот файл с моей спецификацией проблемы, который можно запустить в GLPK с glpsol --cpxlp anonymizedlp.lp
,
Ниже приведен список журнала GLPK - вы увидите, что почти оптимальное решение MIP находится в пределах 54K итераций, а затем дерево ветвей только начинает расти и расти:
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)
2 ответа
SCIP может решить проблему за доли секунды. Три эвристики (блокировки, сдвиг и oneopt) дают все более и более хорошие решения, пока двойная граница не будет достигнута. Это решается в корневом узле и без каких-либо режущих плоскостей.
Без предварительного разрешения, которое удаляет половину ограничений и половину двоичных переменных, SCIP требуется немного больше времени для ее решения. Это все еще решается в корневом узле с добавлением очень небольшого числа плоскостей резания, и та же эвристика находит 3 возможных целочисленных решения, включая оптимальное.
Хотя это не отвечает на ваш вопрос о том, почему эта проблема трудна для GLPK или CBC, по крайней мере это не сложно для SCIP, который также является открытым исходным кодом и бесплатен для ученых. Скорее всего, одна из эвристик не реализована в других решателях, потому что отключение эвристики в SCIP затрудняет поиск решения - ветвление просто не решает эту проблему.
Вы должны иметь правильную эвристику.
теория
Даже целочисленное программирование 0-1 является NP-сложным, что в основном означает, что нет эффективного алгоритма (для общей проблемы), если только P=NP
,
Что это значит для вашей проблемы:
Это означает, что существуют проблемы, которые могут быть смоделированы как MIP, содержат только 100 переменных и менее, и ваш решатель не может решить их (до оптимального уровня). Позвольте мне быть более ясным: для каждого MIP-решателя, который вы мне даете, я могу создать экземпляр из, возможно, 100 переменных, которые ваш решатель не может решить (это можно сделать для любой задачи, которая является NP-трудной, хотя мы говорим об общем целочисленное программирование здесь).
Подход к NP-сложным задачам сводится к использованию предположений о вашей проблеме и ваших данных, чтобы иметь возможность сократить экспоненциально большое пространство поиска (которое необходимо обходить для каждой NP-сложной задачи). Но: P!=NP
означает, что не существует алгоритма, который мог бы сделать это (используя преимущества специфических для проблемы вещей) для всех проблем в целом (частично связанных: нет теоремы о бесплатном обеде)! Следствие: все хорошие MIP-решатели созданы для решения общих проблем, которые важны для многих людей и где из-за этого была разработана хорошая и полезная эвристика (например, плоскости резания).
Итак, теперь мы знаем, что все успешные MIP-решатели - это эвристики, настроенные на более быстрое решение более распространенных проблем, и могут решительно провалиться в других задачах (опять-таки: теорема о бесплатном обеде отсутствует). Это не пройдет, учитывая вышеизложенные предположения. Может помочь попытка использования разных решателей и настройка разных параметров (раздраженно: разные параметры = разные решатели)!
Есть по крайней мере еще одна вещь, чтобы сказать:
Даже если мы ограничимся, скажем, простой проблемой упаковки мусора, существуют простые и сложные случаи. Некоторые из них будут решены мгновенно, а другие никогда не остановятся. Очень сложно проанализировать, какие случаи сложны, а какие нет. Но эти различия влияют на, возможно, очень высокую дисперсию в отношении времени решения, что является естественным следствием твердости NP!
Существуют некоторые интересные (основанные на статистической физике) исследования по проблеме SAT, в которых исследователи обнаружили и количественно оценили явление фазового перехода, которое говорит нам, какие проблемы (с точки зрения соотношения переменная / предложение) сложны в отношении случайных формулы.
(Некоторые вступительные записи в блоге, охватывающие некоторые из них: SAT Solvers: SAT сложно или легко?
Практика (только замечания)
Коммерческие решатели, такие как Gurobi и CPLEX, намного мощнее, чем CBC и co. (и CBC уже очень хороший решатель), и они оба предоставляют бесплатные лицензии для академической работы. Но они испытывают те же проблемы, упомянутые в этом посте.
Что касается параметров, следует отметить, что параметры в целом могут быть настроены на:
- быстро найти хорошее решение (высокая частота эвристики)
- получить хорошие оценки (высокая частота резки)
- доказать оптимальность (я предполагаю, что снова есть режущие плоскости, но я не уверен)
Подобные настройки объясняются в этой замечательной статье: "Практическое руководство по решению сложных смешанных целочисленных линейных программ, и вам следует прочитать его".
Возможно также проверить полные или неполные методы (например, в мире SAT: DPLL/CDCL или стохастический поиск) для решения задач оптимизации, чтобы понять, почему некоторые настройки лучше в достижении некоторого прогресса = становятся лучше объективными, в то время как другие лучше в доказательстве мы достигли минимума.