Графовый алгоритм для нахождения всех путей между N произвольными вершинами - PullRequest
6 голосов
/ 27 апреля 2010

У меня есть график со следующими атрибутами:

  • неориентированный
  • Не взвешенный
  • Каждая вершина имеет минимум 2 и максимум 6 ребер, связанных с ней.
  • Количество вершин будет <100 </li>
  • График статичен, и вершины / ребра нельзя добавлять / удалять или редактировать.

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

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

Все алгоритмы, которые я нашел (Dijkstra, поиск в глубину и т. Д.), Похоже, имеют дело с путями между двумя вершинами и кратчайшими путями.

Есть ли известный алгоритм, который даст мне все пути (я полагаю, это подграфы), которые соединяют эти подмножества вершин?

редактирование:

Я создал анимированный GIF (предупреждение! Искусство программиста), чтобы проиллюстрировать, чего я пытаюсь достичь: http://imgur.com/mGVlX.gif

Есть две стадии предварительной обработки и выполнения.

предварительной обработки

  1. У меня есть граф и подмножество вершин (синие узлы)
  2. Я генерирую все возможные маршруты, которые соединяют все синие узлы

выполнения

  1. Я могу начать с любого синего узла, выбрать любой из сгенерированных маршрутов и пройти по нему, чтобы добраться до моего синего узла назначения.

Итак, моя задача больше о создании всех подграфов (маршрутов), которые соединяют все синих узлов, а не о создании пути из A-> B.

Ответы [ 3 ]

1 голос
/ 28 апреля 2010

То, что вы ищете, это (если я правильно понимаю) не все пути , а скорее все охватывающие деревья . Прочтите статью википедии о связующих деревьях здесь , чтобы определить, ищите ли вы их. Если это так, есть бумага, которую вы, вероятно, захотите прочитать:

Gabow, Harold N .; Майерс, Юджин В. (1978). «Поиск всех связующих деревьев ориентированных и неориентированных графов». SIAM J. Comput. 7 (280).

1 голос
/ 29 апреля 2010

Есть много способов подойти к этому, и чтобы не путать вещи, вот отдельный ответ, посвященный описанию вашей основной проблемы:

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

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

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

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

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

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

1 голос
/ 27 апреля 2010

Простой поиск в ширину даст вам кратчайшие пути от одной исходной вершины ко всем остальным вершинам. Таким образом, вы можете выполнить BFS, начиная с каждой вершины интересующего вас подмножества, чтобы получить расстояния до всех остальных вершин.

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

Этот алгоритм аналогичен алгоритму Джонсона , но значительно упрощен благодаря тому, что ваш график не взвешен.

Сложность времени : поскольку в каждой вершине имеется постоянное число ребер, каждая BFS будет принимать O (n), а общее количество - O (kn), где n - количество вершин k - размер подмножества. Для сравнения: алгоритм Floyd-Warshall будет принимать O (n ^ 3).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...