มีกรณีใดบ้างที่คุณต้องการO(log n)
ความซับซ้อนของO(1)
เวลากับความซับซ้อนของเวลา? หรือO(n)
เพื่อO(log n)
?
คุณมีตัวอย่างหรือไม่?
มีกรณีใดบ้างที่คุณต้องการO(log n)
ความซับซ้อนของO(1)
เวลากับความซับซ้อนของเวลา? หรือO(n)
เพื่อO(log n)
?
คุณมีตัวอย่างหรือไม่?
คำตอบ:
มีหลายเหตุผลที่จะชอบอัลกอริธึมที่มีความซับซ้อนของเวลา O ใหญ่มากกว่าในช่วงล่าง:
10^5
ได้ดีกว่าในมุมมองของ big-O มากกว่า1/10^5 * log(n)
( O(1)
vs O(log(n)
) แต่สำหรับเหตุผลที่เหมาะสมที่สุดn
ตัวแรกจะทำงานได้ดีกว่า ยกตัวอย่างเช่นความซับซ้อนที่ดีที่สุดสำหรับการคูณเมทริกซ์คือO(n^2.373)
แต่ค่าคงที่นั้นสูงมากจนไม่มีการใช้ห้องสมุดการคำนวณO(n*log(n))
หรือO(n^2)
อัลกอริทึมO(log log N)
ซับซ้อนเวลาที่จะหารายการ O(log n)
แต่ยังมีต้นไม้ไบนารีซึ่งพบในที่เดียวกัน แม้ว่าจะมีn = 10^20
ความแตกต่างจำนวนมากO(n^2)
และต้องการO(n^2)
หน่วยความจำ มันอาจจะดีกว่าเมื่อO(n^3)
เวลาผ่านไปและO(1)
พื้นที่เมื่อ n ไม่ใหญ่จริง ๆ ปัญหาคือคุณสามารถรอเป็นเวลานาน แต่สงสัยอย่างมากว่าคุณสามารถหา RAM ที่ใหญ่พอที่จะใช้กับอัลกอริทึมของคุณO(n^2)
แย่กว่า quicksort หรือการรวม แต่เมื่ออัลกอริทึมออนไลน์สามารถเรียงลำดับรายการค่าได้อย่างมีประสิทธิภาพตามที่ได้รับ (เป็นอินพุตของผู้ใช้) ซึ่งอัลกอริธึมอื่น ๆ ในรายการค่าทั้งหมดมีค่าคงที่ซ่อนอยู่เสมอซึ่งสามารถลดลงในอัลกอริทึมO (log n ) ดังนั้นจึงสามารถทำงานได้เร็วขึ้นในทางปฏิบัติสำหรับข้อมูลในชีวิตจริง
นอกจากนี้ยังมีข้อกังวลเกี่ยวกับพื้นที่ (เช่นวิ่งบนเครื่องปิ้งขนมปัง)
นอกจากนี้ยังมีข้อกังวลเกี่ยวกับเวลาของนักพัฒนา - O (บันทึกn ) อาจง่ายกว่า 1,000 ×ในการนำไปใช้และตรวจสอบ
lg n
เป็นเช่นนั้นดังนั้นใกล้k
มากสำหรับn
การดำเนินการส่วนใหญ่จะไม่สังเกตเห็นความแตกต่าง
ฉันประหลาดใจที่ไม่มีใครพูดถึงแอปพลิเคชันที่ผูกกับหน่วยความจำ
อาจมีอัลกอริทึมที่มีการดำเนินการจุดลอยตัวน้อยลงเนื่องจากความซับซ้อน (เช่นO (1) < O (log n )) หรือเนื่องจากค่าคงที่ด้านหน้าของความซับซ้อนนั้นมีขนาดเล็กกว่า (เช่น2 n 2 <6 n 2 ) . ไม่ว่าคุณจะยังคงชอบอัลกอริทึมที่มี FLOP มากกว่าหรือไม่หากอัลกอริทึม FLOP ที่ต่ำกว่านั้นถูกผูกไว้กับหน่วยความจำมากกว่า
สิ่งที่ฉันหมายถึงโดย "ขอบเขตของหน่วยความจำ" คือคุณมักจะเข้าถึงข้อมูลที่อยู่นอกแคชตลอดเวลา เพื่อดึงข้อมูลนี้คุณต้องดึงหน่วยความจำจากพื้นที่หน่วยความจำจริงของคุณไปยังแคชของคุณก่อนที่คุณจะสามารถดำเนินการกับมันได้ ขั้นตอนการดึงข้อมูลนี้มักจะค่อนข้างช้า - ช้ากว่าการปฏิบัติการของคุณมาก
ดังนั้นหากอัลกอริทึมของคุณต้องการการดำเนินการเพิ่มเติม (แต่การดำเนินการเหล่านี้จะดำเนินการกับข้อมูลที่มีอยู่แล้วในแคช [และไม่จำเป็นต้องมีการดึงข้อมูล]) มันจะยังคงออกอัลกอริทึมของคุณ ข้อมูลแคช [และดังนั้นจึงจำเป็นต้องมีการดึงข้อมูล]) ในแง่ของเวลาที่เกิดขึ้นจริง
O(logn)
O(1)
คุณสามารถจินตนาการถึงสถานการณ์ที่เป็นไปได้ทั้งหมดของคุณn
แอปพลิเคชันที่ผูกกับหน่วยความจำน้อยกว่าจะทำงานในเวลาที่เร็วขึ้นถึงแม้จะมีความซับซ้อนสูงกว่าก็ตาม
ในบริบทที่มีความปลอดภัยของข้อมูลเป็นกังวลขั้นตอนวิธีการที่ซับซ้อนมากขึ้นอาจจะดีกว่าที่จะวิธีที่ซับซ้อนน้อยลงหากขั้นตอนวิธีการที่ซับซ้อนมากขึ้นมีความต้านทานที่ดีกว่าที่จะโจมตีระยะเวลา
(n mod 5) + 1
ก็ยังคงยังเผยข้อมูลเกี่ยวกับO(1)
n
ดังนั้นอัลกอริทึมที่ซับซ้อนมากขึ้นพร้อมรันไทม์ที่ราบรื่นกว่าอาจจะดีกว่าแม้ว่ามันอาจจะไม่แสดงอาการ
Alistra จับมัน แต่ล้มเหลวในการให้ตัวอย่างใด ๆ ดังนั้นฉันจะ
คุณมีรายการรหัส 10,000 UPC สำหรับสิ่งที่ร้านค้าของคุณขาย 10 หลัก UPC, จำนวนเต็มราคา (ราคาเป็นเพนนี) และ 30 ตัวอักษรสำหรับการอธิบาย
วิธีการ O (บันทึก N): คุณมีรายการเรียงลำดับ 44 ไบต์ถ้า ASCII, 84 ถ้า Unicode ให้ถือว่า UPC เป็น int64 และรับ 42 & 72 ไบต์ 10,000 เรคคอร์ด - ในกรณีสูงสุดที่คุณกำลังดูอยู่ภายใต้พื้นที่เก็บข้อมูลเมกะไบต์
O (1) วิธีการ: อย่าเก็บ UPC ไว้แทนคุณใช้มันเป็นรายการในอาเรย์ ในกรณีที่น้อยที่สุดคุณกำลังดูพื้นที่เก็บข้อมูลเกือบหนึ่งในสามของเทราไบต์
วิธีการที่คุณใช้นั้นขึ้นอยู่กับฮาร์ดแวร์ของคุณ ในการกำหนดค่าสมัยใหม่ที่สมเหตุสมผลส่วนใหญ่คุณจะใช้วิธีการ log N ฉันสามารถนึกภาพแนวทางที่สองว่าเป็นคำตอบที่ถูกต้องถ้าด้วยเหตุผลบางอย่างที่คุณใช้ในสภาพแวดล้อมที่ RAM สั้นมาก แต่คุณมีพื้นที่เก็บข้อมูลมากมาย หนึ่งในสามของเทราไบต์บนดิสก์ไม่ใช่เรื่องใหญ่การรับข้อมูลของคุณในหนึ่งโพรบของดิสก์นั้นคุ้มค่า วิธีไบนารีง่าย ๆ ใช้เวลาเฉลี่ย 13 (อย่างไรก็ตามโปรดทราบว่าโดยการจัดกลุ่มคีย์ของคุณคุณสามารถทำให้การอ่าน 3 แบบมีการรับประกันและในทางปฏิบัติคุณจะแคชครั้งแรก)
malloc(search_space_size)
และการลงรายการในสิ่งที่ส่งคืนนั้นง่ายเหมือนที่ได้รับ
พิจารณาต้นไม้สีแดงดำ มันมีการเข้าถึง, การค้นหา, O(log n)
แทรกและลบของ เปรียบเทียบกับอาร์เรย์ซึ่งมีการเข้าถึงและส่วนที่เหลือของการดำเนินงานที่มีO(1)
O(n)
เมื่อได้รับแอปพลิเคชันที่เราแทรกลบหรือค้นหาบ่อยกว่าที่เราเข้าถึงและตัวเลือกระหว่างโครงสร้างทั้งสองนี้เท่านั้นเราจะชอบต้นไม้สีแดงดำ ในกรณีนี้คุณอาจบอกว่าเราชอบO(log n)
เวลาเข้าถึงต้นไม้ที่มีความยุ่งยากมากกว่า
ทำไม? เพราะการเข้าถึงไม่ใช่ความกังวลที่สำคัญของเรา เรากำลังทำการแลกเปลี่ยน: ประสิทธิภาพการทำงานของแอปพลิเคชันของเรานั้นได้รับอิทธิพลอย่างมากจากปัจจัยอื่นนอกเหนือจากที่กล่าวมานี้ เราอนุญาตให้อัลกอริทึมนี้ประสบความสำเร็จเนื่องจากเราสร้างผลกำไรจำนวนมากโดยการปรับอัลกอริทึมอื่น ๆ ให้เหมาะสม
ดังนั้นคำตอบสำหรับคำถามของคุณคือ: เมื่ออัตราการเติบโตของอัลกอริทึมไม่ใช่สิ่งที่เราต้องการเพิ่มประสิทธิภาพเมื่อเราต้องการเพิ่มประสิทธิภาพอย่างอื่น. คำตอบอื่น ๆ ทั้งหมดเป็นกรณีพิเศษของเรื่องนี้ บางครั้งเราปรับเวลาการทำงานอื่น ๆ ให้เหมาะสม บางครั้งเราปรับให้เหมาะสมสำหรับหน่วยความจำ บางครั้งเราปรับให้เหมาะสมเพื่อความปลอดภัย บางครั้งเราเพิ่มประสิทธิภาพการบำรุงรักษา บางครั้งเราปรับให้เหมาะสมสำหรับเวลาในการพัฒนา แม้แต่ค่าคงที่การเอาชนะที่ต่ำพอที่จะสำคัญคือการปรับให้เหมาะสมสำหรับเวลาทำงานเมื่อคุณรู้ว่าอัตราการเติบโตของอัลกอริทึมนั้นไม่ได้ส่งผลกระทบมากที่สุดต่อเวลาทำงาน (หากชุดข้อมูลของคุณอยู่นอกช่วงนี้คุณจะปรับให้เหมาะสมสำหรับอัตราการเติบโตของอัลกอริทึมเพราะในที่สุดมันจะครองค่าคงที่) ทุกอย่างมีค่าใช้จ่ายและในหลาย ๆ กรณีเราแลกเปลี่ยนต้นทุนการเติบโตที่สูงขึ้นสำหรับ อัลกอริทึมเพื่อเพิ่มประสิทธิภาพอย่างอื่น
O(log n)
"ต้นไม้สีแดงดำ"? การแทรกของ5
ในตำแหน่งที่ 2 ของอาร์เรย์[1, 2, 1, 4]
จะส่งผลให้[1, 2, 5, 1 4]
(องค์ประกอบ4
จะได้รับการปรับปรุงดัชนีจาก 3 เป็น 4) คุณจะรับพฤติกรรมนี้ได้อย่างไรในO(log n)
"ต้นไม้สีแดงดำ" ที่คุณอ้างอิงว่าเป็น "รายการที่เรียงลำดับ"?
ใช่.
ในกรณีจริงเราทำการทดสอบเกี่ยวกับการค้นหาตารางด้วยคีย์สตริงทั้งสั้นและยาว
เราใช้ a std::map
, a ที่std::unordered_map
มีแฮชที่สุ่มตัวอย่างมากที่สุด 10 เท่าตลอดความยาวของสตริง (กุญแจของเรามีแนวโน้มที่จะคล้าย guid ดังนั้นนี่เป็นสิ่งที่ดี) และแฮชที่สุ่มตัวอย่างทุกตัวละคร (ในทางทฤษฎีลดการชน) เวกเตอร์ที่ไม่เรียงลำดับที่เราทำการ==
เปรียบเทียบและ (ถ้าฉันจำได้อย่างถูกต้อง) เวกเตอร์ที่ไม่เรียงลำดับที่เราเก็บแฮชไว้ก่อนอื่นให้เปรียบเทียบแฮชแล้วเปรียบเทียบอักขระ
อัลกอริทึมเหล่านี้มีตั้งแต่O(1)
(unordered_map) ถึงO(n)
(การค้นหาเชิงเส้น)
สำหรับขนาดที่ไม่ใหญ่นักมักจะ O (n) เอาชนะ O (1) เราสงสัยว่านี่เป็นเพราะคอนเทนเนอร์ที่ใช้โหนดต้องการให้คอมพิวเตอร์ของเรากระโดดไปรอบ ๆ ในหน่วยความจำมากขึ้นในขณะที่คอนเทนเนอร์ที่ใช้เชิงเส้นไม่ได้
O(lg n)
มีอยู่ระหว่างคนทั้งสอง ฉันจำไม่ได้ว่ามันเป็นอย่างไร
ความแตกต่างด้านประสิทธิภาพนั้นไม่ใหญ่มากนักและจากข้อมูลที่ใหญ่กว่านั้นชุดแฮชที่ทำงานได้ดีกว่ามาก ดังนั้นเราจึงติดอยู่กับแผนที่ที่ไม่มีการเรียงลำดับตามแฮช
ในทางปฏิบัติสำหรับ n ขนาดที่เหมาะสมคือO(lg n)
O(1)
หากคอมพิวเตอร์ของคุณมีเพียงห้องพักสำหรับ 4 พันล้านรายการในตารางของคุณแล้วตั้งอยู่ทางทิศเหนือโดยO(lg n)
32
(lg (2 ^ 32) = 32) (ในสาขาวิทยาศาสตร์คอมพิวเตอร์ lg เป็นมือสั้นสำหรับการบันทึก 2)
ในทางปฏิบัติอัลกอริทึมของ lg (n) ช้ากว่า O (1) อัลกอริธึมไม่ใช่เพราะปัจจัยการเติบโตแบบลอการิทึม แต่เนื่องจากส่วนของ lg (n) หมายความว่ามีความซับซ้อนในอัลกอริทึมในระดับหนึ่งและความซับซ้อนนั้นเพิ่ม มีปัจจัยคงที่ที่ใหญ่กว่า "การเติบโต" ใด ๆ จากคำว่า lg (n)
อย่างไรก็ตามอัลกอริทึม O (1) ที่ซับซ้อน (เช่นการแมปแฮช) สามารถมีปัจจัยคงที่ที่คล้ายกันหรือใหญ่กว่าได้อย่างง่ายดาย
ความเป็นไปได้ในการประมวลผลอัลกอริทึมแบบขนาน
ฉันไม่รู้ว่ามีตัวอย่างสำหรับคลาสO(log n)
หรือO(1)
ไม่ แต่สำหรับปัญหาบางอย่างคุณเลือกอัลกอริทึมที่มีคลาสความซับซ้อนสูงกว่าเมื่ออัลกอริทึมง่ายต่อการเรียกใช้งานแบบขนาน
อัลกอริทึมบางอย่างไม่สามารถขนานกันได้ แต่มีระดับความซับซ้อนต่ำมาก พิจารณาอัลกอริธึมอื่นที่ได้ผลลัพธ์เดียวกันและสามารถขนานได้อย่างง่ายดาย แต่มีคลาสที่ซับซ้อนกว่า เมื่อดำเนินการในเครื่องหนึ่งอัลกอริทึมที่สองจะช้าลง แต่เมื่อดำเนินการกับหลายเครื่องเวลาดำเนินการจริงจะลดลงและลดลงในขณะที่อัลกอริทึมแรกไม่สามารถเร่งความเร็วได้
สมมติว่าคุณกำลังใช้บัญชีดำในระบบสมองกลฝังตัวซึ่งตัวเลขระหว่าง 0 ถึง 1,000,000 อาจถูกขึ้นบัญชีดำ นั่นทำให้คุณมีสองทางเลือก:
การเข้าถึงบิตเซ็ตจะรับประกันการเข้าถึงอย่างต่อเนื่อง ในแง่ของเวลาที่ซับซ้อนมันเป็นสิ่งที่ดีที่สุด ทั้งจากทฤษฏีและจากมุมมองของภาคปฏิบัติ (เป็น O (1) ที่มีค่าโสหุ้ยคงที่ต่ำมาก)
อย่างไรก็ตามคุณอาจต้องการโซลูชันที่สอง โดยเฉพาะอย่างยิ่งถ้าคุณคาดหวังว่าจำนวนของจำนวนเต็มในบัญชีดำจะเล็กมากเพราะมันจะมีประสิทธิภาพของหน่วยความจำมากขึ้น
และแม้ว่าคุณจะไม่ได้พัฒนาระบบฝังตัวที่หน่วยความจำหายากฉันก็สามารถเพิ่มขีด จำกัด โดยพลการของ 1,000,000 ถึง 1,000,000,000,000 และสร้างอาร์กิวเมนต์เดียวกัน จากนั้นบิตเซ็ตจะต้องการหน่วยความจำประมาณ 125G การมีความซับซ้อนของกรณีที่เลวร้ายที่สุดที่รับประกันได้ของ O (1) อาจไม่ทำให้หัวหน้าของคุณมอบเซิร์ฟเวอร์ที่ทรงพลังเช่นนั้น
ที่นี่ฉันต้องการอย่างยิ่งการค้นหาแบบไบนารี (O (log n)) หรือต้นไม้ไบนารี (O (log n)) เหนือบิต O (1) และอาจตารางแฮชที่มีความซับซ้อนของกรณีที่แย่ที่สุดของ O (n) จะเอาชนะพวกเขาทั้งหมดในทางปฏิบัติ
คำตอบของฉันที่นี่การเลือกแบบสุ่มแบบสุ่มอย่างรวดเร็วในทุกแถวของเมทริกซ์สุ่มเป็นตัวอย่างที่อัลกอริทึมที่มีความซับซ้อน O (m) เร็วกว่าหนึ่งด้วยความซับซ้อน O (log (m)) เมื่อm
ไม่ใหญ่เกินไป
ผู้คนตอบคำถามของคุณแล้วดังนั้นฉันจะตอบคำถามที่แตกต่างกันเล็กน้อยว่าผู้คนอาจจะคิดถึงเมื่อมาที่นี่
จำนวนมากของ "O (1) เวลา" ขั้นตอนวิธีและโครงสร้างข้อมูลจริงใช้เวลาเพียงคาดว่า O (1) เวลาหมายความว่าพวกเขาเฉลี่ยเวลาทำงานเป็น O (1) อาจจะเป็นเฉพาะภายใต้สมมติฐานบางอย่าง
ตัวอย่างทั่วไป:แฮชเทเบิลการขยาย "รายการอาร์เรย์" (อาคาอาร์เรย์ / เวกเตอร์ขนาดไดนามิก)
ในสถานการณ์เช่นนี้คุณอาจต้องการใช้โครงสร้างข้อมูลหรืออัลกอริทึมที่มีเวลารับประกันว่าจะถูกจำกัด ขอบเขตลอการิทึมอย่างแน่นอนแม้ว่าพวกเขาอาจทำงานได้แย่ลงโดยเฉลี่ย
ตัวอย่างอาจเป็นโครงสร้างการค้นหาแบบทวิภาคที่สมดุลซึ่งเวลาทำงานโดยเฉลี่ยแย่กว่า แต่ดีกว่าในกรณีที่แย่ที่สุด
คำถามทั่วไปมากขึ้นคือถ้ามีสถานการณ์ที่หนึ่งจะชอบO(f(n))
ขั้นตอนวิธีการไปยังO(g(n))
ขั้นตอนวิธีการแม้g(n) << f(n)
เป็นn
แนวโน้มที่จะอินฟินิตี้ เป็นคนอื่น ๆ ได้กล่าวแล้วคำตอบคืออย่างชัดเจนว่า "ใช่" ในกรณีที่และf(n) = log(n)
g(n) = 1
บางครั้งมันก็ใช่แม้ในกรณีที่f(n)
เป็นพหุนาม แต่g(n)
เป็นเลขชี้กำลัง ตัวอย่างที่มีชื่อเสียงและสำคัญคือSimplex Algorithmสำหรับการแก้ปัญหาการโปรแกรมเชิงเส้น ในปี 1970 O(2^n)
มันก็แสดงให้เห็นว่า ดังนั้นพฤติกรรมที่เลวร้ายยิ่งของมันเป็นไปไม่ได้ แต่พฤติกรรมโดยเฉลี่ยของมันนั้นดีมากแม้สำหรับปัญหาในทางปฏิบัติที่มีตัวแปรและข้อ จำกัด นับหมื่น ในปี 1980 อัลกอริทึมเวลาพหุนาม (เช่นกอัลกอริธึมภายในจุดของ Karmarkar ) สำหรับการเขียนโปรแกรมเชิงเส้นถูกค้นพบ แต่ 30 ปีต่อมาอัลกอริทึมแบบซิมเพล็กซ์ยังคงเป็นอัลกอริธึมที่เลือก (ยกเว้นปัญหาที่มีขนาดใหญ่มาก) นี่คือเหตุผลที่ชัดเจนว่าพฤติกรรมโดยเฉลี่ยของผู้ป่วยมักมีความสำคัญมากกว่าพฤติกรรมที่เลวร้ายกว่า แต่สำหรับเหตุผลที่ละเอียดอ่อนกว่าที่อัลกอริทึมแบบซิมเพล็กซ์นั้นมีข้อมูลมากกว่า
วิธีใส่ 2 เซ็นต์ของฉันใน:
บางครั้งอัลกอริทึมความซับซ้อนที่แย่กว่านั้นจะถูกเลือกแทนที่อัลกอริธึมที่ดีกว่าเมื่ออัลกอริทึมทำงานบนสภาพแวดล้อมฮาร์ดแวร์ที่แน่นอน สมมติว่าอัลกอริทึม O (1) ของเราเข้าถึงองค์ประกอบทุกส่วนของอาเรย์ที่มีขนาดใหญ่และคงที่ไม่ต่อเนื่องเพื่อแก้ปัญหาของเรา จากนั้นวางอาร์เรย์นั้นลงบนฮาร์ดไดรฟ์เชิงกลหรือเทปแม่เหล็ก
ในกรณีนั้นอัลกอริทึม O (logn) (สมมติว่าเข้าถึงดิสก์ตามลำดับ) กลายเป็นที่นิยมมากขึ้น
มีกรณีการใช้งานที่ดีสำหรับการใช้อัลกอริทึม O (log (n)) แทนอัลกอริทึม O (1) ที่คำตอบอื่น ๆ อีกมากมายไม่สนใจ: ความไม่สามารถเปลี่ยนแปลงได้ แผนที่ Hash มี O (1) ทำการใส่และรับสมมติว่ามีการแจกจ่ายค่าแฮชที่ดี แต่พวกเขาต้องการสถานะที่ไม่แน่นอน แผนผังต้นไม้ที่ไม่เปลี่ยนรูปมี O (log (n)) ทำให้และรับซึ่งช้ากว่าซีมโทติค อย่างไรก็ตามการไม่เปลี่ยนรูปอาจมีค่ามากพอที่จะชดเชยประสิทธิภาพที่แย่ลงและในกรณีที่ต้องเก็บรักษาแผนที่หลายเวอร์ชันไว้การเปลี่ยนแปลงไม่ได้ช่วยให้คุณหลีกเลี่ยงการคัดลอกแผนที่ซึ่งเป็น O (n) และสามารถปรับปรุงได้ประสิทธิภาพ.
ง่ายๆ: เนื่องจากค่าสัมประสิทธิ์ - ค่าใช้จ่ายที่เกี่ยวข้องกับการตั้งค่าการจัดเก็บและเวลาดำเนินการของขั้นตอนนั้น - อาจมีขนาดใหญ่กว่ามากโดยมีปัญหาใหญ่ -O น้อยกว่าค่าที่ใหญ่กว่า Big-O เป็นเพียงมาตรการของขั้นตอนวิธีการปรับขยาย
ลองพิจารณาตัวอย่างต่อไปนี้จากพจนานุกรมของแฮ็กเกอร์โดยเสนออัลกอริทึมการเรียงลำดับโดยอาศัยการตีความหลายระดับโลกของกลศาสตร์ควอนตัม :
- อนุญาตให้อาร์เรย์สุ่มโดยใช้กระบวนการควอนตัม
- หากไม่ได้จัดเรียงอาร์เรย์ให้ทำลายจักรวาล
- จักรวาลที่เหลืออยู่ทั้งหมดจะถูกจัดเรียง [รวมทั้งจักรวาลที่คุณอยู่]
(ที่มา: http://catb.org/~esr/jargon/html/B/bogo-sort.html )
ขอให้สังเกตว่าใหญ่ -O ของอัลกอริทึมนี้O(n)
ซึ่งเต้นอัลกอริทึมการเรียงลำดับที่รู้จักใด ๆ ถึงวันที่ในรายการทั่วไป สัมประสิทธิ์ของขั้นตอนเชิงเส้นก็ต่ำมากเช่นกัน (เนื่องจากเป็นเพียงการเปรียบเทียบไม่ใช่แบบสลับที่ทำแบบเชิงเส้น) ในความเป็นจริงอัลกอริทึมที่คล้ายกันสามารถนำมาใช้เพื่อแก้ปัญหาใด ๆ ทั้งในNPและco-NPในเวลาพหุนามเนื่องจากแต่ละวิธีแก้ปัญหาที่เป็นไปได้ (หรือพิสูจน์ได้ว่าไม่มีวิธีแก้ปัญหา) สามารถสร้างขึ้นโดยใช้กระบวนการควอนตัม เวลาพหุนาม
อย่างไรก็ตามในกรณีส่วนใหญ่เราอาจไม่ต้องการรับความเสี่ยงที่หลายโลกอาจไม่ถูกต้องไม่ต้องพูดถึงการดำเนินการตามขั้นตอนที่ 2 นั้นยังคงเป็น "การออกกำลังกายสำหรับผู้อ่าน"
ณ จุดใด ๆ เมื่อ n ถูกล้อมรอบและอัลกอริธึมตัวคูณ O (1) คงที่สูงกว่าขอบเขตบนล็อก (n) ตัวอย่างเช่นการจัดเก็บค่าใน hashset คือ O (1) แต่อาจต้องการการคำนวณฟังก์ชัน hash ที่มีราคาแพง หากรายการข้อมูลสามารถนำมาเปรียบเทียบได้เล็กน้อย (เทียบกับคำสั่งบางอย่าง) และขอบเขตบน n คือ log n นั้นมีความสำคัญน้อยกว่าการคำนวณแฮชในรายการใดรายการหนึ่งการจัดเก็บในต้นไม้ไบนารีแบบสมดุลอาจเร็วกว่าการจัดเก็บใน hashset
ในสถานการณ์เรียลไทม์ที่คุณต้องการขอบเขตบนของ บริษัท คุณจะเลือกเช่น heapsort ซึ่งตรงข้ามกับ Quicksort เพราะพฤติกรรมเฉลี่ยของ heapsort ก็เป็นพฤติกรรมที่เลวร้ายที่สุดเช่นกัน
การเพิ่มคำตอบที่ดีอยู่แล้วตัวอย่างที่ใช้งานได้จริงคือดัชนี Hash กับดัชนี B-tree ในฐานข้อมูล postgres
ดัชนีแฮชจัดทำดัชนีตารางแฮชเพื่อเข้าถึงข้อมูลบนดิสก์ในขณะที่ btree เนื่องจากชื่อแนะนำให้ใช้โครงสร้างข้อมูล Btree
ในเวลา Big-O เหล่านี้คือ O (1) vs O (logN)
ปัจจุบันดัชนีแฮชไม่สนับสนุนใน postgres เนื่องจากในสถานการณ์จริงโดยเฉพาะอย่างยิ่งในระบบฐานข้อมูลการบรรลุการแฮ็กโดยไม่มีการชนกันนั้นยากมาก (อาจนำไปสู่ความซับซ้อนของกรณีที่เลวร้ายที่สุด O) ข้อผิดพลาดเหล่านี้ปลอดภัย (เรียกว่าการบันทึกการเขียนล่วงหน้า - WAL เป็น postgres)
การแลกเปลี่ยนนี้เกิดขึ้นในสถานการณ์นี้เนื่องจาก O (logN) ดีพอสำหรับดัชนีและการใช้ O (1) ค่อนข้างยากและความแตกต่างของเวลาจะไม่สำคัญ
เมื่อn
มีขนาดเล็กและO(1)
ช้าอยู่ตลอดเวลา
หรือ
นี่เป็นกรณีของแอปพลิเคชันด้านความปลอดภัยที่เราต้องการออกแบบปัญหาซึ่งอัลกอริทึมช้าตามวัตถุประสงค์เพื่อหยุดไม่ให้ใครบางคนได้รับคำตอบของปัญหาอย่างรวดเร็วเกินไป
นี่คือตัวอย่างสองสามตัวอย่างจากส่วนบนของหัวของฉัน
O(2^n)
เวลาที่หวังซึ่งn
เป็นความยาวบิตของคีย์ (นี่คือกำลังดุร้าย)อื่น ๆ ใน CS ด่วนเรียงเป็นO(n^2)
ในกรณีที่เลวร้ายที่สุด O(n*log(n))
แต่ในกรณีทั่วไปคือ ด้วยเหตุนี้บางครั้งการวิเคราะห์ "บิ๊กโอ" จึงไม่ใช่สิ่งเดียวที่คุณใส่ใจเมื่อวิเคราะห์ประสิทธิภาพของอัลกอริทึม
O(log n)
อัลกอริธึมกับO(1)
อัลกอริทึมถ้าเข้าใจก่อนหน้านี้ แต่ไม่ใช่อัลกอริธึม ...