web-dev-qa-db-fra.com

Trouver tous les sous-graphiques déconnectés dans un graphique

J'ai un graphique qui contient un nombre inconnu de sous-graphes déconnectés. Qu'est-ce qu'un bon algorithme (ou Java bibliothèque) pour les trouver tous?

37
Ollie Glass

Je pense que ce que vous cherchez est généralement appelé A Remplissage des inondations . C'est à vous de décider si vous parcourez le graphique à travers un BFS ou un DFS.

Fondamentalement, vous prenez un nœud non étiqueté (aka non coloré) et attribuez-y une nouvelle étiquette. Vous attribuez la même étiquette à tous les nœuds adjacents à celui-là, et ainsi de suite à tous les nœuds accessibles à partir de ce nœud.

Lorsqu'il n'y a plus de nœuds accessibles ne peut être étiqueté, vous recommencez en cueillant un autre nœud non étiqueté. Notez que le fait que ce nouveau nœud est non étiqueté implique qu'il n'est pas accessible de notre noeud antérieur et est donc dans un composant déconnecté différent.

Lorsqu'il n'y a plus de nœuds non complets, le nombre d'étiquettes distinctes que vous avez dû utiliser est le nombre de composants du graphique. L'étiquette pour chaque nœud vous indique quel nœud fait partie de laquelle composant.

55
MAK

Pas un Java Mise en œuvre mais peut-être qu'il sera utile pour quelqu'un, voici comment le faire en 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

Plus d'informations ICI .

17
Datageek

Il existe de nombreuses facettes de cette question qui ne sont pas complètement expliquées, alors je vais donner une réponse quelque peu exhaustive. Ma tendance à poster des murs-du-texte nonobstant. :/Notez également que je suppose que cela constitue une question de devoirs ou une question d'auto-éducation, donc je ne vais pas donner une réponse simple.

Les deux algorithmes de base pour détecter la connectivité d'un graphique sont Profond First Search et première recherche d'une première recherche . Ce sont vraiment les 2 points de départ que vous souhaitez regarder. Les deux vous amèneront à la solution, mais de différentes manières, et c'est difficile à discuter, ce qui est "mieux" sans considérer certains aspects assez approfondis du problème. Mais passons à autre chose.

Comme je l'ai déjà mentionné, vous avez laissé des détails importants et je vais aborder des possibilités ici.

Votre graphique est-il dirigé ou non dirigé? Et considérez-vous la connectivité dans le sens "fort" (auquel cas, voir la réponse d'Oggy) ou la connectivité du sens "faible"? Selon votre réponse, vous devrez aborder votre algorithme de manière subtile différente. Notez que, pour un graphique non dirigé, une connectivité faible et forte est équivalente, c'est bien. Mais vous devrez garder la structure du graphique à l'esprit, tout en mettant en œuvre ou à trouver un algorithme.

De plus, il y a la question de savoir ce que vous entendez par "trouver les sous-graphes" (paraphrase). Habituellement, la connectivité graphique est un problème de décision - simplement "il y a un graphique connecté" ou "il y a deux sous-graphiques ou plus (AKA, il est déconnecté)". Avoir un algorithme pour cela nécessite le moins de rétrograder, ce qui est agréable. :) L'étape suivante serait le nombre des graphiques, littéralement le nombre d'entre eux et que ce librairie n'est pas aussi mauvais. Un avant-dernier, vous pouvez vouloir une liste de nœuds dans chaque sous-graphique. Enfin, vous voudrez peut-être copier littéralement les sous-graphiques, les bords et tous (le type de retour serait donc une liste de graphiques, je suppose, avec un invariant implicite que chaque graphique est connecté). Aucun de ces types de résultats différents ne nécessiterait un algorithme différent, mais sera certainement nécessite une approche différente de la librairie.

Tout cela peut sembler comme une quantité ridicule de surkilleuse pour une question assez fondamentale, mais je pensais que je soulignerais tout simplement tous les aspects impliqués dans une question de graphique unique. Comme une sorte de cliffhanger, notez comment rien de tout cela n'est même pas encore atteint lors de l'utilisation de l'heure ou de la mémoire! :) - Agor

8
agorenst

JGRAPHT est une belle bibliothèque graphique open source sous licence sous la licence LGPL. Je l'ai utilisé dans le passé pour faire face aux graphiques et à la détection de cycles dans les graphiques. Il est également assez facile à utiliser et vous pouvez utiliser jgraph pour visualiser les graphiques.

3
aperkins

Je suppose que vous voulez trouver tous les composants (fortement) connectés? Pour cela, vous pouvez utiliser algorithme de Tarjan (une variante de DFS)

2
oggy

Qu'en est-il d'une première recherche d'une largeur pour trouver tous les nœuds connectés? Une fois la liste des nœuds connectés, vous soustrayez cette liste dans la liste de tous les nœuds. Vous vous retrouvez avec une liste de nœuds déconnectés

1
MedicineMan

J'ai rencontré un problème similaire où je voulais tous les sous-gradins faiblement connectés d'un graphique dirigé. J'ai blogué à ce sujet ici . J'ai utilisé le JUNG API et comparez deux approches. Ma première approche pourrait être utilisée comme modèle pour résoudre votre problème.

1
harschware