Inizializza array in tempo costante ammortizzato - come viene chiamato questo trucco?

13

Esiste questa struttura dati che scambia le prestazioni dell'accesso agli array contro la necessità di iterare su di esso al momento della cancellazione. Mantieni un contatore di generazione con ogni voce e anche un contatore di generazione globale. L'operazione "clear" aumenta il contatore di generazione. Su ogni accesso, si confrontano i contatori di generazione locali rispetto a quelli globali; se differiscono, il valore viene considerato come "pulito".

Questo è arrivato in questa risposta su Stack Overflow di recente, ma non ricordo se questo trucco ha un nome ufficiale. Lo fa?

Un caso d'uso è l'algoritmo di Dijkstra se solo un piccolo sottoinsieme dei nodi deve essere rilassato, e se questo deve essere fatto ripetutamente.

    
posta krlmlr 09.07.2012 - 22:13
fonte

3 risposte

2

L'approccio sopra menzionato richiede che ogni cella sia in grado di contenere un numero abbastanza grande da contenere il numero di volte che la matrice può aver bisogno di essere reinizializzata, che è una penalità sostanziale dello spazio. Se uno slot è in grado di contenere almeno un valore che non sarà mai scritto in modo legittimo, si può evitare di avere qualsiasi altra penalità di spazio (non costante) a spese di aggiungere una penalità di tempo O(Wlg(N)) , dove W è il numero di distinti slot di matrice scritti tra le operazioni di cancellazione e N è la dimensione dell'array. Ad esempio, supponiamo che uno stia memorizzando numeri interi da -2.147.483.647 a 2.147.483.647 (ma mai -2.147.483.648) e uno vuole che gli elementi della matrice vuota vengano letti come zero. Inizia riempiendo l'array con -2,147,483,648 (chiama quel valore B ). Durante la lettura di uno slot di array per l'applicazione, riporta un valore di B come zero. Prima di scrivere lo slot di matrice I , controlla se ha trattenuto B e in tal caso e I è maggiore di uno, memorizza uno zero a slot I/4 dopo aver eseguito un controllo simile per quella posizione (e, se conteneva B , I/16 , ecc.)

Per cancellare la matrice, inizia con I uguale a 0 o 1, a seconda della base dell'array (l'algoritmo come descritto funzionerà per entrambi). Quindi ripetere la seguente procedura: Se l'elemento I è B , incrementa I e, se così facendo restituisce un multiplo di quattro, dividi per quattro (terminare se la divisione produce un valore di 1); se l'articolo I non è B , memorizza B lì e moltiplica I per quattro (se I inizia a zero, moltiplicando per quattro lo lascerà zero, ma poiché l'elemento 0 sarà vuoto, I verrà incrementato).

Si noti che si potrebbe sostituire la costante "quattro" sopra con altri numeri, con valori più grandi che generalmente richiedono meno tagging del lavoro, ma valori più piccoli generalmente richiedono meno spazio di lavoro; poiché gli slot di array che sono taggati devono essere cancellati, un valore di tre o quattro è quasi certamente ottimale; poiché il valore quattro è certamente vicino all'ottimale, è meglio di due o otto, ed è più conveniente di qualsiasi altro numero, sembrerebbe la scelta più ragionevole.

    
risposta data 11.07.2012 - 18:26
fonte
1

Lo chiamerei "reinizializzazione di celle array pigro", ma non sembra avere alcun nome stabilito (vale a dire, il nome è ampiamente utilizzato).

L'algoritmo è intelligente, ma molto specializzato e applicabile in un'area molto ristretta.

    
risposta data 11.07.2012 - 16:43
fonte
1

Credo che sia un caso speciale di memoization , tranne in questo caso, i "memo" implicitamente " età "con ogni incremento del contatore globale. Immagino una sorta di "backward memoization".

    
risposta data 24.07.2012 - 08:06
fonte

Leggi altre domande sui tag