Somma ponderata degli ultimi N numeri


19

Supponiamo di ricevere numeri in uno stream. Dopo aver ricevuto ciascun numero, è necessario calcolare una somma ponderata degli ultimi numeri, in cui i pesi sono sempre gli stessi, ma arbitrari.N

Quanto efficacemente può essere fatto se ci è permesso mantenere una struttura di dati per aiutare con il calcolo? Possiamo fare di meglio di , ovvero ricalcolare la somma ogni volta che viene ricevuto un numero?Θ(N)

Ad esempio: supponiamo che i pesi siano . A un certo punto abbiamo l'elenco degli ultimi numeri L_1 = \ langle a, b, c, d \ rangle> e la somma ponderata S_1 = w_1 * a + w_2 * b + w_3 * c + w_4 * d .W=⟨w1,w2,w3,w4⟩NL1=⟨a,b,c,d⟩>S1=w1∗a+w2∗b+w3∗c+w4∗d

Quando viene ricevuto un altro numero, e , aggiorniamo l'elenco per ottenere L2=⟨b,c,d,e⟩ e dobbiamo calcolare S2=w1∗b+w2∗c+w3∗d+w4∗e .

Considerazione sull'uso di FFT Un caso speciale di questo problema sembra essere risolvibile in modo efficiente impiegando la trasformata di Fourier veloce. Qui, calcoliamo le somme pesate S in multipli di N . In altre parole, riceviamo N numeri e solo allora possiamo calcolare le corrispondenti N pesate. Per fare ciò, abbiamo bisogno N−1 numeri passati N-1 (per i quali sono già state calcolate le somme) e N nuovi numeri, in totale numeri 2N−1 .

Se questo vettore di numeri di input e il vettore di peso W definiscono i coefficienti dei polinomi P(x) e Q(x) , con coefficienti in Q invertiti, vediamo che il prodotto P(x)×Q(x) è un polinomio i cui coefficienti davanti a xN−1 fino a x2N−2 sono esattamente le somme ponderate che cerchiamo. Questi possono essere calcolati usando FFT in Θ(N∗log⁡(N)) tempo, che ci dà una media di Θ(log⁡(N)) tempo per numero di input.

Questa non è tuttavia una soluzione al problema come indicato, poiché è necessario che la somma ponderata sia calcolata in modo efficiente ogni volta che viene ricevuto un nuovo numero - non possiamo ritardare il calcolo.


Nota che puoi usare LaTeX qui.
— Raffaello

Gli input provengono da una distribuzione nota? Hanno qualche utile proprietà matematica? In caso contrario, è improbabile che ciò sia possibile (a meno che qualcuno non sia in grado di trovare una forma chiusa ordinata che sia calcolabile in modo sublineare - certamente non riesco a trovarne una). Inoltre, le approssimazioni sono OK? Potrebbe essere una strada da percorrere se ti è utile.
— RDN

I filtri FIR lo fanno, quindi il loro design sarà rilevante.
— adrianN,

@RDN Ho posto questa domanda come una curiosità, non ho in mente un'applicazione pratica.
— Ambroz Bizjak,

Risposte:


6

Ecco un'elaborazione del tuo approccio. Ogni iterazioni, usiamo l'algoritmo FFT per calcolare i valori della convoluzione nel tempo , supponendo che i valori successivi siano zero. In altre parole, stiamo calcolando dove sono i pesi (o i pesi inversi), è la sequenza di input, è l'ora corrente e per .m O ( n log n ) m n - 1 ∑ i = 0 w i a t - i + k ,mmO(nlog⁡n)mw i n a i t a t ′ = 0 t ′ > t

Σio=0n-1wioun't-io+K,0≤K≤m-1,
wionun'iotun't'=0t'>t

Per ciascuna delle seguenti iterazioni, siamo in grado di calcolare la convoluzione richiesto nel tempo (la esima iterazione richiede tempo ). Quindi il tempo ammortizzato è . Questo è ridotto al minimo scegliendo , che fornisce un tempo di esecuzione ammortizzato di .O ( m ) i O ( i ) O ( m ) + O ( n log n / m ) m = √mO(m)ioO(io)O(m)+O(nlog⁡n/m) O( √m=nlog⁡nO(nlog⁡n)

Possiamo migliorare il tempo di esecuzione nel caso peggiore di suddividendo il calcolo in parti. Correggi e definisci Ogni dipende solo da input, quindi può essere calcolato nel tempo . Inoltre, dato per , possiamo calcolare la convoluzione nel tempo . Il piano quindi è di mantenere l'elenco Per ogni periodo dimbO(nlog⁡n)mC T , p 2 m O ( m log m )

bT,p,o=∑i=0m−1wpm+iaTm−i+o,CT,p=bT,p,0,…,bT,p,m−1.
CT,p2mO(mlog⁡m) 0 ≤ p ≤ n / m - 1 O ( n / m + mC⌊t/m⌋−p,p0≤p≤n/m−1C ⌊ t / m ⌋ - p , p ,O(n/m+m)m n / m O ( m log m ) O ( ( n / m 2 ) m log m ) = O ( ( n / m ) log m ) O ( ( n / m ) log m + m ) m = √
C⌊t/m⌋−p,p,0≤p≤n/m−1.
minput, dobbiamo aggiornare di questi. Ogni aggiornamento richiede tempo , quindi se distribuiamo questi aggiornamenti in modo uniforme, ogni input occuperà il lavoro . Insieme al calcolo della convoluzione stessa, la complessità temporale per input è . Scegliendo come prima, questo dà .n/mO(mlog⁡m)O((n/m2)mlog⁡m)=O((n/m)log⁡m)O((n/m)log⁡m+m) O( √m=nlog⁡nO(nlog⁡n)

Soluzione meravigliosa, grazie, non ero davvero sicuro che potesse essere fatto.
— Ambroz Bizjak,

E funziona! Implementazione C: ideone.com/opuoMj
— Ambroz Bizjak

Meh, mi mancava quell'ultimo bit di codice che in realtà lo fa interrompere il calcolo, risolto qui ideone.com/GRXMAZ .
— Ambroz Bizjak,

Sulla mia macchina questo algoritmo inizia ad essere più veloce del semplice algoritmo a circa 17000 pesi. Per piccoli numeri di pesi è lento. Indice di riferimento: ideone.com/b7erxu
— Ambroz Bizjak

Molto impressionante che tu l'abbia effettivamente implementato! Probabilmente vuoi ottimizzare oltre . La scelta è solo una guida approssimativa e potrebbe non essere ottimale. Hai provato a eseguire l'algoritmo con valori diversi di ? mm=nlog⁡nm
— Yuval Filmus,
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.