Ważona suma ostatnich N liczb


19

Załóżmy, że otrzymujemy liczby w strumieniu. Po otrzymaniu każdej liczby należy obliczyć ważoną sumę ostatnich liczb, przy czym wagi są zawsze takie same, ale dowolne.N

Jak skutecznie można to zrobić, jeśli pozwolimy zachować strukturę danych, która pomoże w obliczeniach? Czy możemy zrobić coś lepszego niż , tj. Przeliczać sumę za każdym razem, gdy liczba jest odbierana?Θ(N)

Na przykład: Załóżmy, że wagi to . W pewnym momencie mamy listę ostatnich liczb i ważoną sumę .W=⟨w1,w2,w3,w4⟩NL1=⟨a,b,c,d⟩>S1=w1∗a+w2∗b+w3∗c+w4∗d

Po otrzymaniu innej liczby, , aktualizujemy listę, aby uzyskać i musimy obliczyć .eL2=⟨b,c,d,e⟩S2=w1∗b+w2∗c+w3∗d+w4∗e

Rozważanie przy użyciu FFT Szczególny przypadek tego problemu wydaje się być do rozwiązania w wyniku skutecznego zastosowania szybkiej transformacji Fouriera. Tutaj obliczania sumy ważonych wielokrotność . Innymi słowy, otrzymujemy liczb i tylko wtedy możemy obliczyć odpowiednie ważonych sum. Aby to zrobić, potrzebujemy przeszłych liczb (dla których sumy zostały już obliczone) i nowych liczb, łącznie liczb.SNNNN−1N2N−1

Jeśli ten wektor liczb wejściowych i wektor ciężaru określają współczynniki wielomianów i , przy współczynnikach w odwróconym , widzimy, że iloczyn jest a wielomian, którego współczynniki przed do są dokładnie ważonymi sumami, których szukamy. Można je obliczyć za pomocą FFT w czasie , co daje nam średni czas Θ (\ log (N)) na liczbę wejściową.P ( x ) Q ( x ) Q P ( x ) × Q ( x ) x N - 1 x 2 N - 2 Θ ( N ∗ log ( N ) ) Θ ( log ( N ) )WP(x)Q(x)QP(x)×Q(x)xN−1x2N−2Θ(N∗log⁡(N))Θ(log⁡(N))

Nie jest to jednak rozwiązanie problemu, jak stwierdzono, ponieważ wymagane jest, aby suma ważona była obliczana wydajnie za każdym razem, gdy otrzymywana jest nowa liczba - nie możemy opóźniać obliczeń.


Pamiętaj, że możesz używać LaTeX tutaj.
— Raphael

Czy dane wejściowe pochodzą z jakiejś znanej dystrybucji? Czy mają jakieś przydatne właściwości matematyczne? Jeśli nie, to jest mało prawdopodobne, że jest to możliwe (chyba że ktoś jest w stanie znaleźć zgrabną zamkniętą formę, która jest obliczeniem sublinearnym - z pewnością nie mogę jej znaleźć). Czy przybliżenia są w porządku? To może być jeden sposób, jeśli w ogóle ci się przyda.
— RDN

Robią to filtry FIR , więc ich konstrukcja będzie odpowiednia.
— adrianN

@RDN Zadałem to pytanie jako ciekawość, nie mam na myśli praktycznego zastosowania.
— Ambroz Bizjak

Odpowiedzi:


6

Oto opracowanie twojego podejścia. Każdy iteracji używamy algorytm do obliczania FFT wartości zwoju w czasie , przy założeniu, że kolejne wartości zero. Innymi słowy, gdzie są wagami (lub wagi odwrotne), jest sekwencją wprowadzania, jest bieżącym czasem, a dla .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

∑i=0n−1wiat−i+k,0≤k≤m−1,
winaitat′=0t′>t

Dla każdego z poniższych iteracji, że są w stanie wyliczyć wymagane splot w czasie (The tą iterację potrzebuje czasu, ). Tak więc zamortyzowany czas wynosi . Można to zminimalizować, wybierając , co daje zamortyzowany czas działania .O ( m ) i O ( i ) O ( m ) + O ( n log n / m ) m = √mO(m)iO(i)O(m)+O(nlog⁡n/m) O( √m=nlog⁡nO(nlog⁡n)

Możemy to poprawić do najgorszego czasu działania , dzieląc obliczenia na części. Napraw i zdefiniuj Każde zależy tylko od wejść, więc można je obliczyć w czasie . Ponadto, biorąc pod uwagę dla , możemy obliczyć splot w czasie . Dlatego planuje się utrzymanie listy Dla każdego okresumb T , p , o = m - 1 ∑ i = 0 w p m + i a T m - i + o ,O(nlog⁡n)mC T , str

bT,p,o=∑i=0m−1wpm+iaTm−i+o,CT,p=bT,p,0,…,bT,p,m−1.
CT,pO ( m log m ) C ⌊ t / m ⌋ - p , p 0 ≤ p ≤ n / m - 1 O ( n / m + m2mO(mlog⁡m)C⌊t/m⌋−p,p0≤p≤n/m−1C ⌊ t / m ⌋ - p , p ,O(n/m+m)m n / m O ( m log m ) O (
C⌊t/m⌋−p,p,0≤p≤n/m−1.
mdane wejściowe, musimy zaktualizować z nich. Każda aktualizacja zajmuje czas , więc jeśli rozłożymy te aktualizacje równomiernie, każde wejście zajmie pracę . Wraz z obliczeniem samego splotu złożoność czasowa na wejście wynosi . Wybranie jak poprzednio, daje .n/mO(mlog⁡m)O ( ( n / m ) log m + m ) m = √O((n/m2)mlog⁡m)=O((n/m)log⁡m)O((n/m)log⁡m+m) O( √m=nlog⁡nO(nlog⁡n)

Cudowne rozwiązanie, dzięki, nie byłem do końca pewien, czy da się to zrobić.
— Ambroz Bizjak

I to działa! Implementacja C: ideone.com/opuoMj
— Ambroz Bizjak

Meh, brakowało mi tego ostatniego fragmentu kodu, który faktycznie powoduje, że zrywa on obliczenia, naprawione tutaj ideone.com/GRXMAZ .
— Ambroz Bizjak

Na mojej maszynie ten algorytm zaczyna być szybszy niż prosty algorytm o wadze około 17000. W przypadku małej liczby ciężarków jest powolny. Benchmark: ideone.com/b7erxu
— Ambroz Bizjak

Bardzo imponujące, że faktycznie to zaimplementowałeś! Prawdopodobnie chcesz zoptymalizować ponad . Wybór jest jedynie orientacyjnym przewodnikiem i może nie być optymalny. Czy próbowałeś uruchomić algorytm z różnymi wartościami ? m = √m mm=nlog⁡nm
— Yuval Filmus
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.