Comment représenter proprement un graphe en Python ? (À partir de zéro, c'est-à-dire pas de bibliothèques!)
Quelle structure de données (par exemple dicts / tuples / dict (tuples)) sera rapide mais aussi efficace en mémoire?
Il faut pouvoir y effectuer diverses opérations graphiques .
Comme indiqué, les différentes représentations graphiques peuvent aider. Comment les implémenter en Python?
Quant aux bibliothèques, cette question a d'assez bonnes réponses.
python
data-structures
graph
shad0w_wa1k3r
la source
la source
dict
delist
s. Fondamentalement, quelque chose comme{<parent>: [<child>, ...], ...}
.Réponses:
Même si c'est une question un peu ancienne, j'ai pensé donner une réponse pratique à quiconque trébucherait dessus.
Disons que vous obtenez vos données d'entrée pour vos connexions sous la forme d'une liste de tuples comme ceci:
La structure de données que j'ai trouvée la plus utile et la plus efficace pour les graphiques en Python est un dict d'ensembles . Ce sera la structure sous-jacente de notre
Graph
classe. Vous devez également savoir si ces connexions sont des arcs (dirigés, connecter dans un sens) ou des arêtes (non dirigés, connecter dans les deux sens). Nous allons gérer cela en ajoutant undirected
paramètre à laGraph.__init__
méthode. Nous ajouterons également d'autres méthodes utiles.Je vais le laisser comme un "exercice pour le lecteur" pour créer une
find_shortest_path
méthode et d'autres.Voyons cela en action cependant ...
la source
heapq
lib pour heapifier des listes de tuples au lieu d'ensembles. Par exemple, le graphe serait un dict de tas comme:_graph = {'A': heapify([(0.3, 'D'), (0.5, 'B'), (0.75, 'A'), (0.9, 'C')])}
(note: vous n'utiliseriez pas réellementheapify
comme ceci, lisez l'aide pour la lib), alors vous pourriez utiliser lesheapq
fonctions pour insérer et obtenir les arêtes pondérées.log
accès horaire. Mais comment étendre le dictionnaire que vous avez utilisé pour mapper à la fois nodeID et weight?NetworkX est une superbe bibliothèque de graphes Python. Vous aurez du mal à trouver quelque chose dont vous avez besoin et qu'il ne fait pas déjà.
Et c'est open source afin que vous puissiez voir comment ils ont implémenté leurs algorithmes. Vous pouvez également ajouter des algorithmes supplémentaires.
https://github.com/networkx/networkx/tree/master/networkx/algorithms
la source
graph.py --> class Graph
. Et tout ce que je veux voir, c'est comment ils utilisent__iter__
.Premièrement, le choix des représentations classiques par liste ou par matrice dépend du but (de ce que vous voulez faire de la représentation). Les problèmes et algorithmes bien connus sont liés au choix. Le choix du type de représentation abstraite dicte comment il doit être implémenté.
Deuxièmement, la question est de savoir si les sommets et les arêtes doivent être exprimés uniquement en termes d'existence, ou s'ils portent des informations supplémentaires.
Du point de vue des types de données intégrés Python, toute valeur contenue ailleurs est exprimée sous la forme d'une référence (masquée) à l'objet cible. S'il s'agit d'une variable (c'est-à-dire d'une référence nommée), le nom et la référence sont toujours stockés dans un dictionnaire (interne). Si vous n'avez pas besoin de noms, alors la référence peut être stockée dans votre propre conteneur - ici probablement la liste Python sera toujours utilisée pour la liste comme abstraction.
La liste Python est implémentée comme un tableau dynamique de références, le tuple Python est implémenté comme un tableau statique de références avec un contenu constant (la valeur des références ne peut pas être modifiée). Pour cette raison, ils peuvent être facilement indexés. De cette façon, la liste peut également être utilisée pour l'implémentation de matrices.
Une autre façon de représenter les matrices est les tableaux implémentés par le module standard
array
- plus contraints par rapport au type stocké, valeur homogène. Les éléments stockent directement la valeur. (La liste stocke les références aux objets de valeur à la place). De cette façon, la mémoire est plus efficace et l'accès à la valeur est plus rapide.Parfois, vous pouvez trouver utile une représentation encore plus restreinte comme
bytearray
.la source
Il existe deux excellentes bibliothèques de graphiques NetworkX et igraph . Vous pouvez trouver les deux codes sources de la bibliothèque sur GitHub. Vous pouvez toujours voir comment les fonctions sont écrites. Mais je préfère NetworkX car il est facile à comprendre.
Voir leurs codes pour savoir comment ils font les fonctions. Vous obtiendrez plusieurs idées et pourrez ensuite choisir comment vous souhaitez créer un graphique en utilisant des structures de données.
la source