อัลกอริทึม


14

สมมติว่าเราจะได้รับเลขที่แตกต่างกันเช่นว่าสำหรับบางคงและสำหรับทุกฉันna1,a2,…,an0≤ai≤knk>0i

เรามีความสนใจในการหาข้อหาทุกคู่ที่เป็นไปได้สรุปa_j ( อนุญาตให้ )Sij=ai+aji=j

อัลกอริทึมหนึ่งคือการสร้างพหุนามของระดับและคำนวณสแควร์โดยใช้วิธีการแปลงฟูริเยร์และอ่านพลังกับพวกมัน สัมประสิทธิ์ในพหุนามผลลัพธ์ นี่เป็นอัลกอริทึมเวลาP(x)=∑j=1nxaj≤knO(nlog⁡n)

ฉันมีสองคำถาม:

  • มีอัลกอริทึมซึ่งไม่ได้ใช้ FFT หรือไม่?O(nlog⁡n)

  • รู้จักอัลกอริทึมที่ดีกว่า (เช่น ) หรือไม่ (อนุญาต FFT)o(nlog⁡n)


เหตุใดจึงสำคัญที่จะไม่ใช้ FFT ดูเหมือนคุณจะมีทางออกที่ดีสำหรับปัญหาของคุณแล้ว ข้อกำหนดที่จะไม่ใช้ FFT มาจากที่ใด นั่นฟังดูเป็นเรื่องที่ไม่เป็นธรรมชาติสำหรับฉัน
— DW

@DW: เพราะงั้นก็ไม่มีคำถามที่จะถามเหรอ? :-) ฉันแค่อยากรู้ว่ามีวิธีอื่นไหม
— Aryabhata

ตกลงเข้าใจแล้ว! ฉันก็ยอมรับว่าฉันก็สงสัยเช่นกัน :-) ขอบคุณสำหรับคำถามที่น่าสนใจ
— DW

@DW: ยินดีต้อนรับคุณ :-)
— Aryabhata

คำตอบ:


8

ดูเหมือนว่าปัญหานี้จะเท่ากับจำนวนเต็ม / พหุนามกำลังสอง:

1. เป็นที่รู้จักกันว่าการคูณพหุนามเทียบเท่ากับการคูณจำนวนเต็ม

2.เห็นได้ชัดว่าคุณลดปัญหาดังกล่าวเป็นพหุนาม / จำนวนเต็มกำลังสองแล้ว ดังนั้นปัญหานี้ยากที่สุดเท่าที่จะเป็นกำลังสอง

ตอนนี้ฉันจะลดจำนวนเต็มกำลังสองของปัญหานี้:

สมมติว่าคุณมีอัลกอริทึม:

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

อัลกอริทึมนี้เป็นหลักอัลกอริทึมที่คุณร้องขอในคำถามของคุณ ดังนั้นถ้าฉันมีอัลกอริทึมเวทมนต์ที่สามารถทำสิ่งนี้ได้ฉันสามารถสร้างฟังก์ชันที่จะยกกำลังสองจำนวนเต็มy ( โอ้ใช่ฉันรัก mathjax: P ):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 ( ทดสอบด้วยแผ่นจดบันทึก ):

#/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. ดังนั้นการ squaring นั้นยากที่สุดเท่ากับปัญหานี้

4. ดังนั้นการ squaring จำนวนเต็มจึงเท่ากับปัญหานี้ (พวกเขาแต่ละคนมีความแข็งแกร่งเท่ากันเนื่องจาก ( 2 , 3 , 1 ))

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

O(nlog⁡n)

5.ทีนี้ปัญหาของคุณไม่ใช่การคูณแน่นอนมันกำลังสอง ดังนั้นการ squaring ง่ายขึ้น? มันเป็นปัญหาแบบเปิด (ไม่ใช่ตอนนี้) : การรู้กำลังสองไม่ได้มีอัลกอริธึมเร็วกว่าการคูณ หากคุณสามารถหาอัลกอริทึมที่ดีกว่าสำหรับปัญหาของคุณได้มากกว่าการใช้การคูณ แล้วนี่อาจเป็นความก้าวหน้า

O(nlog⁡n)O(nlog⁡n)O(nlog⁡n)O(nlog⁡n) ในฐานะที่เป็นอัลกอริธึมการคูณที่ดีที่สุดจะเข้าใกล้ความซับซ้อนนั้นเท่านั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.