Hva er den mest effektive diagramdatastruktur i Python?

stemmer
63

I må være i stand til å manipulere et stort (10 ^ 7 noder) graf i python. De data som svarer til hver node / kant er minimal, la oss si, et lite antall strenger. Hva er den mest effektive, i form av minne og hastighet , måte å gjøre dette?

En dict av dicts er mer fleksibel og enklere å implementere, men jeg intuitivt forventer en liste av lister for å bli raskere. Listen alternativet ville også kreve at jeg holder dataene atskilt fra strukturen, mens dicts ville tillate noe slikt:

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

Hva ville du foreslå?


Ja, jeg burde ha vært litt klarere på hva jeg mener med effektivitet. I dette tilfellet mener jeg det i form av random access henting.

Lasting av data inn i minnet er ikke et stort problem. Det er gjort en gang for alle. Den tidkrevende delen besøker nodene slik at jeg kan trekke ut informasjon og måle beregningene jeg er interessert i.

Jeg hadde ikke vurdert å lage hver node en klasse (egenskaper er de samme for alle noder), men det virker som det ville legge et ekstra lag med overhead? Jeg håpet noen ville ha noen direkte erfaring med en lignende sak som de kunne dele. Tross alt, grafer er en av de mest vanlige abstraksjoner i CS.

Publisert på 04/08/2008 klokken 12:00
kilden bruker
På andre språk...                            


7 svar

stemmer
51

Jeg vil sterkt argumentere du ser på NetworkX . Det er en kamp-testet krig hest og det første verktøyet fleste forsknings "typer strekke seg etter når de trenger å gjøre analyse av nettverksbaserte data. Jeg har manipulert grafer med 100s av tusenvis av kantene uten problem på en bærbar PC. Dens funksjon rik og svært enkel å bruke. Du vil finne deg selv å fokusere mer på problemet på hånden i stedet for detaljene i den underliggende implementeringen.

Eksempel på Erdős-Rényi tilfeldig graf generering og analyse


"""
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)

Visualiseringer er også enkel:

skriv bildebeskrivelse her

Mer visualisering: http://jonschull.blogspot.com/2008/08/graph-visualization.html

Svarte 26/08/2008 kl. 17:43
kilden bruker

stemmer
12

Selv om dette spørsmålet er nå ganske gamle, tror jeg det er verdt å nevne min egen python-modul for grafen manipulasjon kalles graf-verktøy . Det er veldig effektivt, siden datastrukturer og algoritmer er implementert i C ++, med mal metaprograming, bruker Boost Graph Library. Derfor ytelsen (både i minnebruk og runtime) kan sammenlignes med en ren C ++ bibliotek, og kan være størrelsesordener bedre enn vanlig python kode, uten å ofre brukervennlighet. Jeg bruker det selv hele tiden for å arbeide med svært store grafer.

Svarte 27/11/2010 kl. 14:10
kilden bruker

stemmer
6

Som allerede nevnt, er NetworkX veldig bra, med et annet alternativ være igraph . Begge modulene vil ha de fleste (om ikke alle) verktøy analyse du sannsynligvis til å trenge, og begge bibliotekene blir rutinemessig brukes med store nettverk.

Svarte 27/08/2008 kl. 10:01
kilden bruker

stemmer
4

En ordbok kan også inneholde overhead, avhengig av den faktiske implementering. En hashtabellen vanligvis inneholder noen prim antall tilgjengelige noder til å begynne med, selv om du kanskje bare bruke et par av noder.

Dømme etter ditt eksempel, "eiendom", du ville være bedre av med en klasse tilnærming for det siste nivået og faste eiendommer? Eller er navnene på de egenskapene skiftende mye fra node til node?

Jeg vil si at det som "effektiv" betyr, avhenger av en rekke ting, som:

  • hastigheten på oppdateringer (sette inn, oppdatere, slette)
  • hastigheten på random access gjenfinning
  • hastigheten på sekvensiell gjenfinning
  • minne som brukes

Jeg tror at du vil finne at en datastruktur som er rask generelt vil forbruke mer minne enn en som er treg. Dette er ikke alltid tilfelle, men de fleste datastrukturer synes å følge dette.

En ordbok kan være lett å bruke, og gir deg relativt jevnt rask tilgang, vil det mest sannsynlig bruke mer minne enn, som du foreslår, lister. Lister, men generelt har en tendens til å inneholde mer overhead når du sette inn data i det, med mindre de preallocate X noder, der de igjen vil bruke mer minne.

Mitt forslag, generelt, ville være å bare bruke den metoden som virker mest naturlig for deg, og deretter gjøre en "stresstest" av systemet, og legger en betydelig mengde data til den og se om det blir et problem.

Du kan også vurdere å legge et lag av abstraksjon til systemet ditt, slik at du ikke trenger å endre programmeringsgrensesnittet hvis du senere behov for å endre den interne datastruktur.

Svarte 04/08/2008 kl. 12:09
kilden bruker

stemmer
3

Som jeg forstår det, er random access i konstant tid for begge Pythons dicts og lister, er forskjellen at du bare kan gjøre random access heltallsargumenter indekser med lister. Jeg antar at du trenger å finne en node av etiketten, slik at du vil ha en dict av dicts.

Men på ytelsen fronten, legger det inn i minnet kan ikke være et problem, men hvis du bruker for mye du vil ende opp med å bytte til disk, noe som vil drepe ytelsen til selv Pythons høyeffektive dicts. Prøv å holde minnebruken ned så mye som mulig. Dessuten er RAM utrolig billig akkurat nå; hvis du gjør denne typen ting mye, er det ingen grunn til ikke å ha minst 4GB.

Hvis du ønsker råd om å holde minnebruk ned, gi litt mer informasjon om hva slags informasjon du sporer for hver node.

Svarte 06/08/2008 kl. 05:37
kilden bruker

stemmer
2

Å gjøre en klassebasert struktur ville sannsynligvis ha mer overhead enn dict basert struktur, da det i python klasser faktisk bruke dicts når de iverksettes.

Svarte 04/08/2008 kl. 12:41
kilden bruker

stemmer
1

Ingen tvil NetworkX er den beste datastrukturen til nå for grafen. Den leveres med verktøy som Helper funksjoner, datastrukturer og algoritmer, tilfeldig sekvens generatorer, dekoratører, Cuthill-Mckee bestilling, kontekst Managers

NetworkX er stor fordi det wowrs for grafer, digraphs og multigraphs. Den kan skrive graf med flere måter: tilstøter List, Multi tilstøter List, Edge List, GEXF, GML. Det fungerer med Pickle, GraphML, JSON, SparseGraph6 etc.

Den har implimentation av ulike radimade algoritmer inkludert: Tilnærming, todelt, Boundary, sentralitet, Clique, Clustering, Maling, komponenter, Tilkobling, Cycles, Directed asykliske grafer, Avstand tiltak, Dominerende Stiller, Eulersk, isomorphism, Link Analysis, Link Prediction, Matching , Minimum Spanning Tree, Rich Club, korteste vei, overgang, treet.

Svarte 18/01/2016 kl. 09:08
kilden bruker

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