2011-02-09 26 views
5

Sto scrivendo un programma per una simulazione numerica in C. Parte della simulazione sono nodi fissi nello spazio che hanno un valore float l'uno rispetto all'altro. È come un grafico diretto. Tuttavia, se due nodi sono troppo lontani, (più lontano di una lunghezza di taglio a) questo valore è 0.Come implementare una matrice enorme in C

Per rappresentare tutte queste "correlazioni" o valori float, ho provato a utilizzare un array 2D, ma dal Ho 100.000 e più nodi, che corrispondono a una memoria da 40 GB o giù di lì.

Ora, sto cercando di pensare a diverse soluzioni per quel problema. Non voglio salvare tutti questi valori sul disco fisso. Inoltre, non voglio calcolarli al volo. Un'idea era una sorta di matrice sparsa, come quella che si può usare in Matlab.

Avete altre idee, come conservare questi valori?

Sono nuovo di C, quindi per favore non aspettatevi troppa esperienza.

Grazie e cordiali saluti, Jan Oliver

+2

Che dire di una specie di hash/mappa in cui la chiave è (riga x colonna)? Avrebbe solo tanti elementi quante sono le voci nella matrice con un valore diverso da zero. –

+0

Non è una domanda specifica ... Sì, matrici sparse. Vai a cercare alcuni algoritmi ... Forse con alcuni dettagli sulla percentuale di nodi nulll nella matrice, o più informazioni sulla simulazione, forse qualcuno potrebbe suggerire altre soluzioni oltre una rappresentazione grah. – pascal

+0

... per esempio, cosa vuoi fare con questa matrice? – pascal

risposta

4

Quanti nodi, in media, si trovano all'interno della distanza di cutoff per un determinato nodo determinano i requisiti di memoria e indicano se è necessario eseguire una pagina su disco. La soluzione che occupa meno memoria è probabilmente una tabella hash che mappa una coppia di nodi a una distanza. Poiché la distanza è uguale in ogni modo, è sufficiente inserirlo nella tabella hash una volta sola per la coppia: inserire i due numeri di nodo in ordine numerico e combinarli per formare una chiave hash. È possibile utilizzare le funzioni Posix hsearch/hcreate/hdestroy per la tabella hash, sebbene non siano l'ideale.

+0

è una buona idea. Un nodo è in media collegato allo 0,2% degli altri nodi. Questo dipende dai parametri. – janoliver

+0

Sono un po 'preoccupato per le prestazioni del processo di ricerca, però. Questo è in realtà molto più importante della creazione della matrice/hashmap, poiché quest'ultima viene eseguita solo una volta ... – janoliver

+0

@janoliver Quindi questo è 200 dei 100.000 nodi? Velocità: la ricerca hash è O (1) ma il tempo costante può essere grande, specialmente quando si ha poca memoria. (Quanto hai?) Forse sarebbe meglio una serie di nodi con ogni nodo contenente un elenco di nodi vicini ordinati per numero di nodo; la ricerca binaria richiederebbe circa 9 confronti per 200 nodi. È facile da implementare e potresti voler iniziare con esso e considerare solo qualcos'altro se necessario. –

0

Se possibile, utilizzare matrici sparse. In Scipy, abbiamo il supporto per le matrici sparse, in modo da poter giocare in Python, anche se per essere sincero il supporto sparse ha ancora i bordi grezzi.

Se si ha accesso a MATLAB, sarà sicuramente ATM migliore.

Senza utilizzare la matrice sparsa, si potrebbe pensare di utilizzare matrici basate su memap in modo da non aver bisogno di 40 Gb di RAM, ma sarà comunque lento, e ha senso solo se si ha un basso grado di scarsità (diciamo che se il 10-20% della matrice 100000x100000 contiene elementi, allora gli array completi saranno effettivamente più veloci e forse occuperanno meno spazio rispetto alle matrici sparse).

2

Una matrice di adiacenza sparsa è un'idea, oppure è possibile utilizzare un elenco di adiacenza che consente di archiviare solo i bordi più vicini del valore limite.

+0

Ciao Jim, grazie per l'idea. Dopo un rapido sguardo su questi elenchi, sembra che un semplice valore float a cui fanno riferimento due indici richieda meno memoria di uno di questi elementi dell'elenco .. – janoliver

1

Si potrebbe anche tenere un elenco per ogni nodo, che contiene gli altri nodi a cui questo nodo è correlato. Avresti quindi un numero complessivo di voci di elenco di 2 * k, dove k è il numero di valori diversi da zero nella matrice virtuale.

L'implementazione dell'intero sistema come combinazione di hash/set/mappe è ancora accettabile per quanto riguarda velocità/prestazioni rispetto a una matrice "reale" che consente l'accesso casuale.

modifica: questa soluzione è una possibile forma di implementazione di una matrice sparsa. (Vedi anche la nota di Jim Balter qui sotto. Grazie, Jim.)

+0

Sicuramente 2 (k-1) perché un nodo non si collegherà a se stesso? Vedi il mio commento sulla domanda principale, sono d'accordo che questo è il modo per risolverlo. – SlappyTheFish

+0

Si noti che un elenco in ciascun nodo in cui ogni voce dell'elenco contiene un numero di nodo e una distanza diversa da zero è una matrice di matrice sparsa, in cui ogni elenco di nodi è una riga (o colonna). –

+0

@SlappyTheFish Flinsch ha scritto "k è il numero di valori diversi da zero nella matrice virtuale" - la diagonale è tutti zero nella matrice virtuale, quindi k esclude già tali voci. L'elenco include effettivamente k voci, in cui ogni voce ha due valori, un numero di nodo e una distanza. –