ทำไมเป้มีปัญหา pseudo-polynomial?


89

ฉันรู้ว่าKnapsackNP สมบูรณ์ในขณะที่ DP สามารถแก้ไขได้ พวกเขากล่าวว่าโซลูชัน DP คือpseudo-polynomialเนื่องจากเป็นเลขชี้กำลังใน "ความยาวของอินพุต" (เช่นจำนวนบิตที่ต้องใช้ในการเข้ารหัสอินพุต) น่าเสียดายที่ฉันไม่ได้รับมัน ใครช่วยอธิบายpseudo-polynomialเรื่องนั้นให้ฉันฟังช้าๆ


คำตอบ:


92

เวลาในการทำงานคือ O (NW) สำหรับปัญหากระเป๋าเป้ที่ไม่มีการผูกมัดกับรายการ N และกระเป๋าเป้ขนาด W W ไม่ใช่พหุนามในความยาวของอินพุตซึ่งเป็นสิ่งที่ทำให้เป็นโพลิโนเมียลหลอก

พิจารณา W = 1,000,000,000,000 ใช้เวลาเพียง 40 บิตในการแสดงจำนวนนี้ดังนั้นขนาดอินพุต = 40 แต่รันไทม์การคำนวณใช้ตัวประกอบ 1,000,000,000,000 ซึ่งเป็น O (2 40 )

ดังนั้นรันไทม์จึงถูกกล่าวอย่างถูกต้องมากขึ้นว่าเป็น O (N.2 บิตใน W ) ซึ่งเป็นเลขชี้กำลัง

ดูเพิ่มเติมที่:


1
ลิงก์ # 3 ที่อ้างถึง "ความซับซ้อนของการเขียนโปรแกรมแบบไดนามิกสำหรับปัญหากระเป๋าเป้ 0-1" ตายแล้ว
dev_nut

1
ขออภัยฉันไม่เข้าใจ สมมติว่าถ้าเรามีอัลกอริทึมที่มีความซับซ้อนของเวลา O (N) เราก็มี O (2 ^ (บิตใน N)) ซึ่งเป็นเลขชี้กำลัง? ขอบคุณ ~
Lusha Li

3
@LushaLi นี้ช่วยให้ฉัน: youtube.com/watch?v=9oI7fg-MIpE ถ้า N เป็นอาร์เรย์ที่แต่ละองค์ประกอบมีอินพุตขนาดสูงสุดคงที่ (กล่าวว่าแต่ละองค์ประกอบในอาร์เรย์มีขนาดไม่เกิน 32 บิต) และคุณรันสำหรับลูปบนอาร์เรย์นี้หนึ่งครั้งก็จะเป็นอัลกอริทึมเวลาพหุนามในอินพุต ขนาด N ของอาร์เรย์ อย่างไรก็ตามหาก N เป็นจำนวนเต็มและคุณรันการวนซ้ำบน N ดังนั้น N จะไม่ถูกผูกไว้และเพิ่มขึ้นแบบทวีคูณในจำนวนบิตที่ใช้แทนค่านี้ วิธีง่าย ๆ สำหรับการวนซ้ำบน N คือเลขชี้กำลัง โปรดทราบว่าในกรณีของอาร์เรย์ขนาดของแต่ละองค์ประกอบในอาร์เรย์จะมีขอบเขตบน
max_max_mir

ฉันไม่มั่นใจ มีอัลกอริทึมจำนวนมากที่มีคุณสมบัติเดียวกันซึ่งไม่ใช่ "พหุนามหลอก" พูดว่าอะไรคือความซับซ้อนของ Sieve of Eratosthenes (หรือเครื่องมือค้นหาจำนวนเฉพาะอื่น ๆ )?
Ofir A.

31

ในปัญหาส่วนใหญ่ของเราเรากำลังจัดการกับรายการตัวเลขจำนวนมากซึ่งพอดีกับประเภทข้อมูล int / float มาตรฐาน เนื่องจากวิธีการที่โปรเซสเซอร์ส่วนใหญ่สร้างขึ้นเพื่อจัดการกับตัวเลข 4-8 ไบต์ในแต่ละครั้งโดยไม่มีค่าใช้จ่ายเพิ่มเติม (เทียบกับตัวเลขที่พอดีเช่น 1 ไบต์) เราจึงแทบไม่พบการเปลี่ยนแปลงเวลาในการทำงานจากการปรับขนาดตัวเลขของเราขึ้นหรือ ลงไปภายในช่วงที่เราพบในปัญหาจริง - ดังนั้นปัจจัยที่โดดเด่นจึงยังคงเป็นเพียงปริมาณจุดข้อมูลที่แท้จริงปัจจัย n หรือ m ที่เราคุ้นเคย

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

แต่ลองทำงานซ้ำกับอัลกอริทึมอื่น ๆ เพื่อดำเนินการกับชุดข้อมูลที่เกี่ยวข้องกับ ints ขนาดใหญ่ซึ่งเป็นตัวเลขที่ต้องใช้มากกว่า 8 ไบต์ในการแสดงและดูว่าจะทำอย่างไรกับรันไทม์ ขนาดของตัวเลขที่เกี่ยวข้องจะสร้างความแตกต่างได้เสมอแม้ในอัลกอริทึมอื่น ๆ เช่นการเรียงลำดับไบนารีเมื่อคุณขยายเกินบัฟเฟอร์ของโปรเซสเซอร์ทั่วไปด้านความปลอดภัยจะทำให้เรา "ฟรี" ด้วยการจัดการแบทช์ 4-8 ไบต์

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


8

รันไทม์ของอัลกอริทึมของเป้สะพายหลังไม่เพียง แต่ผูกไว้กับขนาดของอินพุต (n - จำนวนรายการ) แต่ยังรวมถึงขนาดของอินพุตด้วย (W - ความจุของเป้สะพายหลัง) O (nW) ซึ่งเป็นเลขชี้กำลังในลักษณะที่เป็น เป็นตัวแทนในการใช้คอมพิวเตอร์ในไบนารี (2 ^ n) ได้โดยเริ่มต้นในการคำนวณความซับซ้อน (เช่นวิธีการทำภายในเครื่องคอมพิวเตอร์ผ่านบิต) เป็นห่วงเพียง แต่มีขนาดของปัจจัยการผลิตที่ไม่ได้เป็นของเคาะ / ค่า

ไม่สนใจรายการค่า / น้ำหนักสักครู่ สมมติว่าเรามีอินสแตนซ์ที่มีความจุเป้ 2 W จะใช้เวลาสองบิตในข้อมูลอินพุต ตอนนี้เราจะเพิ่มความจุเป้เป็น 4 โดยคงส่วนที่เหลือไว้ ข้อมูลของเราเพิ่มขึ้นเพียงหนึ่งบิต แต่ความซับซ้อนในการคำนวณเพิ่มขึ้นสองเท่า ถ้าเราเพิ่มความจุเป็น 1024 เราจะมีอินพุตเพียง 10 บิตสำหรับ W แทนที่จะเป็น 2 แต่ความซับซ้อนเพิ่มขึ้นเป็น 512 ความซับซ้อนของเวลาเพิ่มขึ้นแบบทวีคูณในขนาดของ W ในการแทนเลขฐานสอง (หรือทศนิยม) .

อีกตัวอย่างง่ายๆที่ช่วยให้ฉันเข้าใจแนวคิดพหุนามหลอกคืออัลกอริธึมการทดสอบความเป็นจริงแบบไร้เดียงสา สำหรับจำนวนที่กำหนด n เรากำลังตรวจสอบว่ามันหารด้วยจำนวนเต็มเท่า ๆ กันหรือไม่ในช่วง2..√nดังนั้นอัลกอริทึมจึงใช้ขั้นตอน√ (n − 1) แต่ที่นี่ n คือขนาดของอินพุตไม่ใช่ขนาด

                     Now The regular O(n) case

ในทางตรงกันข้ามการค้นหาอาร์เรย์สำหรับองค์ประกอบที่กำหนดจะทำงานในเวลาพหุนาม: O (n) ใช้เวลามากที่สุด n ขั้นตอนและนี่คือขนาดของอินพุต (ความยาวของอาร์เรย์)

[ดูที่นี่]

การคำนวณบิตที่จำเป็นในการจัดเก็บเลขฐานสิบ


3
ดังนั้นสำหรับตัวอย่างการค้นหาล่าสุดของคุณทำไมไม่พิจารณา n เป็นไบนารีด้วยล่ะ? ถ้า n = 1024 ก็ใช้เวลาเพียง 10 บิตดังนั้นจึงไม่ควรเป็นพหุนามหลอก?
user1024

7

วิธีที่ฉันเข้าใจก็คือความจุจะเป็น O (W) ถ้าอินพุตความจุเป็นอาร์เรย์ [1,2, ... , W]ซึ่งมีขนาด W แต่อินพุตความจุไม่ใช่ อาร์เรย์ของตัวเลขแทนที่จะเป็นจำนวนเต็มเดียว ความซับซ้อนของเวลาเป็นเรื่องเกี่ยวกับความสัมพันธ์กับขนาดของอินพุต ขนาดของจำนวนเต็มไม่ได้ค่าของจำนวนเต็ม แต่จำนวนบิตที่เป็นตัวแทนของมัน ในภายหลังเราจะแปลงจำนวนเต็ม W เป็นอาร์เรย์ [1,2, ... , W] ในอัลกอริทึมทำให้ผู้คนเข้าใจผิดคิดว่า W คือขนาด แต่อาร์เรย์นี้ไม่ใช่อินพุต แต่จำนวนเต็มนั้นเอง

ให้คิดว่าอินพุตเป็น "อาร์เรย์ของสิ่งของ" และมีขนาดเท่ากับ "จำนวนสิ่งของในอาร์เรย์" อินพุตรายการเป็นอาร์เรย์ของ n รายการในอาร์เรย์ดังนั้น size = n อินพุตความจุไม่ใช่อาร์เรย์ของตัวเลข Wในนั้นแต่เป็นจำนวนเต็มเดียวซึ่งแสดงโดยอาร์เรย์ของล็อก (W) บิต เพิ่มขนาดของมันขึ้น 1 (เพิ่ม 1 บิตที่มีความหมาย), W เพิ่มเป็นสองเท่าดังนั้นเวลารันจึงเพิ่มเป็นสองเท่าดังนั้นความซับซ้อนของเวลาเลขชี้กำลัง

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