FFT az


14

Varsayalım biz verilir belirgin tamsayılar bir 1 , bir 2 , ... , bir n , öyle ki 0 a ik , n bazı sabiti için k > 0 , ve herkes için i .na1,a2,,an0aiknk>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=1nxajknO(nlogn)

İki sorum var:

  • FFT kullanmayan bir algoritması var mı?O(nlogn)

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


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)=aiaxai

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.:i04.:while y0 do break y down into a polynomial of base 25.:if y & 1 then if lsb of y is set6.:aai append i to a (appending xi)7.:end if8.:ii+19.:yy1 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(nlogn)O(nlognloglogn)O(nlogn2O(logn))Ω(nlogn)

O(nlogn)

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(nlogn)O(nlogn)O(nlogn)O(nlogn) 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.