Произвольно генерировать ориентированный граф на сетке


11

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

Мне нужно иметь возможность ограничить размер графика в измерениях X и Y. В примере, приведенном в ссылке, он будет ограничен сеткой 8x4.
Проблема, с которой я сталкиваюсь, заключается не в том, чтобы случайным образом генерировать граф, а в том, чтобы генерировать случайным образом граф, который я могу правильно отобразить в 2-мерном пространстве, поскольку мне нужно что-то (например, камень) на противоположной стороне узла, чтобы сделать его визуально имеет смысл, когда вы перестаете скользить. Проблема в том, что иногда порода оказывается на пути между двумя другими узлами или, возможно, на другом узле, что приводит к поломке всего графа.

Обсудив проблему с несколькими знакомыми людьми, мы пришли к нескольким выводам, которые могут привести к решению.

  • Включая препятствия в сетке как часть графика при его построении.
  • Начните с полностью заполненной сетки и просто нарисуйте случайный путь и удалите блоки, которые заставят этот путь работать.

Тогда возникает проблема выяснения, какие из них следует удалить, чтобы избежать введения более короткого пути. Мы также думали, что алгоритм динамического программирования может быть полезным, хотя никто из нас не слишком опытен в создании алгоритмов динамического программирования из ничего. Любые идеи или ссылки о том, как эта проблема официально называется (если это проблема с официальным графом), были бы наиболее полезными.

Вот несколько примеров того, чего я достиг на данный момент, просто разместив блоки в случайном порядке и сгенерировав график навигации из выбранного начала / конца. Идея (как описано в предыдущей ссылке) заключается в том, что вы начинаете с зеленого 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

Вам может понравиться игра Tsuro , она использует плитки для генерации случайной доски.


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.