FFT az


14

Varsayalım biz verilir belirgin tamsayılar bir 1 , bir 2 , ... , bir n , öyle ki 0 ≤ a i ≤ k , n bazı sabiti için k > 0 , ve herkes için i .na1,a2,…,an0≤ai≤knk>0i

Tüm olası ikili toplamların sayılarını bulmak istiyoruz . ( i = j'ye izin verilir).Sij=ai+aji=j

Bir algoritma polinom derece ≤ k n oluşturmak ve Fourier dönüşüm yöntemini kullanarak karesini hesaplamak ve ortaya çıkan polinomdaki katsayıları ile güçleri okumaktır. Bu bir O ( n log n ) zaman algoritmasıdır.P(x)=∑j=1nxaj≤knO(nlog⁡n)

İki sorum var:

  • FFT kullanmayan bir algoritması var mı?O(nlog⁡n)

  • Daha iyi algoritmalar biliniyor mu (yani )? (FFT'ye izin verilir).o(nlog⁡n)


FFT'yi kullanmamak neden önemlidir? Sorununuz için zaten iyi bir çözümünüz var gibi görünüyor. FFT kullanmama gereksinimi nereden geliyor? Bana empoze etmek oldukça doğal olmayan bir gereklilik gibi geliyor.
— DW

@DW: Çünkü o zaman sorulacak bir soru olmayacak mı? :-) Ben sadece farklı bir yaklaşım olup olmadığını bilmek merak ediyorum.
— Aryabhata

Tamam anladım! Ben de merak ediyorum itiraf ediyorum. :-) İlginç soru için teşekkür ederim.
— DW

@DW: Rica ederim :-)
— Aryabhata

Yanıtlar:


8

Bu sorunun tamsayı / polinom karelemesine eşdeğer olduğu görülüyor:

1. Polinom çoğalmasının tamsayı çoğalmasına eşdeğer olduğu bilinmektedir .

2. Açıkçası, sorunu zaten polinom / tamsayı karelemesine düşürdünüz; bu nedenle bu problem en fazla kareleme kadar zordur.

Şimdi bu soruna tam sayı karesini azaltacağım:

Bir algoritmanız olduğunu varsayalım:

F(a→)→P2(x),where P(x)=∑ai∈a→xai

Bu algoritma aslında sorunuzda talep ettiğiniz algoritmadır. Bunu yapmak için sihirli algoritması olsaydı Böylece, bir fonksiyon, yapabilir tamsayı kare olacaktır y ( : pOH evet, aşkın mathjax do ):SQUARE(y)y

Algorithm 1 Squaring1.:procedure SQUARE(y):2.:a→←()▹ a→ starts as empty polynomial sequence3.:i←04.:while y≠0 do▹ break y down into a polynomial of base 25.:if y & 1 then▹ if lsb of y is set6.:a→←a→i▹ append i to a→ (appending xi)7.:end if8.:i←i+19.:y←y≫1▹ shift y right by one10.:end while11.:P2(x)←F(a→)▹ obtain the squared polynomial via F(a→)12.:return P2(2)▹ simply sum up the polynomial13.:end procedure

Python ( kod takımı ile test ):

#/cs//q/11418/2755

def F(a):
    n = len(a)
    for i in range(n):
        assert a[i] >= 0

    # (r) => coefficient
    # coefficient \cdot x^{r}
    S = {}
    for ai in a:
        for aj in a:
            r = ai + aj

            if r not in S:
                S[r] = 0

            S[r] += 1

    return list(S.items())

def SQUARE(x):
    x = int(x)

    a = []
    i = 0
    while x != 0:
        if x & 1 == 1:
            a += [i]
        x >>= 1
        i += 1

    print 'a:',a
    P2 = F(a)

    print 'P^2:',P2

    s = 0
    for e,c in P2:
        s += (1 << e)*c
    return s

3. Böylece kare alma en fazla bu problem kadar zordur.

4. Bu nedenle, tamsayı kare alma bu soruna eşdeğerdir. (( 2 , 3 , 1 ) nedeniyle her biri birbirleri kadar serttir )

O(nlog⁡n)O(nlog⁡nlog⁡log⁡n)O(nlog⁡n2O(log∗⁡n))Ω(nlog⁡n)

O(nlog⁡n)

5. Şimdi, probleminiz tam olarak çarpma değil, kareleniyor. Peki kareleme daha kolay mı? Açık bir sorundur (şimdilik hayır) : kareleme, çarpma işleminden daha hızlı bir algoritmaya sahip olduğu bilinmemektedir. Sorununuz için çarpma yönteminden daha iyi bir algoritma bulabiliyorsanız; o zaman bu muhtemelen bir atılım olacaktır.

O(nlog⁡n)O(nlog⁡n)O(nlog⁡n)O(nlog⁡n) ya da en iyi çarpma algoritması sadece bu karmaşıklığa yaklaşır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.