Что такое хороший метод для случайного генерирования ребер между узлами графа?

10

Я делаю генератор случайных карт для космической игры 4X.

Каждый узел в игре находится в произвольной (x, y) координате на двумерной сетке. Узел может иметь один или несколько двунаправленных ребер для другого узла (представляющих червоточины). Все узлы должны иметь хотя бы одну червоточину, и все узлы должны принадлежать одному графику.

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

Моя наивная реализация состоит в том, чтобы перебрать все узлы и привязать узел к ближайшим 3 узлам. Тем не менее, я в конечном итоге с многочисленными подпрограммами. Какой хороший метод для создания ребер для узлов?

Extrakun
источник
как узлы разбросаны по галактике? Я имею в виду, могу ли я предположить, что для каждой точки (X, Y) в галактике есть узел? или хотя бы для большинства из них или нет?
Ali1S232 10.10.11
Не все координаты будут иметь узел. Около 40% я бы сказал.
Extrakun

Ответы:

9

Вот хороший ответ на аналогичный вопрос.

Сначала создайте связанный граф, возможно, используя минимальное связующее дерево, как в ссылке выше. Он предлагает использовать случайные веса ребер, чтобы сделать «минимальное» дерево случайным. Тогда вы можете случайным образом добавить больше ребер, чтобы это было не просто минимальное дерево. Как именно вы добавляете случайные ребра, зависит от того, какой граф вы хотите.


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

Филипп
источник
+1, так как это очень хороший ответ, но мне просто не нравится такое поколение, поэтому я буду думать о лучшем алгоритме в ближайшие несколько дней!
Ali1S232 10.10.11
Да, нет «правильного» ответа на этот вопрос, мне интересно посмотреть, что придут другие.
Филипп
Оффтоп, но я тоже собирался ссылку на свой ответ! : p
r2d2rigo
Так я получу за это очки, ха!
Филипп
7

Основные ограничения вашей проблемы двояки: создание односвязного графа; и создавая его с проксимальными связями. Ответ Филиппа, хотя и несколько ценный, не затрагивает все ограничения вашей проблемы

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

Когда вы наивно соединяете точки в облаке, вы рискуете (и к тому же высок), что эти условия не будут выполнены.

Итак, вы видите, проблема не столько в связанности, сколько в близости этих соединений. Соединить каждый узел графа с любым другим узлом тривиально, но соединить только те, которые находятся ближе всего при сохранении односвязности всего графа, немного сложнее.

Это то, что создает триангуляция Делоне в n измерениях. Первая причина использования триангуляции Делоне состоит в том, что она выполняет оба эти условия неявно. Вторая причина в том, что намного проще работать в обратном направлении от такого графа (вычитая ненужные ребра и вершины), чем пытаться создать его другими способами.

  1. Случайно создайте ваше полное облако точек.
  2. Делоне-триангулируй это.
  3. Построить график (соединение точек). При этом вы можете либо сначала сгенерировать весь график (каждую звезду), а затем получить график в виде миноров, представляющих ваши области, связанные с червоточиной, при выполнении шага 4. В качестве альтернативы вы можете работать наоборот, генерируя только области, связанные с червоточиной сначала в качестве узлов суперграфа, а затем во второй фазе, генерируют отдельные звезды в ограничивающих объемах этих областей (для них я бы вывел двойственный граф триангуляции Делоне - диаграмму Вороного в 3 измерениях) в виде подграфов. Теперь у вас есть проксимально связанные звездные скопления, и все скопления связаны более редкими червоточинами: ваша топология и топография имеют смысл для игрока.
  4. Применяйте интеллектуальные методы для формирования супер- и подграфов, в зависимости от того, как вы решили обращаться с ним на шаге 3.

Важно видеть, что это иерархический процесс. Первый уровень связан с подключением червоточины; вторая касается расстояний, по-видимому, пройденных с использованием стандартного корабля. Вы можете применить Делоне на одном или обоих уровнях, чтобы удовлетворить ваши ограничения.

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

инженер
источник
Триангуляция Делоне - хорошая идея, но она не создает случайных ребер. Вы можете произвольно удалить ребра из ребер, созданных триангуляцией Делоне, но тогда вы рискуете снова получить отдельные графики ...
bummzack
@Bummzack "Это не создает случайные края". Вы когда-нибудь слышали о несовершеннолетних графа? Если у вас есть более сложные ограничения, решаемые с помощью Делоне, тривиально выполнять добавления или удаления на этом графике по своему усмотрению.
инженер
@Bummzack, я только что обновил его - спасибо за отзыв.
инженер