สมมติว่าฉันเป็นโปรแกรมเมอร์และฉันมีปัญหาที่สมบูรณ์แบบที่ฉันต้องแก้ปัญหา มีวิธีการใดบ้างที่สามารถจัดการกับปัญหา NPC มีแบบสำรวจหรืออะไรที่คล้ายกันในหัวข้อนี้?
สมมติว่าฉันเป็นโปรแกรมเมอร์และฉันมีปัญหาที่สมบูรณ์แบบที่ฉันต้องแก้ปัญหา มีวิธีการใดบ้างที่สามารถจัดการกับปัญหา NPC มีแบบสำรวจหรืออะไรที่คล้ายกันในหัวข้อนี้?
คำตอบ:
มีกลยุทธ์ที่ได้รับการศึกษาเป็นอย่างดี สิ่งที่ดีที่สุดในใบสมัครของคุณขึ้นอยู่กับสถานการณ์
ปรับปรุงรันไทม์กรณีที่เลวร้ายที่สุด
ด้วยการใช้ข้อมูลเชิงลึกเฉพาะปัญหาคุณสามารถปรับปรุงอัลกอริทึมที่ไร้เดียงสาได้บ่อยครั้ง ตัวอย่างเช่นมีอัลกอริทึมสำหรับ Vertex Cover ด้วย c < 1.3 [1]; นี้เป็นอย่างมากการปรับปรุงในช่วงที่ไร้เดียงสา Ω ( 2 n )และอาจจะทำให้อินสแตนซ์ขนาดที่เกี่ยวข้องสำหรับคุณเวไนย
ปรับปรุงรันไทม์ที่คาดไว้
การใช้ฮิวริสติกคุณสามารถคิดค้นอัลกอริทึมที่รวดเร็วในหลาย ๆ กรณี หากสิ่งเหล่านั้นรวมถึงสิ่งที่คุณพบเจอในทางปฏิบัติคุณก็เป็นทองคำ ตัวอย่างคือ SAT ซึ่งมีนักแก้ปัญหาที่เกี่ยวข้องค่อนข้างมากและอัลกอริธึม Simplex (ซึ่งแก้ปัญหาพหุนาม แต่ยังคง) หนึ่งในเทคนิคพื้นฐานที่มักจะเป็นประโยชน์คือสาขาและผูกพัน
จำกัด ปัญหา
หากคุณสามารถตั้งสมมติฐานเพิ่มเติมในอินพุตของคุณปัญหาอาจกลายเป็นเรื่องง่าย
ผลลัพธ์ที่อ่อนแอลง
ซึ่งหมายความว่าคุณยอมรับผลลัพธ์ที่ผิดพลาดหรือไม่สมบูรณ์ มีสองรสชาติหลัก:
อ้างถึงอัลกอริทึมสำหรับปัญหาหนักโดยHromkovičสำหรับการรักษาอย่างละเอียด
คำตอบอื่น ๆ ได้กล่าวถึงเรื่องนี้จากมุมมองเชิงทฤษฎีมากขึ้น นี่คือวิธีการที่ใช้งานได้จริงมากขึ้น
สำหรับปัญหาการตัดสินใจที่สมบูรณ์แบบ "ปกติ" ( "มีบางสิ่งที่ตรงกับข้อ จำกัด เหล่านี้หรือไม่" ) นี่คือสิ่งที่ฉันจะลองก่อนเสมอ:
เขียนโปรแกรมง่ายๆที่เข้ารหัสเช่นปัญหาของคุณเป็นเช่น SAT
จากนั้นใช้ตัวแก้ SAT ที่ดีเรียกใช้ (ใช้คอมพิวเตอร์มัลติคอร์ที่เร็วที่สุดที่คุณมี) และดูว่าเกิดอะไรขึ้น
ลองใช้อินสแตนซ์ขนาดเล็กก่อนเพื่อทำความเข้าใจว่าใช้เวลานานแค่ไหน
น่าแปลกที่มักจะวิธีนี้มากดีกว่าการพยายามที่จะใช้แก้ของคุณเองเฉพาะสำหรับปัญหาปัจจุบันของคุณ:
นักแก้ปัญหา SAT นั้นฉลาดและมีประสิทธิภาพดี พวกเขาทำได้ง่ายกว่าการใช้การค้นหาย้อนรอย (ไม่ว่าคุณจะเสียเวลามากแค่ไหนในการปรับแต่งโค้ดของคุณ) พวกเขายังมีประสิทธิภาพสูงกว่าทางเลือกอื่นนอกตัวเองเช่นตัวแก้โปรแกรมเชิงเส้นจำนวนเต็ม
ต้องใช้การเขียนโปรแกรมน้อยมาก ขั้นตอนที่ 1 ค่อนข้างตรงไปตรงมาและไม่ได้เป็นเรื่องสำคัญต่อประสิทธิภาพ คุณสามารถใช้ภาษาสคริปต์เช่น Python มีคนอื่นดูแลการใช้งานทุกอย่างที่คุณต้องการสำหรับขั้นตอนที่ 2 แล้ว
สำหรับปัญหาการเพิ่มประสิทธิภาพ NP-hard ทั่วไป( "ค้นหาสิ่งเล็กที่สุดที่เป็นไปตามข้อ จำกัด เหล่านี้ทั้งหมด" ) วิธีการนี้อาจจะใช้งานได้หรือไม่ก็ได้
หากคุณสามารถทำให้เป็นปัญหาในการตัดสินใจได้อย่างง่ายดาย ( "มีสิ่งที่มีขนาด 4 ที่สอดคล้องกับข้อ จำกัด เหล่านี้ทั้งหมดหรือไม่" , "แล้วขนาด 3 มีขนาดเท่าไร?" ) เยี่ยมมากทำตามแนวทางเดียวกันกับปัญหาการตัดสินใจ
มิฉะนั้นคุณอาจต้องการใช้วิธีแก้ปัญหาฮิวริสติกที่พยายามหาวิธีแก้ปัญหาขนาดเล็ก (ไม่จำเป็นต้องเป็นวิธีแก้ปัญหาที่เล็กที่สุด ) ตัวอย่างเช่น:
วิธีหนึ่งในการโจมตีความสามารถในการบุกรุกคือการคิดถึงปัญหาในบริบทความซับซ้อนที่ซับซ้อน
นี่คือตัวอย่างบางส่วนในคลาสต่างๆของลำดับชั้น W:
นี่เป็นอีกระดับของความซับซ้อนในการจำแนกปัญหา NP อย่างแม่นยำยิ่งขึ้นและหากคุณต้องการมากขึ้นคุณสามารถดูParameterized Circuit Complexity และ W Hierarchyโดย Downey et al (1998)
และถ้าคุณต้องการมากยิ่งขึ้นเป็นสิ่งที่ดีในการอ่าน Flum และ Grohe ของParameterized ซับซ้อนทฤษฎี
และในที่สุดก็:
เป็นที่ทราบกันว่าหากปัญหามี FPTAS (แบบแผนพหุนามแบบเต็มเวลา ) จากนั้นก็เป็น FPT (ซึ่งเห็นได้ชัด) แต่ไม่มีสิ่งใดที่รู้จักกันดีในทิศทางย้อนกลับยังมีงานบางอย่างเกี่ยวกับความสัมพันธ์ของ PTAS และ XP แต่มี ไม่ได้มีความสัมพันธ์ที่แน่นแฟ้นมากระหว่าง PTAS และลำดับชั้น W (อย่างน้อยตอนนี้ฉันไม่ทราบ)
นอกจากนี้ในบางกรณีเราอาจแก้ไขพารามิเตอร์ที่แตกต่างกันเช่น: ความยาวของเส้นทางที่ยาวที่สุดในกราฟถูก จำกัด ขอบเขตและขนาดของการแก้ปัญหาถูก จำกัด ขอบเขต (เช่นในชุดคำติชมจุดยอด), ...
อาจเป็นบางคนเชื่อว่าความซับซ้อนที่ถูกขนานนามนั้นไม่มีประโยชน์ในทางปฏิบัติ แต่นี่เป็นสิ่งที่ผิด อัลกอริทึมแบบ Parametrized จำนวนมากถูกค้นพบในแอปพลิเคชันในโลกแห่งความจริงเมื่อคุณสามารถแก้ไขพารามิเตอร์บางอย่างได้นี่คือตัวอย่าง:
หนึ่งในอัลกอริทึมฮิวริสติกที่รวดเร็วและแม่นยำที่สุดสำหรับ TSP คือ: การรวมการเดินทางและการแยกย่อยสาขาซึ่งใช้การแก้ปัญหาแบบขนาน (ไม่ใช่โดยตรง แต่เป็นการย่อยสลายสาขาและวิธีการเขียนโปรแกรมแบบไดนามิกที่พวกเขาใช้
ความครบถ้วนสมบูรณ์ของ NP นั้นเกี่ยวกับการบุกรุกในกรณีที่เลวร้ายที่สุด ขึ้นอยู่กับปัญหาที่คุณกำลังดำเนินการอินสแตนซ์ของคลาสจำนวนมากอาจถูกแก้ไขในเวลาที่เหมาะสมในทางปฏิบัติ (แม้ว่าคุณอาจต้องใช้อัลกอริทึมพิเศษเพิ่มเติมเพื่อให้ได้ runtimes ดี)
ลองพิจารณาดูว่ามีการลดปัญหาของคุณอย่างมีประสิทธิภาพไปเป็นปัญหาด้วยตัวแก้ปัญหาที่ดีหรือไม่เช่น Boolean Satisfiability หรือ Integer Linear Programming
ใช้อัลกอริทึมที่ยอมรับได้เพื่อแก้ปัญหาของคุณในเวลาแบบเอ็กซ์โพเนนเชียล ระหว่างอัลกอริธึมแบบเอ็กซ์โปเนนเชียลเวลาในการทำงานบางอย่างสามารถยอมรับได้เมื่อขนาดอินพุตของปัญหาของคุณน้อยกว่าค่าที่ระบุ
แม้ว่าจะสัมผัสกับคำตอบบางข้อสั้น ๆ แต่ขอให้ฉันเน้นว่าในทางปฏิบัติปัญหาที่เกิดจากปัญหาสมบูรณ์ได้รับการแก้ไข (หรือโดยประมาณ) ตลอดเวลา เหตุผลหลักที่คุณสามารถแก้ปัญหา NP-complete ในทางปฏิบัติคือ:
อินสแตนซ์ที่พบในการปฏิบัติไม่ใช่ "กรณีที่เลวร้ายที่สุด"
เหตุผลอื่นสำหรับความคลาดเคลื่อนคือ:
เป็นการยากที่จะวิเคราะห์อัลกอริทึมฮิวริสติกอย่างเป็นทางการ
ในทางปฏิบัติคุณใช้อัลกอริทึมแบบฮิวริสติกเพื่อแก้ปัญหา NP-complete ของคุณและหวังให้ดีที่สุด ผลลัพธ์มักจะสวยงาม
ปัญหาอื่นที่สัมผัสกับคำตอบอื่น ๆ คือ:
บางครั้งอัลกอริธึมเอ็กซ์โปเนนเชียลนั้นเร็วพอ
แน่นอนว่าขึ้นอยู่กับปัญหา เมื่อข้อมูลขนาดใหญ่มีส่วนเกี่ยวข้องเรามีค่าสูงสุดตรงข้าม:
บางครั้งอัลกอริธึมที่เป็นไปได้เพียงอย่างเดียวคือ quasilinear
ฉันกลัวว่าฝูงชนที่นี่ค่อนข้างมีแนวโน้มทางทฤษฎี คุณอาจได้รับคำตอบที่ดีกว่าในไซต์ stackexchange หลัก