¿Cómo se puede representar claramente un gráfico en Python ? (¡Comenzando desde cero, es decir, sin bibliotecas!)
¿Qué estructura de datos (por ejemplo, dicts / tuples / dict (tuples)) será rápida pero también eficiente en memoria?
Uno debe poder realizar varias operaciones gráficas en él.
Como se señaló, las diversas representaciones gráficas pueden ayudar. ¿Cómo se implementan en Python?
En cuanto a las bibliotecas, esta pregunta tiene muy buenas respuestas.
python
data-structures
graph
shad0w_wa1k3r
fuente
fuente
dict
de las siguientes opcioneslist
. Básicamente algo como{<parent>: [<child>, ...], ...}
.Respuestas:
Aunque esta es una pregunta algo antigua, pensé en dar una respuesta práctica a cualquiera que se encuentre con esto.
Digamos que obtiene sus datos de entrada para sus conexiones como una lista de tuplas así:
La estructura de datos que he encontrado más útil y eficiente para gráficos en Python es un dictado de conjuntos . Esta será la estructura subyacente de nuestra
Graph
clase. También debe saber si estas conexiones son arcos (dirigidos, se conectan en una dirección) o bordes (no dirigidos, se conectan en ambos sentidos). Lo manejaremos agregando undirected
parámetro alGraph.__init__
método. También agregaremos algunos otros métodos útiles.Lo dejo como un "ejercicio para que el lector" cree un
find_shortest_path
y otros métodos.Sin embargo, veamos esto en acción ...
fuente
heapq
biblioteca para apilar listas de tuplas en lugar de conjuntos. Por ejemplo, el gráfico sería un dictado de montones como:_graph = {'A': heapify([(0.3, 'D'), (0.5, 'B'), (0.75, 'A'), (0.9, 'C')])}
(nota: en realidad no usaríaheapify
así, lea la ayuda de la biblioteca), entonces podría usar lasheapq
funciones para insertar y obtener los bordes ponderados.log
tiempo de acceso. Pero, ¿cómo extender el diccionario que usó para mapear tanto nodeID como weight?NetworkX es una impresionante biblioteca de gráficos de Python. Te será difícil encontrar algo que necesites y que aún no funcione.
Y es de código abierto para que pueda ver cómo implementaron sus algoritmos. También puede agregar algoritmos adicionales.
https://github.com/networkx/networkx/tree/master/networkx/algorithms
fuente
graph.py --> class Graph
. Y todo lo que quiero ver es cómo se usan__iter__
.En primer lugar, la elección de las representaciones clásicas de lista frente a matrices depende del propósito (de qué quiere hacer con la representación). Los problemas y algoritmos conocidos están relacionados con la elección. La elección del tipo de representación abstracta dicta cómo debe implementarse.
En segundo lugar, la cuestión es si los vértices y los bordes deben expresarse solo en términos de existencia o si contienen información adicional.
Desde el punto de vista de los tipos de datos integrados de Python, cualquier valor contenido en otro lugar se expresa como una referencia (oculta) al objeto de destino. Si es una variable (es decir, una referencia con nombre), entonces el nombre y la referencia siempre se almacenan en un diccionario (interno). Si no necesita nombres, entonces la referencia se puede almacenar en su propio contenedor; aquí probablemente la lista de Python siempre se usará para la lista como abstracción.
La lista de Python se implementa como una matriz dinámica de referencias, la tupla de Python se implementa como una matriz estática de referencias con contenido constante (el valor de las referencias no se puede cambiar). Por eso se pueden indexar fácilmente. De esta forma, la lista se puede utilizar también para la implementación de matrices.
Otra forma de representar matrices son las matrices implementadas por el módulo estándar
array
, más restringidas con respecto al tipo almacenado, valor homogéneo. Los elementos almacenan el valor directamente. (En su lugar, la lista almacena las referencias a los objetos de valor). De esta manera, es más eficiente en memoria y también el acceso al valor es más rápido.A veces, puede encontrar una representación útil incluso más restringida como
bytearray
.fuente
Hay dos bibliotecas de gráficos excelentes NetworkX e igraph . Puede encontrar ambos códigos fuente de la biblioteca en GitHub. Siempre puede ver cómo se escriben las funciones. Pero prefiero NetworkX porque es fácil de entender.
Vea sus códigos para saber cómo hacen las funciones. Obtendrá varias ideas y luego podrá elegir cómo desea hacer un gráfico utilizando estructuras de datos.
fuente