У меня есть график со следующими атрибутами:
Я ищу пути между случайным подмножеством вершин (по крайней мере 2). Пути должны простые контуры, которые только проходят любую вершину однажды.
Моя конечная цель должна иметь ряд маршрутов так, чтобы можно было запустить в одной из вершин подмножества и достигнуть любой из других вершин подмножества. Не необходимый для прохождения через все узлы подмножества при следовании за маршрутом.
Все алгоритмы, которые я нашел (Dijkstra, Поиск в глубину и т.д.), кажется, имеют дело с путями между двумя вершинами и кратчайшими путями.
Существует ли известный алгоритм, который даст мне все пути (я предполагаю, что это подграфы), которые соединяют их подмножество вершин?
править:
Я создал (предупреждение! искусство программиста), анимировал gif для иллюстрирования то, чего я пытаюсь достигнуть: http://imgur.com/mGVlX.gif
Существует два этапа, предварительно обрабатывают и время выполнения.
Таким образом, моя задача больше о создании всех подграфов (маршруты), которые соединяют все синие узлы, вместо того, чтобы создать путь из A-> B.
Есть так много способов подойти к этому, и, чтобы не путать вещи, вот отдельный ответ, посвященный описанию вашей основной проблемы:
Поиск ВСЕ возможные подграфы, которые соединяют ваши синие вершины, вероятно, будут излишними, если вы все равно собираетесь использовать только по одному. Я бы предпочел использовать алгоритм, который находит один, но случайным образом (то есть не какой-либо алгоритм кратчайшего пути или что-то подобное, поскольку он всегда будет одинаковым).
Если вы хотите сохранить один из этих подграфов, вам просто нужно сохранить начальное число, которое вы использовали для генератора случайных чисел, и вы снова сможете создать тот же подграф.
Кроме того, если вы действительно хотите найти кучу подграфов, рандомизированный алгоритм по-прежнему является хорошим выбором, поскольку вы можете запускать его несколько раз с разными начальными числами.
Единственным реальным недостатком является то, что вы никогда не узнаете, нашли ли вы каждый из возможных подграфов, но на самом деле это не похоже на требование для вашего приложения.
Итак, перейдем к алгоритму: в зависимости от свойств вашего графа (ов) оптимальный алгоритм может варьироваться, но вы всегда можете начать с простого случайного блуждания, начиная с одного синего узла, переходя к другому синему узлу. (при этом убедитесь, что вы не идете по своим старым стопам). Затем выберите случайный узел на этом пути и начните оттуда переходить к следующему синему и так далее.
Для некоторых графиков это имеет очень плохую сложность наихудшего случая, но может быть достаточным для вашего случая. Конечно, есть более разумные способы найти случайные пути, но я бы начал с легкости и посмотрел, достаточно ли он хорош. Как говорится, преждевременная оптимизация - зло;)
Простой поиск в ширину даст вам кратчайшие пути от одной исходной вершины ко всем остальным вершинам. Таким образом, вы можете выполнить BFS, начиная с каждой вершины в интересующем вас подмножестве, чтобы получить расстояния до всех остальных вершин.
Обратите внимание, что в некоторых местах BFS описывается как указывающий путь между парой вершин, но в этом нет необходимости: вы можете продолжать запускать его, пока он не посетит все узлы в графе.
Этот алгоритм похож на алгоритм Джонсона , но значительно упрощен благодаря тому, что ваш график невзвешен.
Временная сложность : Поскольку количество ребер на вершину постоянно, каждая BFS займет O (n), а общая сумма будет равна O (kn), где n - количество вершин, а k - размер подмножества. Для сравнения, алгоритм Floyd-Warshall принимает значение O (n ^ 3).
Вы ищете (если я правильно понимаю) не все пути , а все охватывающие деревья . Прочтите статью в Википедии о связующих деревьях здесь , чтобы определить, нужны ли они вам. Если да, то есть статья, которую вы, вероятно, захотите прочитать: