“ สำหรับค่าเล็ก ๆ ของ n, O (n) สามารถถือว่าเหมือนกับ O (1)”


26

ฉันเคยได้ยินมาหลายครั้งแล้วว่าสำหรับค่าที่น้อยมากของ n, O (n) สามารถคิดเกี่ยวกับ / ถือว่าราวกับว่ามันเป็น O (1)

ตัวอย่าง :

แรงจูงใจในการทำเช่นนั้นขึ้นอยู่กับความคิดที่ไม่ถูกต้องที่ O (1) ดีกว่า O (lg n) เสมอดีกว่า O (n) ลำดับของการดำเนินการแบบซีมโทติคนั้นเกี่ยวข้องเฉพาะในกรณีที่ขนาดจริงของปัญหาใหญ่มาก ถ้า n ยังเล็กอยู่ทุกปัญหาคือ O (1)!

มีขนาดเล็กพอเพียงคืออะไร 10? 100? 1,000? คุณพูดว่า "เราไม่สามารถปฏิบัติเช่นนี้กับการดำเนินการฟรีอีกต่อไป" มีกฎง่ายๆไหม?

ดูเหมือนว่าจะเป็นโดเมนหรือกรณีเฉพาะ แต่มีกฎทั่วไปเกี่ยวกับวิธีคิดเกี่ยวกับเรื่องนี้หรือไม่?


4
กฎของหัวแม่มือขึ้นอยู่กับปัญหาที่คุณต้องการแก้ไข รวดเร็วในระบบฝังตัวด้วยหรือไม่ เผยแพร่ในทฤษฎีความซับซ้อน? n100
Raphael

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

12
@rianjs ดูเหมือนว่าคุณจะเข้าใจผิดO(1)สำหรับฟรี เหตุผลเบื้องหลังประโยคสองสามข้อแรกคือนั่นO(1)คือค่าคงที่ซึ่งบางครั้งอาจช้าอย่างบ้าคลั่ง การคำนวณที่ใช้เวลานับพันล้านปีโดยไม่คำนึงถึงอินพุตเป็นการO(1)คำนวณ
Mooing Duck

1
คำถามที่เกี่ยวข้องกับสาเหตุที่เราใช้ asymptotics ตั้งแต่แรก
ราฟาเอล

3
@rianjs: ระวังเรื่องตลกตามแนวของ "เพนตากอนจะมีค่าประมาณวงกลมสำหรับค่าที่มีขนาดใหญ่พอ 5" ประโยคที่คุณถามจะทำให้เป็นประเด็น แต่เนื่องจากมันทำให้คุณสับสนบางอย่างมันอาจจะคุ้มค่าที่คุณจะถาม Eric Lippert ว่าการเลือกใช้ถ้อยคำที่ถูกต้องนี้มีผลต่ออารมณ์ขันอย่างไร เขาสามารถพูดได้ว่า "ถ้ามีขอบเขตบนแล้วทุกปัญหาคือO ( 1 ) " และยังคงถูกต้องทางคณิตศาสตร์ "เล็ก" ไม่ใช่ส่วนหนึ่งของคณิตศาสตร์ nO(1)
Steve Jessop

คำตอบ:


21

ออร์เดอร์ทั้งหมดของขนาดเกี่ยวข้องกับค่าคงที่ซึ่งจริง ๆ แล้วหลายคำสั่ง เมื่อจำนวนรายการมีขนาดใหญ่พอที่คงที่ไม่เกี่ยวข้อง คำถามคือจำนวนรายการมีขนาดเล็กเพียงพอสำหรับค่าคงที่ที่จะครองหรือไม่C

นี่เป็นวิธีที่มองเห็นได้

ป้อนคำอธิบายรูปภาพที่นี่

ทั้งหมดมีค่าคงที่เริ่มต้นซึ่งกำหนดจุดเริ่มต้นของพวกเขาบนแกน Y แต่ละคนยังมีความสำคัญอย่างต่อเนื่องครอบครองวิธีการที่รวดเร็วพวกเขาจะเพิ่มขึ้นC

  • สำหรับ , CกำหนดเวลาO(1)C
  • คือ C × nจริงๆโดยที่ CกำหนดมุมO(n)C×nC
  • คือจริง ๆ ( C × n ) 2โดยที่ Cกำหนดความคมชัดของเส้นโค้งO(n2)(C×n)2C

ในการกำหนดอัลกอริทึมที่คุณควรใช้คุณต้องประเมินจุดที่รันไทม์ตัดกัน ตัวอย่างเช่นโซลูชันที่มีเวลาเริ่มต้นสูงหรือCสูงจะสูญเสียไปยังโซลูชันO ( n )ด้วยเวลาเริ่มต้นที่ต่ำและCต่ำที่จำนวนรายการค่อนข้างมากO(1)CO(n)C

นี่คือตัวอย่างโลกแห่งความจริง คุณต้องย้ายก้อนอิฐไปตามลาน คุณสามารถเคลื่อนย้ายพวกมันทีละครั้งด้วยมือของคุณหรือไปรับแบ็คโฮขนาดใหญ่ที่ช้าเพื่อยกและขับเคลื่อนพวกมันในการเดินทางครั้งเดียว คุณมีคำตอบอะไรถ้ามีอิฐสามก้อน คุณมีคำตอบอย่างไรถ้ามีสามพัน

นี่คือตัวอย่าง CS สมมติว่าคุณต้องการรายการที่เรียงลำดับอยู่เสมอ คุณสามารถใช้ต้นไม้ที่จะให้ตัวเองในการสั่งซื้อสำหรับ ) หรือคุณอาจจะใช้รายการที่ไม่ได้เรียงลำดับและการจัดเรียงใหม่ทุกครั้งหลังการแทรกหรือลบที่O ( n log n ) เนื่องจากการดำเนินการต้นไม้มีความซับซ้อน (มีค่าคงที่สูง) และการเรียงลำดับนั้นง่ายมาก (ค่าคงที่ต่ำ) รายการมีแนวโน้มที่จะชนะได้หลายร้อยหรือหลายพันรายการO(เข้าสู่ระบบn)O(nเข้าสู่ระบบn)

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

เนื่องจากข้อกำหนดเหล่านี้อาจมีการเปลี่ยนแปลงจึงเป็นสิ่งสำคัญที่จะต้องตัดสินใจเรื่องเหล่านี้หลังอินเทอร์เฟซ ในตัวอย่างต้นไม้ / รายการด้านบนอย่าเปิดเผยต้นไม้หรือรายการ ด้วยวิธีนี้หากสมมติฐานของคุณผิดหรือคุณพบอัลกอริทึมที่ดีกว่าคุณสามารถเปลี่ยนใจได้ คุณสามารถทำไฮบริดและสลับอัลกอริธึมแบบไดนามิกเมื่อจำนวนรายการเพิ่มขึ้น


มันเป็นความหมายที่จะบอกว่า ) สิ่งที่คุณหมายจริงๆคือว่าถ้าเวลาทำงานคือT = O ( 1 )แล้ว (ในหลายกรณี) T C ถ้าT = OO(1)=O(C)T=O(1)TCแล้วในหลายกรณี T C nหรืออีกอย่างเป็นทางการ T = C n + o ( n ) และอื่น ๆ อย่างไรก็ตามโปรดทราบว่าในกรณีอื่นค่าคงที่ CจะแปรตามT=O(n)TCnT=Cn+โอ(n)Cภายในขอบเขตที่แน่นอน n
Yuval Filmus

@YuvalFilmus นี่คือเหตุผลที่ฉันชอบกราฟ
Schwern

นี่คือคำตอบที่ดีที่สุดเท่าที่ผ่านมาประเด็นก็คือการเติบโตอย่างรวดเร็วของฟังก์ชัน
Ricardo

1
กราฟที่ดี แต่แกนควรมีป้ายกำกับว่า "เวลา" ไม่ใช่ "ความเร็ว" Y
Ilmari Karonen

1
คือเส้นโค้งจริงๆมี? มันมีลักษณะแบนราบมากสำหรับธุรกิจขนาดเล็ก nและสูงชันมากสำหรับขนาดใหญ่n O(n2)nn
David Richerby

44

นี่คือการสนับสนุนลูกหมูกับคำตอบที่โพสต์ไปแล้ว แต่อาจเสนอมุมมองที่แตกต่างออกไป

มันแสดงให้เห็นว่าคำถามพูดถึง "ค่าพอเพียงของn " จุดทั้งหมดของ Big-O คือการอธิบายวิธีการประมวลผลที่เพิ่มขึ้นตามหน้าที่ของสิ่งที่กำลังดำเนินการ หากข้อมูลที่กำลังดำเนินการอยู่มีขนาดเล็กก็ไม่เกี่ยวข้องกับการหารือเกี่ยวกับ Big-O เพราะคุณไม่ได้สนใจที่จะเติบโต

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

สำหรับnขนาดเล็กให้ใช้สิ่งที่สะดวก

หากคุณกำลังเดินทางข้ามประเทศคุณต้องดูวิธีเพิ่มประสิทธิภาพการขับขี่ระยะทางก๊าซของคุณ ฯลฯ


5
"สำหรับ n ขนาดเล็กให้ใช้สิ่งที่สะดวก - หากคุณดำเนินการบ่อยครั้งให้เลือกที่เร็วที่สุด (สำหรับของคุณ) ดูเพิ่มเติมที่นี่n
ราฟาเอล

4
คำอุปมาที่ยอดเยี่ยม!
Evorlor

1
จากมุมมองทางคณิตศาสตร์ล้วนๆความซับซ้อนเชิงซีกn < infinityขวาจะไม่บอกอะไรคุณเมื่อ
Gordon Gustafson

15

คำพูดค่อนข้างคลุมเครือและไม่แน่นอน มีอย่างน้อยสามวิธีที่เกี่ยวข้องซึ่งสามารถตีความได้

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

จุดการปฏิบัติมากขึ้นก็คือว่าเมื่อเราบอกว่าเวลาทำงานของอัลกอริทึมเป็นนั่นหมายความว่าเพียงว่ามันเป็นasymptotically n 2  ขั้นตอนสำหรับการคงที่บาง  C นั่นคือมีค่าคงที่n 0เช่นนั้นสำหรับn n 0ทั้งหมดอัลกอริทึมใช้เวลาประมาณc n 2ขั้นตอน แต่บางทีn 0 = 100 ,Θ(n2) n2Cn0nn0n2n0=100,000,000และคุณสนใจเฉพาะในกรณีที่ขนาดเล็กกว่านั้นมาก ขอบเขตกำลังสองเชิงกำกับแบบ asymptotic อาจไม่ได้ใช้กับอินสแตนซ์ขนาดเล็กของคุณ คุณอาจจะโชคดีและมันอาจเร็วขึ้นสำหรับอินพุตขนาดเล็ก (หรือคุณอาจจะโชคร้ายและช้ากว่า) ตัวอย่างเช่นสำหรับขนาดเล็ก  , n 2 < 1000 nเพื่อให้คุณอยากจะเรียกใช้ขั้นตอนวิธีกำลังสองกับค่าคงที่ที่ดีกว่าขั้นตอนวิธีการเชิงเส้นที่มีค่าคงที่ไม่ดี ตัวอย่างชีวิตจริงของเรื่องนี้คือการที่มีประสิทธิภาพมากที่สุด asymptotically ขั้นตอนวิธีการคูณเมทริกซ์ (สายพันธุ์ของทองแดง-Winograd , ทำงานในเวลาO ( n 2.3729 ) ) จะไม่ค่อยมีใครใช้ในทางปฏิบัติเพราะStrassen ของOnn2<1000nO(n2.3729) อัลกอริทึมเร็วขึ้นเว้นแต่เมทริกซ์ของคุณจะใหญ่มากO(n2.8074)

จุดที่สามคือว่าถ้า  มีขนาดเล็กn 2และแม้กระทั่งn 3  มีขนาดเล็ก ตัวอย่างเช่นหากคุณต้องการเรียงลำดับข้อมูลสองสามพันรายการและคุณต้องการเรียงลำดับเพียงครั้งเดียวอัลกอริทึมการเรียงลำดับก็ดีพอ: a Θ ( n 2nn2n3Θ(n2)อัลกอริทึมยังคงต้องการเพียงแค่คำสั่งหลายสิบล้านในการจัดเรียงข้อมูลของคุณซึ่งไม่ได้มีเวลามากบนซีพียูที่สามารถทำคำสั่งได้นับพันล้านต่อวินาที ตกลงมีหน่วยความจำเข้าถึงด้วยเช่นกัน แต่แม้อัลกอริทึมแบบช้าจะใช้เวลาน้อยกว่าหนึ่งวินาทีดังนั้นจึงน่าจะดีกว่าถ้าใช้อัลกอริทึมแบบง่ายแบบช้าและทำให้ถูกต้องกว่าการใช้อัลกอริธึมที่รวดเร็วและซับซ้อน แต่บั๊กกี้และเรียงลำดับข้อมูลไม่ถูกต้อง


4
ในขณะที่จุดที่ถูกต้องและถูกต้องสมบูรณ์แบบฉันคิดว่าคุณพลาดจุด ดูเหมือนว่าพวกเขาหมายความว่าบางครั้งอัลกอริทึมที่มีดำเนินการดีกว่าอัลกอริทึมที่มีO ( 1 )สำหรับขนาดเล็กพอที่n s นี้เกิดขึ้นเช่นเมื่ออดีตมีเวลาทำงาน10 n + 50ในขณะที่วิ่งหลังในเวลา100000 แล้วสำหรับnพอขนาดเล็กมันเป็นจริงได้เร็วขึ้นที่จะใช้O ( n )โปรโตคอล O(n)O(1)n10n+50100000nO(n)
Ran G.

@RanG นั่นไม่ได้มาในกรณีที่สองของฉันใช่ไหม (โดยเฉพาะถ้าฉันแก้ไขให้พูดอะไรบางอย่างเช่น "อัลกอริทึมเชิงเส้นที่มีค่าคงที่ดีอาจเอาชนะอัลกอริธึมคงที่ / ลอการิทึมที่มีค่าคงที่ไม่ดี"?)
David Richerby

1
มันจะเป็นการดีถ้าจะพูดถึงความสำคัญของค่าคงที่เมื่อnมีค่าน้อย มันเป็นสิ่งที่อาจไม่เกิดขึ้นกับคนที่ไม่เคยได้ยินมาก่อน
Rob Watts

9

Big-O สัญกรณ์พูดเพียงบางอย่างเกี่ยวกับพฤติกรรมของ n ขนาดใหญ่โดยพลการ ยกตัวอย่างเช่นหมายถึงว่ามีความคงที่ c> 0 และจำนวนเต็มn 0เช่นว่าF ( n ) < n 2สำหรับทุกn > n 0(n)=O(n2)n0(n)<n2n>n0

ในหลายกรณีคุณสามารถหาค่าคงที่ c และพูดว่า "สำหรับทุก ๆ n> 0, f (n) มีค่าประมาณ " ซึ่งเป็นข้อมูลที่มีประโยชน์ที่จะมี แต่ในบางกรณีนี้ไม่เป็นความจริง ถ้า f (n) = n 2 + 10 18 แสดงว่าเป็นการเข้าใจผิดทั้งหมด ดังนั้นเพียงเพราะบางสิ่งเป็น O (n ^ 2) ไม่ได้หมายความว่าคุณสามารถปิดสมองของคุณและละเว้นการทำงานที่แท้จริงn2n2+1018

ในทางกลับกันหากคุณเพียงแค่พบค่า n = 1, 2 และ 3 เท่านั้นในทางปฏิบัติมันไม่ได้สร้างความแตกต่างที่ f (n) ทำเพื่อ n ≥ 4 ดังนั้นคุณอาจพิจารณา f ( n) = O (1) โดยมี c = สูงสุด (f (1), f (2), f (3)) และนั่นก็หมายความว่ามีขนาดเล็กพอ: ถ้าการอ้างว่า f (n) = O (1) ไม่ทำให้คุณเข้าใจผิดหากค่า f (n) ที่คุณพบมีเพียงค่าเดียวเท่านั้น "ขนาดเล็กพอ"


5

ถ้ามันไม่เติบโตมันเป็น O (1)

คำสั่งของผู้เขียนเป็นจริงบิต

คำสั่งการเติบโตอธิบายถึงสิ่งที่เกิดขึ้นกับปริมาณงานที่คุณต้องทำเมื่อNเพิ่มขึ้น ถ้าคุณรู้ว่าจะไม่เพิ่มขึ้นปัญหาของคุณได้อย่างมีประสิทธิภาพNO(1)

จำไว้O(1)ว่าไม่ได้แปลว่า "เร็ว" อัลกอริทึมที่มักจะต้อง 1000000000000 O(1)ขั้นตอนในการที่สมบูรณ์ อัลกอริทึมที่ใช้เวลาทุกที่ 1-200 ขั้นตอน O(1)แต่ไม่เคยมากขึ้นคือ [1]

หากขั้นตอนวิธีการของคุณใช้เวลาตรงN ^ 3ขั้นตอนและคุณรู้ว่าNไม่สามารถจะมากกว่า 5 ก็ไม่สามารถใช้เวลากว่า 125 O(1)ขั้นตอนเพื่อให้มันได้อย่างมีประสิทธิภาพ

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


[1] ตัวอย่างเช่นการค้นหาในแฮชคือO(1)แม้ว่าการชนกันของแฮชหมายความว่าคุณอาจต้องดูหลาย ๆ รายการในที่เก็บข้อมูลชุดเดียวตราบใดที่มีข้อ จำกัด อย่างหนักเกี่ยวกับจำนวนรายการที่สามารถอยู่ในที่เก็บข้อมูลนั้น


1
ฟังดูดีทั้งหมดยกเว้นเรื่องนี้: "หากอัลกอริทึมของคุณใช้เวลา N ^ 3 ขั้นตอนทั้งหมดและคุณรู้ว่า N ไม่สามารถเกิน 5 ได้จะไม่สามารถทำได้มากกว่า 125 ขั้นตอนดังนั้นจึงเป็น O (1)" . ถ้าอัลกอริทึมรับจำนวนเต็มและการสนับสนุนจำนวนเต็มสูงสุดของฉันคือ 32767 มันเป็น O (1) หรือไม่? เห็นได้ชัดว่าไม่ Big-O ไม่เปลี่ยนแปลงตามข้อ จำกัด ของพารามิเตอร์ มันเป็น O (n) แม้ว่าคุณจะรู้ว่า 0 <n <3 เพราะ n = 2 จะใช้เวลาสองเท่าตราบใดที่ n = 1
JSobell

3
@JSobell แต่มันเป็น O (1) หากมีข้อ จำกัด ที่ จำกัด n ของคุณสำหรับ f (n) แสดงว่ามันไม่สามารถเติบโตได้อย่างไม่มีกำหนด หาก n ของคุณถูก จำกัด ด้วย 2 ^ 15 ฟังก์ชั่นที่ยอดเยี่ยมของคุณคือ n ^ 2 g(n) = min(f(2^15), f(n))- ซึ่งอยู่ใน O (1) ที่กล่าวว่าในทางปฏิบัติค่าคงที่มีความสำคัญอย่างมากและชัดเจนว่า n อาจมีขนาดใหญ่พอที่การวิเคราะห์เชิงซีกมีประโยชน์
Voo

2
@JSobell นี่คล้ายกับคำถามที่ว่าคอมพิวเตอร์เป็น "ทัวริงที่สมบูรณ์" จริงหรือไม่เนื่องจากพวกเขาในทางเทคนิคไม่มีพื้นที่เก็บข้อมูลที่ไม่มีที่สิ้นสุด ในทางเทคนิคแล้วคอมพิวเตอร์ไม่ใช่เครื่องทัวริงที่ "เป็นจริง" ในทางปฏิบัติไม่มีสิ่งเช่น "เทปไม่มีที่สิ้นสุด" แต่ฮาร์ดไดรฟ์เข้ามาใกล้พอ
Kyle Strand

ฉันเขียนระบบความเสี่ยงทางการเงินเมื่อหลายปีก่อนที่เกี่ยวข้องกับการจัดการเมทริกซ์ n ^ 5 ดังนั้นจึงมีข้อ จำกัด ในทางปฏิบัติที่ n = 20 ก่อนที่ทรัพยากรจะกลายเป็นปัญหา
JSobell

ขออภัยกด Enter เร็วเกินไป ฉันเขียนระบบความเสี่ยงทางการเงินเมื่อหลายปีก่อนที่เกี่ยวข้องกับการจัดการเมทริกซ์ n ^ 5 ดังนั้นจึงมีข้อ จำกัด ในทางปฏิบัติที่ n = 20 ก่อนที่ทรัพยากรจะกลายเป็นปัญหา ตามตรรกะที่มีข้อบกพร่องนี้ฟังก์ชั่นที่สร้างขึ้นคือ O (1) เพราะฉันมีขอบเขตเท่ากับ 20 เมื่อไคลเอนต์บอกว่า "อืมบางทีเราควรย้ายมันไปที่ 40 เป็นขีด จำกัด ... ใช่อัลกอริทึมคือ O (1) ) ดังนั้นจึงไม่มีปัญหา "... นี่คือสาเหตุที่ขอบเขตของอินพุตไม่มีความหมาย ฟังก์ชั่นคือ O (n ^ 5) ไม่ใช่ O (1) และนี่คือตัวอย่างที่ใช้งานได้จริงว่าทำไม Big-O จึงไม่ขึ้นกับขอบเขต
JSobell

2

ตอนนี้ฉันสามารถใช้ hashtable และมีการค้นหา O (1) (ออกจากการใช้ hashtable โดยเฉพาะ) แต่ถ้าฉันมีรายการเช่นฉันจะมีการค้นหา O (n) ด้วยความจริงแล้วทั้งสองนี้จะเหมือนกันถ้าคอลเล็กชั่นมีขนาดเล็กพอ แต่พอถึงจุดหนึ่งพวกเขาก็แตกต่าง ... จุดนั้นคืออะไร?

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


หากคุณต้องการแน่ใจให้ทำการทดลองเพื่อดูว่าโครงสร้างข้อมูลใดดีกว่าสำหรับพารามิเตอร์ของคุณ
Yuval Filmus

@Telastyn Yuval Filmus ถูกต้องถ้าคุณต้องการให้แน่ใจจริงๆ ฉันรู้ชื่อบุคคล Jim พารามิเตอร์ของเขาก็โอเค แต่เขาไม่ฟังคำแนะนำอย่างนั้นของ Yuval คุณควรฟัง Yuval จริงๆเพื่อให้แน่ใจและปลอดภัย
InformedA

2

ในขณะที่การอ้างอิงเป็นจริง (แต่คลุมเครือ) ก็มีอันตรายเช่นกัน Imo คุณควรดูความซับซ้อนในขั้นตอนการสมัครของคุณ

มันง่ายเกินไปที่จะพูดว่า: เฮ้ฉันมีเพียงรายการเล็ก ๆ เท่านั้นถ้าฉันต้องการตรวจสอบว่ารายการ A อยู่ในรายการหรือไม่ฉันจะเขียนลูปง่าย ๆ เพื่อสำรวจรายการและเปรียบเทียบรายการ

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

(โปรดทราบว่ามันยังคงเป็นรายการเล็ก ๆ )

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

ปรากฎว่ารายชื่อนั้นเป็นรายชื่อลูกค้าและลูกค้าของเรามีเพียงลูกค้า 100 รายเท่านั้นดังนั้นจึงไม่มีใครสังเกตเห็น การดำเนินการเติมข้อมูลรายการนั้นเป็นการดำเนินการ O (1) เนื่องจากใช้เวลาน้อยกว่าหนึ่งมิลลิวินาที ไม่มากเมื่อมีลูกค้าเพิ่ม 10,000 คน

และหลายปีหลังจากการตัดสินใจ O (1) ที่ไม่ดีเดิม บริษัท เกือบจะสูญเสียลูกค้ารายใหญ่ ทั้งหมดเกิดจากข้อผิดพลาดในการออกแบบ / การสันนิษฐานเล็กน้อยเมื่อปี


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

1

แรงจูงใจในการทำเช่นนั้นขึ้นอยู่กับความคิดที่ไม่ถูกต้องที่ O (1) ดีกว่า O (lg n) เสมอดีกว่า O (n) ลำดับของการดำเนินการแบบซีมโทติคนั้นเกี่ยวข้องเฉพาะในกรณีที่ขนาดจริงของปัญหาใหญ่มาก

ถ้าฉันมีอัลกอริธึมสองครั้ง:

  • เข้าสู่ระบบ (n) 10000
  • 1 + n

จากนั้นก็มีบางจุดที่พวกเขาข้าม สำหรับnขนาดเล็กกว่านั้นอัลกอริทึม "เชิงเส้น" จะเร็วกว่าและยิ่งnใหญ่กว่านั้นอัลกอริทึม "ลอการิทึม" จะเร็วขึ้น หลายคนทำผิดพลาดในการสมมติว่าอัลกอริธึมลอการิทึมเร็วกว่า แต่สำหรับขนาดเล็กnมันไม่ใช่

ถ้า n ยังเล็กอยู่ทุกปัญหาคือ O (1)!

ฉันคาดเดาสิ่งที่นี่หมายถึงว่าถ้าnมี จำกัด ทุกปัญหาคือ O (1) ตัวอย่างเช่นหากเราเรียงลำดับเลขจำนวนเต็มเราอาจเลือกใช้ quicksort O(n*log(n))อย่างชัดเจน แต่ถ้าเราตัดสินใจว่ามีไม่เคยจะมากกว่า2^64=1.8446744e+19จำนวนเต็มแล้วเรารู้ว่าn*log(n)<= <=1.8446744e+19*log(1.8446744e+19) 1.1805916e+21ดังนั้นอัลกอริทึมจะใช้เวลาน้อยกว่า1.1805916e+21"หน่วยเวลา" เสมอ เป็นที่เวลาคงที่เราสามารถพูดได้ว่าอัลกอริทึมสามารถทำได้ในเวลาคงที่ O(1)-> (โปรดทราบว่าแม้ว่าหน่วยเวลาเหล่านั้นจะมีหน่วยเป็นนาโนวินาทีนั่นเป็นจำนวนรวมที่ยิ่งใหญ่กว่า 37411 ปี) O(1)แต่ก็ยังคง


0

ฉันสงสัยว่าคำตอบเหล่านี้จำนวนมากขาดแนวคิดพื้นฐาน O (1): O (n) ไม่เหมือนกับ f (1): f (n) โดยที่ f คือฟังก์ชันเดียวกันเนื่องจาก O ไม่ได้แทนฟังก์ชันเดี่ยว แม้แต่กราฟที่ดีของ Schwern ก็ไม่ถูกต้องเพราะมันมีแกน Y เหมือนกันสำหรับทุกบรรทัด สำหรับทุกคนที่ใช้แกนเดียวกันเส้นนั้นจะต้องเป็น fn1, fn2 และ fn3 โดยที่แต่ละฟังก์ชั่นนี้มีฟังก์ชั่นที่สามารถเปรียบเทียบประสิทธิภาพกับคนอื่น ๆ ได้โดยตรง

ฉันเคยได้ยินหลายครั้งว่าสำหรับค่าน้อยพอของ n, O (n) สามารถคิดเกี่ยวกับ / ถือว่าราวกับว่ามันเป็น O (1)

ถ้า n = 1 พวกมันเหมือนกันหรือไม่ ไม่ฟังก์ชั่นที่อนุญาตให้มีการวนซ้ำของตัวแปรนั้นไม่มีอะไรที่เหมือนกันกับอันที่ไม่สัญกรณ์ O ขนาดใหญ่ไม่สนใจและไม่ควรทำเช่นนั้น

สัญกรณ์ Big-O อยู่ตรงนั้นเพื่อแสดงว่าเกิดอะไรขึ้นเมื่อเรามีกระบวนการวนซ้ำและประสิทธิภาพ (เวลาหรือทรัพยากร) จะเสื่อมลงเมื่อเพิ่มขึ้น 'n'

ดังนั้นเพื่อตอบคำถามที่แท้จริง ... ฉันจะบอกว่าคนที่อ้างสิทธิ์นั้นไม่เข้าใจสัญกรณ์ Big-O อย่างถูกต้องเพราะเป็นการเปรียบเทียบที่ไร้เหตุผล

นี่คือคำถามที่คล้ายกัน: ถ้าฉันวนผ่านสตริงของตัวละครและฉันรู้ว่าโดยทั่วไปแล้วสตริงของฉันจะน้อยกว่า 10 ตัวอักษรฉันสามารถพูดได้ว่ามันเทียบเท่ากับ O (1) แต่ถ้าสตริงของฉันยาวกว่าฉัน บอกว่าเป็น O (n)

ไม่เพราะสตริง 10 อักขระใช้เวลานานถึง 10 เท่าของสตริง 1 อักขระ แต่น้อยกว่า 1,000 สตริงเป็น 100 เท่า! มันคือ O (n)


O(1)(ผม)ผมสูงสุด{(0),...,(10)}O(1)

ใช่และนี่คือตัวอย่างของการที่สัญลักษณ์ Big-O เข้าใจผิดโดยทั่วไป ตามการโต้เถียงของคุณถ้าฉันรู้ว่าค่าสูงสุดของ n คือ 1,000,000 แล้วฟังก์ชันของฉันคือ O (1) อันที่จริงฟังก์ชั่นของฉันอาจดีที่สุด O (1) และที่แย่ที่สุด O (n) สัญกรณ์นี้ใช้เพื่ออธิบายความซับซ้อนของอัลกอริทึมไม่ใช่การประยุกต์ใช้อย่างเป็นรูปธรรมและเรามักจะใช้อันที่แพงที่สุดในการอธิบายสถานการณ์ไม่ใช่ที่ดีที่สุด ที่จริงแล้วโดยการโต้แย้งของคุณทุกฟังก์ชั่นเดียวที่อนุญาตให้ n <2 คือ O (1)! :)
JSobell

n<2O(1)(n)(10)nO(1)

ขออภัย แต่ถ้าคุณบอกว่าการรู้ขอบเขตบนของ n ทำให้ฟังก์ชัน O (1) คุณกำลังบอกว่าการเป็นตัวแทนสัญกรณ์เกี่ยวข้องโดยตรงกับค่าของ n และไม่ใช่ ทุกอย่างที่คุณพูดถึงถูกต้อง แต่แนะนำว่าเนื่องจาก n มีขอบเขตเป็น O (1) ไม่ถูกต้อง ในทางปฏิบัติมีสถานที่ที่สิ่งที่คุณอธิบายอาจสังเกตได้ แต่เรากำลังมองหาสัญลักษณ์ Big-O ที่นี่ไม่ใช่การเขียนรหัสการทำงาน ดังนั้นอีกครั้งทำไมคุณถึงแนะนำให้ n ที่มีค่าสูงสุด 10 จะทำให้มันเป็น O (1)? ทำไม 10 ทำไมไม่ใช่ 65535 หรือ 2 ^ 64
JSobell

ต้องบอกว่าถ้าคุณเขียนฟังก์ชั่นที่ดึงสตริงออกมาถึง 10 ตัวอักษรจากนั้นจะวนซ้ำไปเรื่อย ๆ สตริงนั้นก็จะเป็น O (1) เพราะ n คือ 10 เสมอ :)
JSobell

0

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

O(1)O(1)

ทีนี้มาลองชุดขององค์ประกอบ 10 อันที่มีขนาดค่อนข้างเล็กและมีอัลกอริธึมไม่กี่ตัวที่จะเรียงมัน สมมติว่าเราเก็บองค์ประกอบไว้ในโครงสร้างที่ให้อัลกอริทึมที่สามารถจัดเรียงองค์ประกอบในเวลาคงที่ได้ สมมติว่าอัลกอริธึมการเรียงลำดับของเราสามารถมีความซับซ้อนดังต่อไปนี้ (พร้อมเครื่องหมายใหญ่ -O):

  1. O(1)
  2. O(n)
  3. O(nล.โอก.(n))
  4. O(n2)

O(1)

ตอนนี้เราจะ "เปิดเผย" ความซับซ้อนที่แท้จริงของอัลกอริธึมการเรียงลำดับที่กล่าวถึงข้างต้น (โดยที่ "ความจริง" หมายถึงไม่ซ่อนค่าคงที่) ซึ่งแสดงด้วยจำนวนขั้นตอนที่ต้องทำให้เสร็จสิ้น

  1. 200
  2. 11n
  3. 4nล.โอก.(n)
  4. 1n2

หากอินพุตของเรามีขนาด 10 แสดงว่าเป็นขั้นตอนที่แน่นอนสำหรับทุกอัลกอริทึมที่กล่าวถึงข้างต้น:

  1. 200
  2. 11×10=110
  3. 4×10×3.32134
  4. 1×100=100

O(n2)O(1),O(n)O(nล.โอก.(n))O(n2)O(1)O(n2)O(1)

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