Эта проблема появилась в challenge, но поскольку она теперь закрыта, должно быть хорошо спросить об этом.
Проблема (не этот вопрос сам по себе, это просто справочная информация) можно визуально описать так, заимствуя их собственный образ:
Я решил решить его оптимально. Это возможно (для варианта решения) NP-полная проблема (это конечно в NP, и это пахнет как точная обложка, хотя я не доказал, что общая точная проблема покрытия может быть сведена к ней), но это прекрасно, она должна быть быстрой на практике, не обязательно в худшем случае. В контексте этого вопроса меня не интересуют какие-либо алгоритмы аппроксимации, если они не обеспечивают разрезы.
Существует очевидная модель ILP: генерировать все возможные квадраты (квадрат возможен, если он охватывает только ячейки сетки, которые присутствуют), ввести двоичную переменную x_i
для каждого квадрата, указывающую, используем мы ее или нет, затем
minimize sum x_i
subject to:
1) x_i is an integer
2) 0 ≤ x_i ≤ 1
3) for every cell c
(sum[j | c ϵ square_j] x_j) = 1
Ограничение 3 говорит, что каждая ячейка покрывается ровно один раз. Ограничения 1 и 2 делают x_i двоичным. Минимальное решение дает оптимальное решение исходной задачи.
Линейная релаксация этого (т.е. игнорирование ограничения 1) является наполовину приличной, но она делает такие вещи (это сетка 6x6 с отсутствием верхнего левого угла):
Здесь 13 квадратов были выбраны "наполовину" (давая объективное значение 6,5), размеров (чтобы вы могли быстрее найти их)
- 1 из 4x4
- 3 из 3x3
- 6 из 2x2
- 3 из 1x1
Оптимальное решение для этого экземпляра имеет объективное значение 8, например:
Линейная релаксация наполовину приличная, но я не совсем ей доволен. Разрыв иногда превышает 10%, что иногда приводит к очень медленной целочисленной фазе.
Что там, где возникает реальный вопрос, существуют ли дополнительные ограничения, которые я могу добавить (лениво) в виде разрезов, чтобы улучшить дробное решение?
Я пробовал альтернативные формулировки проблемы для поиска разрезов, например, вместо выбора квадратов, что, если мы выберем "левые верхние углы" и "правые нижние углы", которые затем должны быть сопоставлены, перекрывающиеся квадраты, которые покрывают все ячейки? Затем на каждой диагонали с обратной косой чертой должно быть соответствующее число левого и правого нижних углов. Но это не помогает, потому что, если мы выберем квадраты, тогда это условие всегда истинно, также в дробных решениях.
Я также пробовал некоторые рассуждения о перекрытиях, например, если два квадрата перекрываются, их сумма не должна быть больше 1, и это можно улучшить, добавив все квадраты, полностью содержащиеся в области перекрытия. Но это ограничение менее мощно, чем ограничение, что все ячейки будут покрыты ровно один раз.
Я пробовал рассуждать об общей площади (как и в случае, общая покрытая площадь должна быть равна числу ячеек), но это уже гарантировано ограничением, что каждая ячейка должна быть покрыта один раз, заявив ее в терминах общая площадь позволяет больше свободы.
Я также пытался что-то сделать с квадратными числами (площадь каждого квадрата, ну, квадрат) и различия квадратных чисел, но это также не закончилось ничем полезным.