Випадково генерувати спрямований графік на сітці


11

Я намагаюся довільно генерувати спрямований графік для того, щоб скласти головоломку, подібну до крижаних головоломок від Pokemon.
Це, по суті, те, що я хочу мати можливість випадковим чином генерувати: http://bulbanews.bulbagarden.net/wiki/Crunching_the_numbers:_Graph_theory .

Мені потрібно мати можливість обмежувати розмір графіка в розмірах x і y. У прикладі, наведеному у посиланні, воно обмежилося б сіткою 8x4.
Проблема, з якою я стикаюся, полягає не у випадковому генеруванні графіка, а у випадковому генеруванні графіка, який я можу правильно відмітити у 2d просторі, оскільки мені потрібно щось (наприклад, скеля) на протилежному боці вузла, щоб зробити це візуально має сенс, коли ви перестаєте ковзати. Проблема в цьому полягає в тому, що іноді скеля опиняється на шляху між двома іншими вузлами або, можливо, на іншому самому вузлі, через що весь графік порушується.

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

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

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

Ось кілька прикладів того, що я досяг до цього часу, лише випадковим чином розміщуючи блоки та генеруючи графік навігації з обраного початку / кінця. Ідея (як описано в попередньому посиланні) полягає в тому, що ви починаєте з зеленого S і хочете дістатися до зеленого F. Ви робите це, рухаючись вгору / вниз / вліво / вправо, і продовжуєте рухатися в обраному напрямку, поки не натиснете на стіна. На цих малюнках сірий - це стіна, білий - підлога, а фіолетова лінія - мінімальна довжина від початку до кінця, а чорні лінії та сірі крапки представляють можливі шляхи.

Ось кілька поганих прикладів випадково згенерованих графіків:

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

Ось кілька хороших прикладів випадково згенерованих (або налаштованих вручну) графіків:

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

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


1
Ви можете генерувати абсолютно випадковий набір гірських порід, а потім перевірити, чи відповідний графік має рішення, а якщо ні, то киньте його та починайте спочатку. З сіткою 8x4 це не може зайняти так довго. Я впевнений, що є більш чисті рішення.
Робота

Це був мій перший підхід, але мені потрібно зробити це в трохи більшому масштабі і грубому змушенні, здавалося, потрібно пройти деякий час і намагався знайти кращий підхід.
Talon876

Відповіді:


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

більш досконалі властивості:

  • клітини без сусідніх гірських порід недоступні (деякі можна пройти)
  • стіни теж скелі, якщо їх зняти, ви можете вирішити обгортати.
  • ви можете використовувати підмережі як візерунки ("плитка" 3x3, 3x4, 5x5, ... тощо)
  • ви можете накласти головоломку MxN плитку поверх непрохідної області MxN і додати скелю для переадресації в / з неї.
  • обертання або симетрія плитки може бути цікавою
  • ви можете розширити плитку, вставивши крижані рядки / стовпці

приклад:

S=start, E=end, o=rock, .=ice

3 . 2 o        3 . . 2 o         . . . . . o o
4 . . E   ~=   4 . . . E   ~=    . . . . . 2 E
o . . .        o . . . .         . . . . . . .
S . 1 o        S . . 1 o         S . . . . 1 o

Приклад комбінування плитки:

3 . . 2 o       o 2 . . 3      3 . . 2 o 7 . . 6
4 . . . E   +   E . . . 4  =   4 . . . . . . . 5
o . . . .       . . . . o      o . . . . . . . o
S . . 1 o       o 1 . . S      S . . 1 o 8 . . E

вам може сподобатися гра Цуро , вона використовує плитки для створення випадкової дошки.


0

Можливо, зворотна інженерія могла б допомогти вам, якщо ви за це готові.

Якщо для кожної проблеми є одне і тільки одне рішення, ви, ймовірно, можете створити графік на основі унікальної відповіді. Це не вимагатиме від вас динамічного програмування або навіть пропускання грубої сили та вибору для методичної генерації.

Ви можете зробити це за допомогою:

  1. Підготовка графіка MxN готова
  2. створення одного / декількох рішень
  3. ставити питання навколо нього, чи це сингулярна проблема вирішення
  4. якщо існує кілька варіантів вирішення проблеми, то ви можете повторити вищевказану процедуру таким чином, щоб поточна ітерація не гальмувала інший спосіб вирішення.

Хоча вам потрібно буде придумати спосіб відповідно до складності проблеми та розміру проблеми, що призведе до цього питання. Не просто йдіть на грубі сили. Спробуйте замість цього рандомізований алгоритм. Це може вам допомогти.


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

0

Як щодо іншого підходу? Почніть з порожнього лабіринту і додайте такі блоки:

  1. Випадково починаючий блок і закінчуючий блок.
  2. Зробіть 1-3 "ковзаючі" кроки у випадковому (але не поверненому) напрямку та з випадковою довжиною (*). Розташуйте блок після кожного кроку (щоб зупинити слайд).
  3. Знайдіть найкоротший шлях до виходу. Якщо сегментів занадто мало (складність низького рівня), візьміть випадковий відрізок шляху і розділіть його на блок. В іншому випадку розмістіть блок, як на кроці 1, і вийдіть.
  4. Повторіть 1 з обережністю (*): коли ви вибираєте довжину ковзаючого кроку, зробіть так, щоб введений вами блок не закривав попередній шлях.

Завершальний штрих: знайдіть найкоротший маршрут за наданим алгоритмом. Візьміть до уваги всі використовувані клітинки та почніть заповнювати решту випадковим чином, переконуючись, що найкоротший шлях не стане коротшим.

Існує застереження на другому кроці, коли ви не можете поставити останній блок, щоб він не перетинав використані шляхи, але я бачу два рішення для цього: перемістіть кінцевий блок раніше або скасуйте кілька кроків і спробуйте ще раз.

І ще одна думка щодо випадкової довжини ковзаючих кроків - ви можете вибрати її так, щоб блок, розміщений раніше, повторно використовувався, доки шляхи не перетинаються.


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