เราจะสันนิษฐานได้ว่าการดำเนินการขั้นพื้นฐานกับตัวเลขต้องใช้เวลาคงที่


73

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

มีหลักฐานแสดงหรือไม่ว่าการเปรียบเทียบตัวเลขสองตัว (หรือฟังก์ชันทางคณิตศาสตร์แบบดั้งเดิมอื่น ๆ ) สามารถทำได้ใน ? ถ้าไม่ใช่ทำไมเราถึงบอกว่าการเรียงลำดับโดยการเปรียบเทียบนั้นเป็นO ( n log n ) ?O(1)O(nlogn)


ฉันพบปัญหานี้เมื่อฉันตอบคำถามมากและฉันรู้ว่าอัลกอริทึมของฉันไม่ได้เพราะไม่ช้าก็เร็วผมควรจะจัดการกับใหญ่ int ยังมันไม่ได้หลอกพหุนามอัลกอริทึมเวลามันเป็นPO(n)P


3
หากคุณจะนับความซับซ้อนของการเปรียบเทียบตัวเลขคุณควรเขียนขอบเขตความซับซ้อนของคุณในแง่ของขนาดบิตของอินพุต ให้ดังนั้นWหมายเลขบิตขนาดบิตของการเข้าเป็นn = N Wและการเรียงลำดับสามารถทำได้ในO ( N W บันทึกN ) = O ( n log n )เวลา N wn=NwO(NwlogN)=O(nlogn)
Sasho Nikolov

2
โดยทั่วไปจะมี "อาณาจักร" หรือ "ระบอบการปกครอง" ของการศึกษาความซับซ้อนสองแห่ง โดยทั่วไปแล้วการดำเนินงานจะถือว่าเป็นการดำเนินการ "ความกว้างคงที่" ซึ่งเป็นการประมาณที่สมเหตุสมผลสำหรับภาษาคอมพิวเตอร์ส่วนใหญ่ที่มีจำนวนตัวเลขที่มีความกว้างคงที่รวมถึงจุดลอยตัวเช่น 2-4 ไบต์ (ดูมาตรฐาน IEEE เช่น) จากนั้นก็มี "เลขคณิตความแม่นยำตามอำเภอใจ" ซึ่งตัวเลขมีขนาดโดยพลการและมีการศึกษาอย่างรอบคอบ / แม่นยำมากขึ้นเกี่ยวกับความซับซ้อนของการปฏิบัติการ บริบทในอดีตนั้นมีมากขึ้นในการวิเคราะห์เชิงประยุกต์และในบริบทหลังเป็นการวิเคราะห์เชิงทฤษฎี / เชิงนามธรรม O(1)
vzn

คำตอบ:


75

สำหรับคนอย่างผมที่ศึกษาอัลกอริทึมสำหรับการใช้ชีวิตในรูปแบบมาตรฐานในศตวรรษที่ 21 ของการคำนวณเป็นจำนวนเต็มแรม แบบจำลองนี้มีจุดประสงค์เพื่อสะท้อนให้เห็นถึงพฤติกรรมของคอมพิวเตอร์จริงอย่างแม่นยำมากกว่ารุ่นทัวริงของเครื่องจักร คอมพิวเตอร์ในโลกแห่งความเป็นจริงประมวลผลจำนวนเต็มหลายบิตในเวลาคงที่โดยใช้ฮาร์ดแวร์แบบขนาน ไม่ใช่จำนวนเต็มตามอำเภอใจแต่ (เนื่องจากขนาดของคำเติบโตอย่างต่อเนื่องตลอดเวลา) ไม่ใช่จำนวนเต็มขนาดคงที่เช่นกัน

รูปแบบขึ้นอยู่กับพารามิเตอร์เดียวเรียกว่าขนาดคำ อยู่หน่วยความจำแต่ละถือเดียวWจำนวนเต็มบิตหรือคำ ในรูปแบบนี้ขนาดอินพุตnคือจำนวนของคำในการป้อนข้อมูลและเวลาทำงานของอัลกอริทึมคือจำนวนของการดำเนินงานในคำพูด การดำเนินงานมาตรฐานเลขคณิต (บวกลบคูณหารจำนวนเต็มเหลือเปรียบเทียบ) และการดำเนินบูล (บิตและหรือ xor กะหมุน) กับคำพูดต้องO ( 1 )เวลาโดยความหมายwwnO(1)

อย่างเป็นทางการขนาดคำไม่คงที่wสำหรับวัตถุประสงค์ในการวิเคราะห์อัลกอริทึมในรุ่นนี้ เพื่อให้แบบจำลองสอดคล้องกับสัญชาตญาณเราต้องการเนื่องจากไม่เช่นนั้นเราไม่สามารถแม้แต่จะเก็บจำนวนเต็มnในคำเดียว อย่างไรก็ตามสำหรับอัลกอริธึมที่ไม่ใช่ตัวเลขส่วนใหญ่เวลาทำงานนั้นไม่ขึ้นกับwเพราะอัลกอริธึมเหล่านั้นไม่สนใจเกี่ยวกับการแทนค่าไบนารีพื้นฐานของอินพุต การรวมและ heapsort ทั้งสองทำงานในเวลาO ( n log n ) ; ค่ามัธยฐานของ 3-quicksort ทำงานในO ( n 2wlog2nnwO(nlogn)เวลาในกรณีที่เลวร้ายที่สุด หนึ่งที่น่าสังเกตคือการจัดเรียง Radix ไบนารีซึ่งทำงานใน O ( n W )เวลาO(n2)O(nw)

การตั้งค่าทำให้เรามีรูปแบบ RAM แบบลอการิทึมราคาดั้งเดิม แต่อัลกอริธึม RAM จำนวนเต็มบางตัวได้รับการออกแบบมาสำหรับขนาดคำที่ใหญ่กว่าเช่นอัลกอริธึมการเรียงลำดับจำนวนเต็มเชิงเส้นของAndersson และคณะ ซึ่งจะต้องมีW = Ω ( เข้าสู่ระบบ2 + ε n )w=Θ(logn)w=Ω(log2+εn)

สำหรับอัลกอริธึมหลายอย่างที่เกิดขึ้นในทางปฏิบัติคำขนาดนั้นไม่ใช่ปัญหาและเราสามารถ (และทำ) ถอยกลับไปที่รูปแบบ RAM ที่ราคาเท่ากันได้ง่ายกว่า เพียงความยากลำบากอย่างรุนแรงมาจากการคูณซ้อนกันซึ่งสามารถใช้ในการสร้างมากจำนวนเต็มขนาดใหญ่มากได้อย่างรวดเร็ว ถ้าเราสามารถดำเนินการทางคณิตศาสตร์ในพลจำนวนเต็มในเวลาคงที่เราสามารถแก้ปัญหาใด ๆ ใน PSPACE ในเวลาพหุนามw

อัปเดต:ฉันควรพูดถึงว่ามีข้อยกเว้นสำหรับ "โมเดลมาตรฐาน" เช่นอัลกอริธึมการคูณจำนวนเต็มของFürerซึ่งใช้เครื่องมัลติทาสกิ้งของทัวริง (หรือเทียบเท่าที่ "บิตแรม") และอัลกอริธึมเรขาคณิตส่วนใหญ่ สะอาดเงียบสงบ แต่"แรมจริง" รูปแบบ

ใช่นี่เป็นหนอนกระป๋อง


3
ฉันรู้ว่าฉันควรจะลงคะแนน แต่ไม่สามารถหยุดตัวเองจากการพูด: นี่คือคำตอบที่ดีที่สุด เคล็ดลับคือ (1) การดำเนินการทางคณิตศาสตร์เป็นเวลาคงที่ตามคำจำกัดความและไม่เป็นไรเพราะในทางทฤษฎีคุณสามารถเลือกรูปแบบใดก็ได้และ (2) คุณควรมีเหตุผลบางประการในการเลือกแบบจำลองบางแบบและคำตอบนี้จะอธิบายว่ามันคืออะไร
rgrig

nmP

1
wwN0MNlogwM=(NlgM)/(lgw)O(NM)M
JeffE

มีอัลกอริธึมที่วิเคราะห์ในโมเดล Real RAM ที่ไม่ใช่อัลกอริทึม "RAM ประเภทการสั่งซื้อ" หรือไม่? ฉันไม่เคยคิดถึงเรื่องนี้มากนัก แต่ไม่สามารถยกตัวอย่างที่ไม่ใช่ได้อย่างรวดเร็ว
Louis

1
O(n3)O(n4)

24

nO(1)O(n)


จากบทความอ้างอิงของคุณ: "สามารถวัดได้สองวิธี: หนึ่งในแง่ของจำนวนเต็มที่ถูกทดสอบหรือคูณและอีกหนึ่งในแง่ของจำนวนเลขฐานสอง (บิต) ในจำนวนเต็มเหล่านั้น" แต่นี่ไม่เป็นความจริงเรา ควรวัดตามขนาดของอินพุต

1
nθ(n1/2)Pn

โดยวิธีการอัลกอริธึมเทียมแบบพหุนามอาจมีประโยชน์จริง ๆ ถ้าลำดับความสำคัญของพารามิเตอร์ของพวกเขาในกรณีที่เกิดขึ้นจริงนั้นค่อนข้างต่ำ ตัวอย่างที่มีชื่อเสียงที่สุดน่าจะเป็นอัลกอริธึมเทียม - พหุนามเพื่อแก้ปัญหาเครื่องหลัง
Massimo Cafaro

PPO(nlogn)

nO(1)nO(n)=O(2lgn)lgnคือขนาดอินพุตอัลกอริธึมเป็นเลขยกกำลังในขนาดอินพุต! คิดเกี่ยวกับสิ่งนี้. ตอนนี้คุณอาจเข้าใจสิ่งที่ฉันหมายถึงด้วย "มันขึ้นอยู่กับบริบท"
Massimo Cafaro

16

เพื่อตอบคำถามตามที่ระบุไว้: อัลกอริธึมทำได้ง่ายๆโดยใช้แบบจำลองแรม สำหรับการเรียงลำดับในหลายกรณีผู้คนถึงกับวิเคราะห์รูปแบบการเปรียบเทียบที่ง่ายกว่าซึ่งฉันพูดถึงอีกเล็กน้อยในคำตอบที่เชื่อมโยง

เพื่อตอบคำถามโดยปริยายเกี่ยวกับสาเหตุที่พวกเขาทำ: ฉันจะบอกว่าแบบจำลองนี้มีพลังการทำนายที่ดีสำหรับอัลกอริทึม combinatorial บางประเภทซึ่งตัวเลขทั้งหมด "เล็ก" และบนเครื่องจริงพอดีกับการลงทะเบียน

ในการตอบกลับการติดตามโดยนัยเกี่ยวกับอัลกอริธึมเชิงตัวเลข: ไม่รุ่น RAM เก่าธรรมดาไม่ใช่มาตรฐานที่นี่ แม้แต่การกำจัดแบบเกาส์เซียนก็ยังต้องการการดูแลบ้าง โดยทั่วไปสำหรับการคำนวณอันดับ Schwartz Lemma จะป้อน (เช่นหมวด 5 ที่นี่ ) อีกตัวอย่างที่ยอมรับได้คือการวิเคราะห์ Ellipsoid Algorithm ซึ่งต้องการการวิเคราะห์อย่างระมัดระวัง

และในที่สุด: ผู้คนเคยคิดเกี่ยวกับการเรียงลำดับสตริงมาก่อนแม้แต่เมื่อไม่นานมานี้

อัปเดต:ปัญหาของคำถามนี้คือ "เรา" และ "ถือว่า" ไม่ได้ระบุอย่างแม่นยำ ฉันจะบอกว่าคนที่ทำงานในรูปแบบ RAM ไม่ได้ทำอัลกอริธึมเชิงตัวเลขหรือทฤษฎีความซับซ้อน (ซึ่งการพิจารณาความซับซ้อนของการแบ่งเป็นผลลัพธ์ที่โด่งดัง )


อืมดูเหมือนว่ามันเป็นคำตอบที่น่าสนใจ ....

มีเหตุผลหรือไม่ที่ไม่ตอบคำถามทั้งหมด?
Louis

7

O(1)O(1)

python -mtimeit "$a * $b"$a10{1,2,...,66}$b = 2*$a

1050log10(sys.maxint)


O(n)O(nlognlogm)

7

O(1)

O(logM)O(NlogN)O(NlogNlogM)

M


O(logm)O(logn)m

O(logN)

nnnn

คุณพูดถูกฉันตอบถูกแล้ว
Erel Segal-Halevi

4

ฉันจะบอกว่าโดยทั่วไปเราจะถือว่าการดำเนินการทางคณิตศาสตร์ O (1) เพราะเรามักจะทำสิ่งต่าง ๆ ในบริบทของจำนวนเต็ม 32 บิตหรือจำนวนเต็ม 64 บิตหรือเลขทศนิยม IEEE 754 O (1) น่าจะเป็นการประมาณค่าที่ดีสำหรับคณิตศาสตร์ชนิดนั้น

แต่โดยทั่วไปนั่นไม่จริง โดยทั่วไปคุณต้องใช้อัลกอริทึมเพื่อทำการบวกการลบการคูณและการหาร Boolos, Burgess และ Jefferies ' Computability และลอจิกสปริงเป็นสิ่งที่เข้าใจถึงการพิสูจน์หลักฐานในแง่ของระบบที่เป็นทางการสองแบบ, Recursive Function และ Abacus Machines อย่างน้อยในสำเนารุ่นที่ 4 ของฉัน

คุณสามารถดูคำศัพท์แลมบ์ดาแคลคูลัสสำหรับการลบและการหารด้วยตัวเลขโบสถ์สำหรับคำอธิบายที่ง่ายต่อการดูว่าทำไมการดำเนินการทั้งสองนั้นไม่ใช่ O (1) เป็นการยากที่จะเห็นการเพิ่มและการคูณและการยกกำลังสักหน่อย แต่ก็มีหากคุณพิจารณารูปแบบของตัวเลขศาสนจักรด้วยตนเอง

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