โดยทางโปรแกรมแล้วการหาสัญกรณ์กุ๊บ (สัญกรณ์ Big O หรือ Theta) ของอัลกอริทึม?


11

ฉันเคยค้นหาสัญกรณ์ Landau (Big O, Theta ... ) ของอัลกอริทึมของฉันด้วยมือเพื่อให้แน่ใจว่าพวกเขาได้รับการปรับให้เหมาะสมที่สุดเท่าที่จะเป็นไปได้ แต่เมื่อฟังก์ชั่นมีขนาดใหญ่และซับซ้อนจริงๆ เวลามากเกินไปที่จะทำด้วยมือ นอกจากนี้ยังมีแนวโน้มที่จะเกิดข้อผิดพลาดของมนุษย์

ฉันใช้เวลากับ Codility (แบบฝึกหัดการเข้ารหัส / อัลโก) และสังเกตว่าพวกเขาจะให้สัญกรณ์ Landau สำหรับการแก้ปัญหาที่คุณส่ง (ทั้งในเวลาและการใช้หน่วยความจำ)

ฉันสงสัยว่าพวกเขาทำได้อย่างไร ... คุณจะทำอย่างไร

มีวิธีอื่นนอกเหนือจากการวิเคราะห์คำศัพท์หรือการแยกรหัส?

คำถามนี้เกี่ยวกับ PHP และหรือ JavaScript เป็นหลัก แต่ฉันเปิดรับทุกภาษาและทุกทฤษฎี


4
ตรวจสอบคำตอบนี้จาก SO ดูเหมือนสิ่งที่คุณกำลังมองหา
Deco

2
หากคุณสามารถสร้างโปรแกรมที่แก้ปัญหานี้สำหรับอัลกอริทึมแต่ละตัวคุณจะมีชื่อเสียงในฐานะ "คนที่พิสูจน์ทัวริง"
281377

1
สำหรับการพิสูจน์ว่าการตัดสินใจเวลาทำงานโดยทั่วไปนั้นเป็นไปไม่ได้ดูที่นี่และที่นี่ - คำตอบที่พิสูจน์ได้มากกว่าที่คุณขอจริงๆ
Alex สิบ Brink

คำตอบ:


13

ฉันสงสัยว่าพวกเขาทำได้อย่างไร ... คุณจะทำอย่างไร

ฉันคิดว่าพวกเขากำลังประเมินมาตรการ Big O จริง ๆ... โดยการเรียกใช้โปรแกรมสำหรับขนาดปัญหาที่แตกต่างกันการวัดเวลาและการใช้พื้นที่และเส้นโค้งที่เหมาะสมกับผลลัพธ์

ปัญหาของวิธีนี้คือมันสามารถผิดได้ถ้าฟังก์ชั่นต้นทุนเปลี่ยนรูปร่างเมื่อ N มีขนาดใหญ่ 1000 N + N^1.5เช่น

มีวิธีอื่นนอกเหนือจากการวิเคราะห์คำศัพท์หรือการแยกรหัส?

การวิเคราะห์คำศัพท์และการแยกวิเคราะห์ไม่เพียงพอ คุณต้องให้เหตุผลเกี่ยวกับพฤติกรรมของอัลกอริทึมด้วย และการทำเช่นนั้นโดยอัตโนมัติสำหรับอัลกอริทึมที่ไม่รู้จักก่อนหน้านี้จะยาก


6
"การทำเช่นนั้นโดยอัตโนมัติสำหรับอัลกอริทึมที่ไม่รู้จักก่อนหน้านี้จะยาก" - แม่นยำยิ่งขึ้น: มันเทียบเท่ากับการแก้ปัญหาการหยุดชะงัก
Jörg W Mittag

เอ่อ ... ไม่แน่นอน การแก้ปัญหาการหยุดชะงักจะเทียบเท่ากับการสามารถทำได้สำหรับอัลกอริทึมที่ไม่รู้จักก่อนหน้านี้ทั้งหมด
สตีเฟ่นซี

2
ใช่ขอโทษ. การทำสำหรับอัลกอริธึมหนึ่งนั้นเทียบเท่ากับ (หรือมากกว่าหมายถึง) การพิสูจน์การเลิกจ้าง
Jörg W Mittag

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

3

พวกเขาไม่สามารถวิเคราะห์รหัสได้

ตัวอย่างด้านล่างที่มีความซับซ้อนของ "เงินเฟ้อ / เงินฝืด" เทียมที่พิสูจน์แล้วว่าการวัดรันไทม์ของโปรแกรมนั้นไม่เพียงพอที่จะประเมิน Big-O ที่เชื่อถือได้

void lets_trick_runtime(int n) {
   if (n == 10 || n == 25 || n == 118) {
      // unfair speed-up
      do_precalculated_solution_in_constant_time(n);
      return;
   }
   if (n == 11 || n == 26 || n == 119) {
      // unfair slow-down
      do_some_fake_processing_in_n_cube_time(n);
      return;
   }
   // fair solution
   do_general_solution_in_quadratic_time(n);
}

การประเมินแบบรันไทม์สำหรับด้านบนนั้นเป็นที่ยอมรับได้ที่จะให้การประมาณแบบปลอม - เวลาคงที่สำหรับค่าnที่มีวิธีแก้ปัญหาที่คำนวณล่วงหน้าและลูกบาศก์เวลาสำหรับค่าที่unfair slow-downเตะเข้า - แทนเวลากำลังสอง "ยุติธรรม"


อย่างไรก็ตามหากพวกเขาเกิดขึ้นเพื่อตรวจสอบกรณี "ไม่ยุติธรรม" พวกเขายังสามารถสันนิษฐานได้ว่ากรณีที่เลวร้ายที่สุดประเมินความซับซ้อนของ Big-O อย่างแน่นอน
Yam Marcovic

1

ฉันคิดว่ามันเป็นไปไม่ได้

หากคุณรันการทดสอบบางอย่างด้วยจำนวนอินพุตที่แตกต่างกันจำนวนคงที่คุณสามารถคำนวณพหุนามได้ง่ายซึ่งจะประมาณค่ารันตีที่คุณวัดได้ดีมาก ดังนั้นคุณจะจบลงด้วยพหุนามสำหรับทุกโปรแกรมที่เป็นไปได้ซึ่งจะหมายถึงP = NP(ใช่!)

halting problemถ้าคุณพยายามที่จะทำกับการจัดการสัญลักษณ์คุณจะจบลงที่ เนื่องจากคุณไม่สามารถตัดสินใจได้ว่าโปรแกรมของคุณจะหยุดทำงานเมื่อใดคุณจึงไม่สามารถตัดสินใจได้ว่าจะมีความซับซ้อนของรันไทม์อะไร

อย่างไรก็ตามอาจมีกรณีพิเศษมากซึ่งเป็นวิธีที่เป็นไปได้ในภายหลัง แต่กรณีเหล่านี้อาจมีขนาดเล็กซึ่งน่าสงสัยหากได้รับความพยายาม


1
+1 แม้ว่าฉันคิดว่าปัญหาการหยุดชะงักอาจถือได้ว่าเป็นสิ่งที่หายาก
Yam Marcovic

0

ฉันจะทำอย่างไร วิธีที่ผมแก้เกือบปัญหาใด ๆ ฉันไม่ต้องการที่จะนั่งลงและแก้ปัญหา ฉันจำลอง

สำหรับปัญหาหลายอย่างมันอาจจะเพียงพอที่จะเรียกใช้อัลกอริทึมของคุณหลาย ๆ ครั้งโดยใช้ขนาดที่หลากหลายและจากนั้นปรับเส้นโค้งการถดถอยให้สอดคล้องกับผลลัพธ์เหล่านั้น นั่นจะระบุค่าใช้จ่ายค่าใช้จ่าย "คงที่" โดยเฉพาะอย่างยิ่งสำหรับอัลกอริทึมของคุณ (การสกัดกั้นของเส้นโค้ง) และปรับขนาดเมื่อขนาดของปัญหาเพิ่มขึ้น

การซ่อมแซมจะต้องใช้วิธีแก้ปัญหาที่ซับซ้อนเป็นพิเศษ แต่โดยเฉพาะอย่างยิ่งหากคุณเพียงแค่มองหาการประเมินแบบ ball-park คุณควรจะได้รับแบบนั้นและดูว่าการประมาณการของคุณแตกต่างจากผลลัพธ์จริงหรือไม่ การประมาณที่ยอมรับได้

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


0

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

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