Thuật toán FFT-


14

Giả sử chúng ta được cung cấp số nguyên khác nhau , sao cho cho một số hằng số và cho tất cả i .một 1 , một 2 , ... , một n 0 một ik n k > 0na1,a2,,an0aiknk>0i

Chúng tôi đang quan tâm đến việc tìm kiếm các tội danh tất cả các khoản tiền cặp có thể Sij=ai+aj . ( i=j được cho phép).

Một thuật toán là xây dựng các đa thức sỹ , và tính toán vuông của nó bằng cách sử dụng phương pháp biến đổi Fourier và đọc ra khỏi quyền hạn với hệ số của họ trong các kết quả đa thức. Đây là thuật toán thời gian .P(x)=j=1nxajO ( n log n )knO(nlogn)

Tôi có hai câu hỏi:

  • Có thuật toán không sử dụng FFT không?O(nlogn)

  • Các thuật toán tốt hơn được biết đến (tức là )? (Cho phép FFT).o(nlogn)


Tại sao điều quan trọng là không sử dụng FFT? Có vẻ như bạn đã có một giải pháp tốt cho vấn đề của bạn. Trường hợp yêu cầu không sử dụng FFT đến từ đâu? Điều đó đối với tôi như một yêu cầu khá tự nhiên để áp đặt.
DW

@DW: Bởi vì sau đó sẽ không có câu hỏi nào? :-) Tôi chỉ tò mò muốn biết liệu có một cách tiếp cận khác.
Aryabhata

OK đã nhận nó! Tôi thừa nhận tôi cũng tò mò. :-) Cảm ơn bạn cho câu hỏi thú vị.
DW

@DW: Bạn được chào đón :-)
Aryabhata

Câu trả lời:


8

Có vẻ như vấn đề này tương đương với bình phương số nguyên / đa thức:

1. Người ta biết rằng phép nhân đa thức tương đương với phép nhân số nguyên .

2. Rõ ràng, bạn đã giảm vấn đề thành bình phương đa thức / số nguyên; do đó, vấn đề này khó nhất là bình phương.

Bây giờ tôi sẽ giảm bình phương số nguyên cho vấn đề này:

Giả sử bạn đã có một thuật toán:

F(a)P2(x),where P(x)=aiaxai

Thuật toán này thực chất là thuật toán bạn yêu cầu trong câu hỏi của bạn. Vì vậy, nếu tôi có một thuật toán ma thuật có thể làm điều này, tôi có thể tạo một hàm, sẽ bình phương số nguyên y ( oh vâng, tôi rất thích mathjax: P ):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 ( kiểm tra với codepad ):

#/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. Như vậy, bình phương khó nhất là vấn đề này.

4. Therefore, integer squaring is equivalent to this problem. (they are each at most as hard as each-other, due to (2,3,1))

Now it is unknown if integer/polynomial multiplication admits bounds better than O(nlogn); in fact the best multiplication algorithms currently all use FFT and have run-times like O(nlognloglogn) (Schönhage-Strassen algorithm) and O(nlogn2O(logn)) (Fürer's algorithm). Arnold Schönhage and Volker Strassen conjectured a lower bound of Ω(nlogn), and so far this seems to be holding.

This doesn't mean your use of FFT is quicker; O(nlogn) for FFT is the number of operations (I think), not the bit complexity; hence it ignores some factors of smaller multiplications; when used recursively, it would become closer to the FFT multiplication algorithms listed above (see Where is the mistake in this apparently-O(n lg n) multiplication algorithm?).

5. Now, your problem is not exactly multiplication, it is squaring. So is squaring easier? Well, it is an open problem (no for now): squaring is not known to have a faster algorithm than multiplication. If you could find a better algorithm for your problem than using multiplication; then this would likely be a breakthrough.

So as of now, the answer to both your questions is: no, as of now, all the ~O(nlogn) multiplication algorithms use FFT; and as of now squaring is as hard as multiplication. And no, unless a faster algorithm for squaring is found, or multiplication breaks the O(nlogn) barrier, your problem cannot be solved faster than O(nlogn); in fact, it cannot currently be solved in O(nlogn) either, as the best multiplication algorithm only approaches that complexity.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.