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,w4NL1=a,b,c,d>S1=w1a+w2b+w3c+w4d

Po otrzymaniu innej liczby, , aktualizujemy listę, aby uzyskać i musimy obliczyć .eL2=b,c,d,eS2=w1b+w2c+w3d+w4e

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.SNNNN1N2N1

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)xN1x2N2Θ(Nlog(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ń.

Ambroz Bizjak
źródło
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(nlogn)mw i n a i t a t = 0 t > t

i=0n1wiati+k,0km1,
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(nlogn/m) O(m=nlognO(nlogn)

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(nlogn)mC T , str

bT,p,o=i=0m1wpm+iaTmi+o,CT,p=bT,p,0,,bT,p,m1.
CT,pO ( m log m ) C t / m - p , p 0 p n / m - 1 O ( n / m + m2mO(mlogm)Ct/mp,p0pn/m1C t / m - p , p ,O(n/m+m)m n / m O ( m log m ) O (
Ct/mp,p,0pn/m1.
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(mlogm)O ( ( n / m ) log m + m ) m = O((n/m2)mlogm)=O((n/m)logm)O((n/m)logm+m) O(m=nlognO(nlogn)
Yuval Filmus
źródło
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=nlognm
Yuval Filmus