การคูณใน


10

ฉันกำลังดูที่นี่และฉันสังเกตเห็นว่า runtime ที่ดีที่สุดสำหรับการคูณจำนวนสองบิตคือO ( n log n 2 O ( log n )แต่ฉันสามารถสังเกตเห็นอัลกอริธึมที่ทำงานในO ( n )ได้อย่างง่ายดายเข้าสู่ระบบn )nO(nlogn2O(logn)O(nlogn)

ท้ายที่สุดเรารู้วิธีคูณสองชื่อพหุนามจากดีกรีในรันไทม์O ( n log n ) แต่พหุนามการคูณจะเหมือนกับการคูณสองจำนวนn-บิต ดังนั้นเราจึงมีขั้นตอนวิธีการที่จะคูณสองn -bits ตัวเลขในO ( n log n ) ตอนนี้ปัญหาเดียวที่อาจเกิดขึ้นได้คือการบรรทุก แต่ในแต่ละขั้นตอนเราสามารถแก้ไขได้ในเวลาO ( n )เพียงแค่เคลื่อนที่ไปทางขวาสุดและเพื่อนบ้านซ้ายจนกระทั่งจบ นั่นคือรันไทม์ของเราจะยังคงอยู่O ( n log nnO(nlogn)nnO(nlogn)O(n) .O(nlogn)

ดังนั้นฉันจึงทำการค้นพบใหม่ (และชัดเจน) หรือหน้าวิกิพีเดียล้าสมัย? หรือบางทีฉันมีข้อผิดพลาดบางอย่าง?


อะไรคือวิธีที่ "เรารู้" "เพื่อคูณสองชื่อพหุนามจากดีกรีในรันไทม์O ( n log n ) "?nO(nlogn)

คำตอบ:


8

@DavidRicherby ชี้ให้เห็นแล้วความสับสนเกิดขึ้นเนื่องจากการวัดความซับซ้อนที่แตกต่างกันเริ่มสับสน แต่ขอผมอธิบายหน่อย

โดยปกติเมื่อศึกษาอัลกอริธึมสำหรับการคูณพหุนามมากกว่าแหวนโดยพลการหนึ่งจะสนใจจำนวนการดำเนินการทางคณิตศาสตร์ในวงแหวนที่อัลกอริทึมใช้ โดยเฉพาะอย่างยิ่งเมื่อได้รับ (commutative, unitary) ring และ polynomials f , g R [ X ]ระดับน้อยกว่าn , Schönhage-Strassen algorithm ต้องการO ( n log n log log n )และการเพิ่มเติมในRเพื่อคำนวณf g R [ X ]Rf,gR[X]nO(nlognloglogn)RfgR[X]โดยประมาณติดรากดั้งเดิม -th ของความสามัคคีในการวิจัยจะได้รับบางแหวนขนาดใหญ่D Rแล้วโดยใช้จานแปลงฟูเรียกว่าDคำนวณผลิตภัณฑ์ในDnRDRDD

ถ้าแหวนของคุณมีราก -th ของความสามัคคีแล้วนี้สามารถเร่งความเร็วได้ถึงO ( n log n )การดำเนินงานในการวิจัยโดยใช้จานฟูริเยร์แปลงโดยตรงผ่านR โดยเฉพาะอย่างยิ่งในZCคุณสามารถทำได้โดยใช้การดำเนินงานเสียงเรียกเข้าO ( n log n ) (โดยไม่สนใจข้อเท็จจริงที่ว่านี่จะต้องใช้เลขคณิตที่แน่นอนมากกว่าจำนวนเชิงซ้อน)nO(nlogn)RRZCO(nlogn)

มาตรการอื่นที่สามารถนำมาพิจารณาได้ก็คือความซับซ้อนของการดำเนินการ และนี่คือสิ่งที่เรากำลังสนใจในเมื่อคูณจำนวนเต็มสองจำนวนของความยาวบิตnที่นี่การดำเนินงานดั้งเดิมจะคูณและเพิ่มสองหลัก (พร้อมส่ง) ดังนั้นเมื่อคูณสองชื่อพหุนามมากกว่าZคุณต้องคำนึงถึงความจริงที่ว่าตัวเลขที่เกิดขึ้นระหว่างการคำนวณไม่สามารถคูณด้วยการดำเนินการดั้งเดิม นี่และความจริงที่ว่าZไม่มีรูตดั้งเดิมของความสามัคคีn -th สำหรับn > 2ทำให้คุณไม่สามารถใช้O ( n log n ) ได้nZZnn>2O(nlogn)ขั้นตอนวิธี คุณเอาชนะสิ่งนี้ได้โดยพิจารณาด้วยค่าสัมประสิทธิ์จากวงแหวนZ /2 n + 1 เนื่องจากค่าสัมประสิทธิ์ของพหุนามผลิตภัณฑ์จะไม่เกินขอบเขตนี้ มี (เมื่อnคุณมี (ชั้นความสอดคล้องกันของ) อำนาจของทั้งสองเป็น) 2เป็นnราก -th ของความสามัคคีและด้วยซ้ำเรียกอัลกอริทึมสำหรับการคูณค่าสัมประสิทธิ์คุณสามารถบรรลุรวมO ( n log n บันทึกบันทึกn )ดั้งเดิมเช่นบิต) การดำเนินงาน ( จากนั้นจะนำไปสู่การคูณจำนวนเต็มf,gZ/2n+1n2nO(nlognloglogn)

f=i=0nfiXixZ

f(x)=((fnx+fn1)x++)+f0
f
H=i=1n/2fn/2+iXi
L=i=0n/2fiXi
H>n/2Ln/2n เป็นพลังของสองเพื่อความง่าย)

f(x)

f(x)=H(x)xn/2+L(x)

nn+logn

n/2n/2Ω(n2)nO(n)O(nlogcn)=O~(n)c>0


9

nO(nlogn)nO(2lognnlogn)nO(nlogn)


5
ฉันไม่คิดว่านี่เป็นปัญหา ถ้าเราคิดว่าตัวเลขเป็นพหุนามซึ่งมี "x" เป็นฐานเช่น 2 โดยทั่วไปเราสามารถคูณจำนวนพหุนามศูนย์องศา (ตัวเลขที่เล็กกว่าฐาน) ในเวลาคงที่ ฉันเดาว่าปัญหาคืออัลกอริทึม O (n * log n) ใช้ FFT และตัวเลขที่มีขนาดใหญ่กว่านั้นอาจปรากฏในอัลกอริทึม FFT
jkff
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.