Qual è la più efficiente struttura dei dati del grafico in Python?

voti
63

Ho bisogno di essere in grado di manipolare una grande (10 ^ 7 nodi) grafico in pitone. I dati corrispondenti a ciascun nodo / bordo è minimo, ad esempio, un piccolo numero di stringhe. Qual è il più efficiente, in termini di memoria e la velocità , modo di fare questo?

Un dict di dicts è più flessibile e più semplice da implementare, ma intuitivamente si aspetta una lista di liste per essere più veloce. L'opzione lista richiederebbe anche che io continuo i dati separati dalla struttura, mentre dicts consentirebbero di qualcosa del genere:

graph[I][J][Property]=value

Che cosa suggeriresti?


Sì, avrei dovuto essere un po 'più chiara su ciò che intendo per efficienza. In questo caso particolare voglio dire che in termini di recupero di accesso casuale.

Caricamento dei dati in memoria non è un problema enorme. Questo è fatto una volta per tutte. La parte che richiede tempo sta visitando i nodi in modo da poter estrarre le informazioni e misurare le metriche che mi interessano.

Non avevo pensato di fare ogni nodo di una classe (proprietà sono le stesse per tutti i nodi) ma sembra che sarebbe aggiungere un ulteriore livello di overhead? Speravo che qualcuno avrebbe qualche esperienza diretta con un caso simile che hanno potuto condividere. Dopo tutto, i grafici sono una delle astrazioni più comuni in CS.

È pubblicato 04/08/2008 alle 13:00
fonte dall'utente
In altre lingue...                            


7 risposte

voti
51

Vivamente avvocato si guarda NetworkX . Si tratta di un cavallo di battaglia di battaglia-testato e il primo strumento maggior parte dei tipi di ricerca '' raggiungere per quando hanno bisogno di fare l'analisi dei dati di rete basata. Ho manipolato grafici con 100s di migliaia di bordi senza problemi su un notebook. La sua caratteristica ricco e molto facile da usare. Vi troverete concentrandosi maggiormente sul problema a portata di mano, piuttosto che i dettagli nella implementazione sottostante.

Esempio di Erdős-Rényi generazione grafo casuale e analisi


"""
Create an G{n,m} random graph with n nodes and m edges
and report some properties.

This graph is sometimes called the Erd##[m~Qs-Rényi graph
but is different from G{n,p} or binomial_graph which is also
sometimes called the Erd##[m~Qs-Rényi graph.
"""
__author__ = """Aric Hagberg (hagberg@lanl.gov)"""
__credits__ = """"""
#    Copyright (C) 2004-2006 by 
#    Aric Hagberg 
#    Dan Schult 
#    Pieter Swart 
#    Distributed under the terms of the GNU Lesser General Public License
#    http://www.gnu.org/copyleft/lesser.html

from networkx import *
import sys

n=10 # 10 nodes
m=20 # 20 edges

G=gnm_random_graph(n,m)

# some properties
print "node degree clustering"
for v in nodes(G):
    print v,degree(G,v),clustering(G,v)

# print the adjacency list to terminal 
write_adjlist(G,sys.stdout)

Le visualizzazioni sono anche semplice:

entrare descrizione dell'immagine qui

Più visualizzazione: http://jonschull.blogspot.com/2008/08/graph-visualization.html

Risposto il 26/08/2008 a 18:43
fonte dall'utente

voti
12

Anche se questo problema ora è abbastanza vecchio, penso che valga la pena di citare il mio modulo Python per la manipolazione grafico chiamato grafo-tool . E 'molto efficace, dal momento che le strutture dati e gli algoritmi sono implementati in C ++, con template metaprogrammazione, utilizzando la spinta Graph Library. Quindi le sue prestazioni (sia in utilizzo della memoria e l'esecuzione) è paragonabile ad una libreria puro C ++, e può essere ordini di grandezza rispetto tipico codice pitone, senza sacrificare la facilità d'uso. Io lo uso io stesso costantemente a lavorare con molto grandi grafici.

Risposto il 27/11/2010 a 15:10
fonte dall'utente

voti
6

Come già accennato, NetworkX è molto buona, con un'altra opzione di essere IGRAPH . Entrambi i moduli avranno la maggior parte (se non tutti) gli strumenti di analisi è molto probabile che hanno bisogno, e entrambe le librerie sono abitualmente utilizzati con reti di grandi dimensioni.

Risposto il 27/08/2008 a 11:01
fonte dall'utente

voti
4

Un dizionario può anche contenere in testa, a seconda della effettiva attuazione. Una tabella hash di solito contengono un numero primo di nodi disponibili per cominciare, anche se si potrebbe usare solo un paio di nodi.

A giudicare dal tuo esempio, "Property", sarebbe meglio con un approccio di classe per il livello finale e le proprietà reali? O è i nomi delle proprietà cambiano molto da nodo a nodo?

Direi che cosa significa "efficace" dipende da un sacco di cose, come:

  • la velocità di aggiornamenti (inserimento, aggiornamento, cancellazione)
  • velocità di recupero di accesso casuale
  • velocità di recupero sequenziale
  • memoria utilizzata

Penso che ci si accorge che una struttura di dati che è la volontà veloce generalmente consumano più memoria di uno che è lento. Questo non è sempre il caso, ma le strutture maggior parte dei data sembra seguire questo.

Un dizionario potrebbe essere facile da usare, e vi darà accesso relativamente uniforme veloce, è molto probabile che utilizzare più memoria di quanto, come lei suggerisce, le liste. Le liste, tuttavia, in genere tendono a contenere più overhead quando si inseriscono i dati in esso, a meno che non preallocare nodi X, in cui saranno di nuovo utilizzare più memoria.

Il mio suggerimento, in generale, sarebbe quella di utilizzare solo il metodo che sembra la più naturale per te, e poi fare un "test di stress" del sistema, l'aggiunta di una notevole quantità di dati ad esso e vedere se diventa un problema.

Si potrebbe anche prendere in considerazione l'aggiunta di un livello di astrazione al vostro sistema, in modo che non c'è bisogno di cambiare l'interfaccia di programmazione se in seguito necessità di cambiare la struttura di dati interna.

Risposto il 04/08/2008 a 13:09
fonte dall'utente

voti
3

A quanto mi risulta, l'accesso casuale è in tempo costante sia per i dicts e le liste di Python, la differenza è che si può fare solo l'accesso casuale di indici interi con le liste. Sto assumendo che avete bisogno di ricercare un nodo per la sua etichetta, Così si desidera un dict di dicts.

Tuttavia, sul fronte delle prestazioni, il caricamento in memoria non può essere un problema, ma se si usa troppo vi ritroverete swapping su disco, che ucciderà le prestazioni anche di dicts altamente efficienti di Python. Cercate di mantenere l'utilizzo della memoria verso il basso, per quanto possibile. Inoltre, la RAM è incredibilmente a buon mercato in questo momento; se si fa questo genere di cose un sacco, non c'è alcun motivo per non avere almeno 4 GB.

Se vuoi consigli su come mantenere l'uso della memoria verso il basso, dare qualche informazione in più sul tipo di informazioni che si sta monitorando per ogni nodo.

Risposto il 06/08/2008 a 06:37
fonte dall'utente

voti
2

Fare una struttura di classe a base sarebbe probabilmente hanno più in alto rispetto alla struttura dict-based, dal momento che in classi Python utilizzano effettivamente dicts quando la loro applicazione.

Risposto il 04/08/2008 a 13:41
fonte dall'utente

voti
1

Non c'è dubbio che NetworkX è la migliore struttura di dati fino ad ora per il grafico. Viene fornito con programmi di utilità come Funzioni di supporto, strutture dati e algoritmi, Generatori sequenza casuale, decoratori, Cuthill-Mckee ordinazione, gestori di contesto

NetworkX è grande perché wowrs per grafici, digrammi, e multigrafi. Si può scrivere grafico con molteplici modi: lista di adiacenza, multilinea lista di adiacenza, List Bordo, GEXF, GML. Funziona con Pickle, graphml, JSON, SparseGraph6 etc.

Ha implimentation di diversi algoritmi radimade tra cui: ravvicinamento, bipartito, Barriera, centralità, Cricca, Clustering, Colorare, Componenti, Connettività, Cicli, diretto aciclico Grafici, Distance Measures, insiemi dominante, Euleriano, Isomorfismo, Link Analysis, Collegamento Prediction, Gli , Minimum Spanning Tree, Rich Club, Percorso minimo, Traversal, Albero.

Risposto il 18/01/2016 a 09:08
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more