Пошук фігур у 2D-масиві та оптимізація


11

Мені щойно було дозволено зображення ... На зображенні нижче в моїй грі є деякі затемнені блоки, які були визнані частиною форми "Т". Як видно, код потемнів блоки червоними цятками, а не побачив фігури "T" із зеленими контурами.

Знайдено бажані зразки, але ще не оптимізовані

Мій код проходить цикл через x / y, позначає блоки як використані, обертає форму, повторює, змінює колір, повторює.

Я почав намагатися виправити цю перевірку з великим побоюванням. Поточна ідея:

  • проведіть через сітку та занотуйте всі події шаблону (НЕ позначаючи блоки як використовувані) та поклавши їх до масиву
  • знову проведіть через сітку, цього разу зазначивши, які блоки зайняті якими візерунками, а отже, які зайняті кількома шаблонами.
  • знову прокручуючи сітку, цього разу зазначаючи, які зразки перешкоджають, які зразки

Це дуже відчуває себе правильно ... Що мені робити зараз?

Я думаю, що мені доведеться

  • спробуйте різні комбінації конфліктуючих фігур, починаючи з тих, які перешкоджають спочатку більшості інших візерунків. Як я підходжу до цього?
  • використовуйте раціональне, що говорить, що у мене є 3 суперечливі форми, що займають 8 блоків, а фігури - по 4 блоки кожен, тому я можу мати максимум дві форми.

(Я також маю намір включити інші фігури, і, ймовірно, буде оцінка ваги, яку потрібно враховувати при переході конфліктуючих фігур, але це може бути інший день)

Я не думаю, що це проблема упаковки у смітник, але я не впевнений, на що звернути увагу. Сподіваюся, що це має сенс, дякую за вашу допомогу

EDIT Незважаючи на чіткість питань, всі, здається, зрозуміли, так,

Я хочу знайти максимум "T" фігур у кожному кольорі

(бо якби я дав тобі очки за двох, а ти зробив три, ти би трохи роздратувався)


Жадібним алгоритмом можна було розділити дошку на колекції об'єднаних блоків. Тоді для кожної колекції ви можете спробувати заповнити фігури та дати оцінку заповненню залежно від кількості блоків, які залишилися б не затемненими. Вигляд змушує мене думати про en.wikipedia.org/wiki/Knapsack_problem .
Джонатан Коннелл

2
Я думаю, що щось не вистачає у питанні. Ви хочете скласти алгоритм, який знайде якомога більше груп у формі "Т"?
Маркус фон Броаді

Якщо я вас зрозумів, ви рухаєтесь правильним шляхом. Ви не надто зрозумілі, і мені б хотілося, щоб ви могли детальніше.
AturSams

Відповіді:


3

Дозвольте мені побачити, чи правильно я зрозумів, червоними блоками були сині кольори, алгоритм знайшов форму T і позначив їх червоною, це правильно? Ваша мета - знайти якомога більше T фігур з однаковими кольоровими блоками, правильно, поки я сподіваюся. В даний час ви відзначаєте їх, як тільки ви їх знайдете, і це зменшує корисність алгоритму (Оскільки, можливо, вам не вистачить оптимального рішення). Ви плануєте шукати всі форми, а потім вибирати, які з них використовувати, а які не використовувати. Чи правильно я поки що? Тому що ви хочете максимально збільшити кількість блоків, що містяться всередині T фігур, коли алгоритм виконаний.

Якщо я маю рацію, наступне - це оптимальне рішення для вашої ситуації, на мою думку.

Ми будемо використовувати лінійне програмування Integer.

Я вважаю, що раніше це використовував:

http://sourceforge.net/projects/lpsolve/

http://lpsolve.sourceforge.net/5.5/Java/README.html

(Ви можете змусити його працювати з багатьма мовами, я використовував це з PHP, Java та C)

Що ми будемо робити, це зареєструвати всі можливі форми T на дошці, а потім використовувати ILP, щоб максимізувати кількість охоплених блоків. ІЛП експоненціально складний. Враховуючи розмір вашої дошки, це не буде проблемою. Я запускав набагато складніші запитання щодо мінімуму / максимуму на графіках з ILP, і на це знадобилося лише частку секунди і до 30-90 секунд із сотнями вершин (у вашому випадку це припадає на частку секунди).

Що я б рекомендував зробити:

  1. Знайдіть усі можливі форми ліній
  2. Знайдіть усі перетини між формами ліній одного кольору
  3. Знайдіть усі можливі форми T, шукаючи всі перетини.
  4. Визначте булеву змінну у лінійній задачі для кожної форми T ( 0 <= Bi <= 1) Оскільки значення є цілими числами, то виходить 0 або 1.
  5. Складіть умови для кожної пари Т-образів, які перетинаються ( Bi + Bj <= 1)
  6. Цільовою функцією буде (сума блоків у "T" формі (i) * Bi)
  7. Запустіть розв'язувач і затемніть Т-фігури там, де розв'язувач відповідає булевим (им), де 1 - в оптимальному рішенні.

Це цінні знання, я часто використовував лінійні розв'язувачі для робочих проектів.

ILP - це в основному спосіб вирішити проблеми вибору, коли ви хочете досягти максимуму або мінімуму для якоїсь лінійної функції.

Ви можете прочитати більше тут, використовуючи лінійне програмування Integer та лінійне програмування - це те саме для програміста, що Integer набагато складніший для комп'ютера, що може спричинити за собою тривалий час роботи. Не у вашому випадку, це дуже просто і у найгіршому випадку має займати менше мілісекунд.

Я думаю, ви можете прочитати більше тут:

http://en.wikipedia.org/wiki/Integer_linear_programming#Integer_unknowns

Це добре пояснює:

http://fisher.osu.edu/~croxton_4/tutorial/

Це в основному рішення проблеми вирішення, як приймати рішення, які максимізують бажаний результат. Це передбачає, що функція, яка оцінює результат, лінійна, що у вашому конкретному випадку це. Функція, яка оцінює результат у цьому випадку, підсумовує блоки для всіх Т-образів, які ви вирішили затемнити.

Математично, як встановити змінні: у нашому теперішньому випадку булеві (чи я затемнював форму T з індексом i чи ні) до оптимальних значень, щоб досягти максимального результату, який ми бажаємо: затемнення якомога більшої кількості блоків без потемніння, що перетинає фігури T. Поки бажаний результат можна обчислити за допомогою лінійної функції, коли у вас встановлені всі змінні, це вирішить. У нашому випадку ми перевіряємо, які форми T потемніли, і підсумовуємо блоки, які вони покривають.

введіть тут опис зображення

Я знаю, що це не банально, тому якщо ви вирішите скористатись стрибком, не соромтесь коментувати, і я докладу.


Дякую Артур за допомогу. Дайджест може зайняти кілька читань. І так, ви правильно зрозуміли проблему. Мені буде дуже цікаво, якби ти докладно розробив (ні, ні, це не банально), але це повинно допомогти мені дістатися куди я йду!
Асемблер

Яку мову ви використовуєте для реалізації?
AturSams

сценарій дій 3! всім улюблений!
Асемблер

те ж саме. Я напишу реалізацію в as3 і завантажу її в github для завантаження з коментарями, працюючи крок за кроком - я можу це зробити пізніше сьогодні
AturSams

Чи є у вас конкретні області 1 -7, де ви хочете, щоб я додав більше коментарів або детальний розгляд? btw, хороша новина для нас, любителів AS3, Adobe випустила FlasCC, який підтримує C ++, щоб ми могли легко використовувати існуючі лінійні рішення. :)
AturSams

4

Після того, як у вас з’явиться список усіх (можливо, що перекриваються) Т-образів, що виникають у вашій сітці, вам залишається максимально встановлена проблема з упаковкою .

Загалом, це проблема, яка не є повною для NP. Однак ваша сітка досить мала (і зазвичай розпадається на ще менші незалежні підпрограми), що цілком можливо здійснити для отримання точних рішень.


Додаток: Ось основний алгоритм пошуку зворотнього відстеження, який може зробити трюк:

function max_packing_recursive ( set A, set S, set M ):
    if |M| < |S| then let M = S;
    for each shape X in A do:
        remove X from A;
        let B = A;
        remove all shapes that intersect with X from B;
        if |M| < |B| + |S| + 1 then:        // upper bound
            let M = max_packing_recursive( B, S + {X}, M );
        end if
        if |M| >= |A| + |S| then return M;  // shortcut
    end for
    return M;
end function

function max_packing( set A ):
    return max_packing_recursive( A, {}, {} );
end function

Тут {X, Y, Z}позначається множина, що містить елементи X, Yі Z{}порожнім набором), і |Q|позначається розмір набору Q.

У рекурсивній функції набір Aмістить фігури, доступні для рішення, що залишилося, Sмістить фігури в поточному кандидаті рішення та Mє максимальним рішенням поки що (яке ви можете зберігати як глобальну змінну, а не повертати її назад ланцюг виклику). Важлива оптимізація - це лінія, позначена символом // upper bound, який обрізає гілки дерева пошуку, які не можуть повернути кращого рішення, ніж M.

( На насправді, так як ми знаємо , що кожен Т-образний містить рівно чотири сайти, набагато краще , верхня межа може бути отримана шляхом заміни |B|з числом різних сайтів , які охоплюються форм в B, розділених на чотири і закруглені вниз (і аналогічно для |A|на рядок, позначений символом // shortcut). Алгоритм, як зазначено вище, однак працює для довільних колекцій фігур.)

Можливою додатковою оптимізацією, яку я не реалізував вище, було б перевірити на початку рекурсивної функції, чи Aділиться на кілька підмножин незалежних, у тому сенсі, що жодна форма в різних підмножинах не перекривається, і якщо так, застосувати алгоритм для кожної підмножини окремо. (У будь-якому випадку, ви обов'язково захочете це зробити хоча б один раз на верхньому рівні перед тим, як викликати рекурсивний алгоритм.) Сортування фігур Aналежним чином перед циклом на них, наприклад, у збільшенні порядку за кількістю фігур, що перекриваються, також може допомогти .


Так, я думаю, що він міг би використати ILP, щоб вирішити це відносно безболісно через розмір проблеми .. 2 ^ 20 ~ = 1 000 000, тому оскільки може бути лише стільки форм T, він повинен бути добре, використовуючи для цього лінійний вирішувач . Це явно експоненціально складне (Принаймні, поки комусь не вдасться довести, що p = np). Розмір дозволяє уникнути евристики в цьому відносно простому випадку.
AturSams

Ільмарі, дуже дякую Ця відповідь також потребує розуміння. Біт довільних фігур цілком може бути корисним для майбутніх ітерацій.
Асемблер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.