По-перше, ми можемо перетворити ваш вихідний прямокутник у комірки вашої базової сітки, щоб зробити введення більш рівномірним. (Ефективно растеризація проблеми)
Це дозволить нам знайти оптимізацію, яка може бути не очевидною при роботі безпосередньо з джерелами прямокутників, особливо коли це стосується розбиття декількох джерел прямокутників для їх комбінації по-різному.
Далі ми можемо знайти з’єднані регіони одного кольору, використовуючи алгоритми глибинного першого пошуку або заливки. Ми можемо розглядати кожну пов'язану область ( поліоміно ) окремо - ніщо, що ми робимо для іншого регіону, не повинно впливати на цю.
Ефективно ми хочемо знайти спосіб розчленувати це поліоміно на прямокутники (на жаль, більшість літератури, яку я можу знайти, стосується протилежної проблеми: розсікання прямокутників на поліміноа! Це ускладнює пошук потенційних клієнтів ...)
Один прямий метод - поєднувати горизонтальні прогони сусідніх квадратів у довгі тонкі прямокутники. Тоді ми можемо порівняти з рядком вище та поєднати, якщо наші запуски та кінці збігу збігаються - або коли ми закінчимо кожний запуск / рядок, або як вважатимемо кожну клітинку додати до поточного циклу.
Я ще не знаю, наскільки близький цей метод до оптимального. Здається, це може зіткнутися з неприємностями, коли ряд, який він ще не розглянув, пропонує інший розкол, ніж рядки, які він бачив досі:
Виявлення, коли пробіг / прямокутник точно покритий прогонами вище та нижче, потім розділення та об'єднання їх вирішить саме цей випадок, але я не дослідив, наскільки загальною є проблема.
Я також розглядав методи, де ми проходимо по периметру полиомино і вирізаємо в будь-який час, коли ми стикаємося з увігнутим кутом, але такий підхід мені здається більш схильним до помилок. Отримання оптимальних результатів, мабуть, вимагає пріоритетності розрізів, які з'єднуються у двох увігнутих кутах, а форми, що містять дуплі, потребують спеціального керування, тому метод сканування рядків, схоже, має перевагу простоти.
Ще один метод, на який я дивлюся - це зробити перший пробіг, знайдений у верхньому ряду, і продовжити його вниз, наскільки ви можете. Тоді зробіть перший пробіг у верхньому ряду того, що залишилося ... Хоча це спрацьовує на перевернуті форми Т, однак це теж не є оптимальним.
Я відчуваю, що, ймовірно, існує спосіб використовувати динамічне програмування, щоб знайти оптимальний розкол, але я його ще не знайшов.