Il calcolo del vicino più vicino ripetuto per milioni di punti dati è troppo lento


14

Ho un set di dati in esecuzione in milioni di punti dati in 3D. Per il calcolo che sto facendo, ho bisogno di calcolare il vicino (ricerca intervallo) per ogni punto dati in un raggio, provare ad adattare una funzione, calcolare l'errore per l'adattamento, ripetere questo per il punto dati successivo e così via. Il mio codice funziona correttamente ma richiede molto tempo per essere eseguito, circa 1 secondo per punto dati! Probabilmente è perché per ogni punto, deve cercare nell'intero set di dati. C'è un modo per velocizzare il processo. Ho un'idea che se in qualche modo riesco a stabilire una relazione di adiacenza tra i primi vicini, allora può essere meno lento. Se aiuta, sto cercando di trovare la larghezza ottimale della finestra di Parzen in 3D.

Risposte:


9

Suggerirei di cercare su Google le gerarchie di volumi limitati (in particolare l'albero BSP). Data la tua nuvola di punti, puoi trovare un piano che lo divide in due subcloud uguali. Quindi, quando devi trovare la raccolta di punti che si trovano all'interno di un raggio R di un punto di prova, puoi prima confrontare il tuo punto di prova con quel piano e se la sua altezza sopra è maggiore di R, allora l'intero sottocloud sotto il piano deve essere anche più lontano di R (quindi non è necessario controllare nessuno di questi punti). Puoi applicare questa idea anche in modo ricorsivo, producendo alla fine n complessità di tipo log anziché n-quadrato. (Questo è BSP / partizionamento dello spazio binario,


7

Esistono diverse strutture di dati per l'archiviazione di dati che preservano le informazioni su posizione e prossimità; lì consentendo la determinazione rapida dei vicini più vicini.

In particolare R-alberi (e forme specializzate come R * -trees ) e X-alberi . Molte scelte ottimizzate per usi leggermente diversi.

La scelta di un albero R * anziché di un'ingenua ricerca del vicino più vicino è stata una parte importante del mio ottenere un fattore di 10000 speedup da un particolare codice. (OK, forse qualche centinaio di che è stata la R * -tree, la maggior parte del resto era perché l'ingenuo look-up era stato male codificato in modo che si è rotto la cache. :: :: sigh )

O(NlogN)NO(logN)


5

Questo è molto simile a una delle maggiori sfide nel campo della dinamica molecolare: calcolare tutte le interazioni a coppie tra particelle non legate.

Lì, usiamo elenchi di celle (o elenchi vicini ) per aiutarci a capire cosa c'è nelle vicinanze; per questa applicazione, l'elenco di celle è probabilmente l'algoritmo più semplice da usare:

  • Dividi la scatola in una serie di celle.
  • Per ogni particella, determinare a quale cella deve essere assegnata (O (1) per particella).
  • Quindi, per ogni particella, controlla la cella "propria" più le celle vicine; se uno di questi è occupato, non sono necessarie ulteriori ricerche.
  • Se tutti i vicini più vicini sono vuoti, espandi ai vicini più vicini e così via, fino a quando non viene trovata una particella.

Se il tuo sistema ha una distribuzione più o meno uniforme delle particelle, ciò ridurrà notevolmente il costo dell'algoritmo, in base alla grossolanità della griglia. Tuttavia, è necessaria una regolazione fine: una griglia troppo grossolana e non si risparmia molto tempo; troppo bene e passerai molto tempo a pedalare su celle della griglia vuote!


Dovresti sottolineare che la lunghezza del bordo della cella dovrebbe essere almeno il raggio di ricerca, o se ogni particella ha il suo raggio di ricerca, quindi del raggio massimo.
Pedro

Questo è vero nel caso del MD; qui, non sappiamo cosa sia quel raggio a priori .
aeismail

Uno schema simile è stato utilizzato per molto tempo nelle simulazioni di gravitazione su nuvola di particelle su larga scala. Non so se fa ancora parte dello stato dell'arte.
dmckee --- ex gattino moderatore,

4

Dovresti assolutamente controllare gli alberi e le occhie KD che sono i metodi di scelta per i set di punti (mentre i BSP sono per oggetti generali e le griglie per densità più o meno uniformi). Possono essere molto compatti e veloci, minimizzando le spese generali in memoria e di calcolo e sono semplici da implementare.

Quando i tuoi punti sono distribuiti più o meno uniformemente (anche con aree vuote, ma non devono esserci singolarità di densità o altre alte concentrazioni) controlla gli imballaggi di sfere se vuoi provare una suddivisione spaziale non gerarchica simile a una griglia.


3

Probabilmente dovresti considerare di costruire la triangolazione di Delaunay (bene, il suo analogo 3D). In 2D, questa è una triangolazione speciale dei punti dati che contiene sempre il vicino più vicino. Lo stesso vale per il 3D, ma con il tetraedro.

nlog(n)

Spero che sia d'aiuto!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.