Поиск всех несвязанных подграфов в графе
У меня есть график, который содержит неизвестное число несвязных подграфов. Какой хороший алгоритм (или библиотека Java), чтобы найти их все?
7 ответов
Я думаю, что вы ищете, называется Заливка. Это зависит от вас, пересекаете ли вы график через BFS или DFS.
в основном вы берете немаркированный (он же неокрашенный) узел и назначаете ему новую метку. Вы назначаете одну и ту же метку всем узлам, смежным с этим, и так далее всем узлам, которые доступны из этого узла.
когда больше недоступные узлы не могут быть помечены, вы начинаете с выбора другого немаркированного узла. Обратите внимание, что тот факт, что этот новый узел не помечен, означает, что он недоступен из нашего предыдущего узла и, таким образом, находится в другом отключенном компоненте.
когда больше нет немаркированных узлов, количество различных меток, которые вы должны были использовать, - это количество компонентов графика. Метка для каждого узла указывает, какой узел является частью какого компонента.
Не реализация Java, но, возможно, это будет полезно для кого-то, вот как это сделать в Python:
import networkx as nx
g = nx.Graph()
# add nodes/edges to graph
d = list(nx.connected_component_subgraphs(g))
# d contains disconnected subgraphs
# d[0] contains the biggest subgraph
дополнительная информация здесь.
есть много аспектов этого вопроса, которые не полностью объяснены, поэтому я собираюсь дать несколько исчерпывающий ответ. Несмотря на мою склонность размещать стены текста. : / Также обратите внимание, что я предполагаю, что это вопрос домашней работы или вопрос самообразования, поэтому я не собираюсь давать прямой ответ.
два основных алгоритма обнаружения связности графа -Глубина Первого Поиска и Широта Первого Поиска. Это действительно 2 начальные точки, на которые вы хотите взглянуть. Оба приведут вас к решению, но по-разному, и трудно спорить, что "лучше", не рассматривая некоторые довольно глубокие аспекты проблемы. Но давайте двигаться дальше.
Как я уже упоминал ранее, вы упустили некоторые важные детали, и я коснусь некоторых возможностей здесь.
- Это граф, ориентированный или неориентированный? и рассматриваете ли вы связь в "сильном" смысле (в этом случае см. ответ Огги), или связь в "слабом" смысле? В зависимости от вашего ответа вам придется подойти к вашему алгоритму немного по-другому. Обратите внимание, что для неориентированного графика слабая и сильная связность эквивалентны, так что это хорошо. Но вам придется иметь в виду структуру графика независимо от того, реализуя или находя алгоритм.
кроме того, возникает вопрос о том, что вы подразумеваете под "нахождением подграфов" (перефразирование). Обычно связность графа является проблемой решения -- просто "есть один связанный граф "или"есть два или более подграфов (он же, он отключен)". Наличие алгоритма для этого требует наименьшего количества книжной работы, что приятно. :) Следующим шагом будет графа графиков, буквально их количество, и эта книжная работа тоже не так уж плоха. В предпоследнем случае вам может потребоваться список узлов в каждом подграфе. Наконец, вы можете буквально скопировать подграфы, ребра и все (так что тип возврата будет списком графы, я полагаю,с подразумеваемым инвариантом, что каждый граф связан). Ни один из этих различных типов результатов не потребует другого алгоритма, но обязательно требуется другой подход к книжной работе.
все это может показаться смешным количеством излишеств для того, что является довольно основным вопросом, но я думал, что просто выделю все аспекты, связанные даже с таким простым вопросом графика. Как некий скалолаз, обратите внимание, как это но затрагивает время выполнения или использование памяти! :) - Агор!--1-->
JGraphT - хорошая библиотека с открытым исходным кодом, лицензированная под лицензией LGPL. Я использовал его в прошлом для работы с графиками и обнаружения циклов внутри графиков. Он также довольно прост в использовании, и вы можете использовать jgraph выступает для визуализации графов.
Я предполагаю, что вы хотите найти все (сильно) связанные компоненты? Для этого вы можете использовать Тарьяна это (вариант DFS)
Как насчет широты первого поиска, чтобы найти все подключенные узлы? Как только у вас есть список подключенных узлов, вы вычитаете этот список из списка всех узлов. Вы в конечном итоге со списком отключенных узлов