Algoritmo


14

Supponiamo di avere numeri interi distinti , in modo tale che per qualche costante e per tutti .na1,a2,,an0aiknk>0i

Siamo interessati a trovare i conteggi di tutte le possibili somme a coppie . ( è consentito).Sij=ai+aji=j

Un algoritmo è costruire il polinomio di grado , e calcolare il suo quadrato usando il metodo di trasformazione di Fourier e leggere i poteri con i loro coefficienti nel polinomio risultante. Questo è un algoritmo .P(x)=j=1nxajknO(nlogn)

Ho due domande:

  • Esiste un algoritmo che non utilizza FFT?O(nlogn)

  • Sono noti algoritmi migliori (ovvero )? (FFT consentita).o(nlogn)


Perché è importante non usare FFT? Sembra che tu abbia già una buona soluzione al tuo problema. Da dove viene il requisito di non usare FFT? Mi sembra un requisito piuttosto non naturale da imporre.
DW

@DW: Perché allora non ci sarà una domanda da porre? :-) Sono solo curioso di sapere se esiste un approccio diverso.
Aryabhata,

Ok capito! Ammetto di essere anche curioso. :-) Grazie per l'interessante domanda.
DW

@DW: Prego :-)
Aryabhata,

Risposte:


8

Sembrerebbe che questo problema sia equivalente alla quadratura intera / polinomiale:

1. È noto che la moltiplicazione polinomiale equivale alla moltiplicazione intera .

2. Ovviamente, hai già ridotto il problema alla quadratura polinomiale / intera; quindi questo problema è tanto difficile quanto la quadratura.

Ora ridurrò la quadratura dei numeri interi a questo problema:

Supponiamo di avere un algoritmo:

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

Questo algoritmo è essenzialmente l'algoritmo richiesto nella domanda. Quindi, se avessi un algoritmo magico in grado di farlo, posso fare una funzione, chequadreràl'intero y (oh sì, adoro 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 ( test con 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. Pertanto, la quadratura è difficile al massimo quanto questo problema.

4. Pertanto, la quadratura dei numeri interi è equivalente a questo problema. (sono entrambi al massimo difficili l'uno dall'altro, a causa di ( 2 , 3 , 1 ))

Ora non è noto se la moltiplicazione intera / polinomiale ammetta limiti migliori di ; infatti i migliori algoritmi di moltiplicazione attualmente utilizzano tutti FFT e hanno runtime come O ( n log n log log n ) ( algoritmo di Schönhage-Strassen ) eO(nlogn)O(nlognloglogn)O(nlogn2O(logn))Ω(nlogn)

O(nlogn)

5. Ora, il tuo problema non è esattamente la moltiplicazione, ma la quadratura. Quindi la quadratura è più facile? Bene, è un problema aperto (no per ora) : la quadratura non è nota per avere un algoritmo più veloce della moltiplicazione. Se riuscissi a trovare un algoritmo migliore per il tuo problema rispetto all'utilizzo della moltiplicazione; allora questo sarebbe probabilmente un passo avanti.

O(nlogn)O(nlogn)O(nlogn)O(nlogn) in entrambi i casi, poiché il miglior algoritmo di moltiplicazione si avvicina solo a quella complessità.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.