อัลกอริทึมการค้นหาชุดย่อย


9

สมมติว่าฉันมีรายการ X จากชุดย่อยของ {1,...,n}. ฉันสามารถทำการประมวลผลล่วงหน้าในรายการนี้หากจำเป็น หลังจากการประมวลผลล่วงหน้านี้ฉันจะได้รับชุดใหม่A{1,...,n}. ฉันต้องการระบุชุดใด ๆBX กับ BA.

อัลกอริทึมที่เห็นได้ชัด (ไม่มีการประมวลผลล่วงหน้า) ต้องใช้เวลา O(n|X|) - คุณเพียงแค่ทดสอบ A ต่อแต่ละ BXแยกต่างหาก มีอะไรดีไปกว่านี้อีกไหม?

ถ้ามันช่วยคุณได้ Aจำนวนการแข่งขันทั้งหมด BX ถูกล้อมรอบด้วยบางสิ่งบางอย่างเช่น O(1).

คำตอบ:


3

นี่ไม่ใช่คำตอบ เป็นการสังเกตที่ง่าย แต่ยาว ฉันหวังว่ามันจะมีประโยชน์

เวอร์ชันการตัดสินใจของปัญหาของคุณคือ: X มีชุดย่อยของ A?

ปัญหานี้เกี่ยวข้องกับปัญหาการประเมินฟังก์ชั่นบูลีนโมโนโทนของ nตัวแปร เซตย่อยของ{1,,n} เทียบเท่ากับ n- สตริงดังนั้นครอบครัว X เทียบเท่ากับฟังก์ชันบูลีน f ของ nตัวแปร รับฟังก์ชั่นfหนึ่งสามารถกำหนดฟังก์ชั่นโมโนโทนน้อยที่สุดที่ไม่ใหญ่กว่า fคือ g(y)=(xy,f(x)). จากนั้นปัญหาต้นฉบับจะถูกลดลงเป็นการประเมินg(A). ในทางกลับกันปัญหาของการประเมินฟังก์ชั่นโมโนโทนบูลสามารถลดลงเป็นปัญหาดั้งเดิมได้f=g หรือโดยการเลือก f ที่ทำให้ X ที่มีขนาดเล็ก

ในทางปฏิบัติ BDDs มักจะทำงานได้ดี ดังนั้นวิธีหนึ่งที่เป็นไปได้คือสร้าง BDD สำหรับfได้มาจากมัน BDD สำหรับ gแล้วประเมินผล g. ขนาดเฉลี่ยของ BDD สำหรับgต้องเพราะมีหลายเสียงเดียวฟังก์ชั่นบูล ดังนั้นในทางทฤษฎีนี่เป็นทางออกที่ไม่ดีΩ((nn/2))

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

เพื่อความสมบูรณ์อัลกอริธึมที่ง่ายสำหรับการคำนวณ BDD สำหรับจาก BDD สำหรับมีดังต่อไปนี้ นี่เป็นมาตรฐานหรือการทำงานของ BDDsgf

m(x?f1:f0)=x?(m(f0)m(f1)):m(f0)

2
นี่ไม่ใช่สิ่งที่เทียบเท่าหรือไม่มากไปกว่าการคำนวณคำตอบสำหรับแต่ละชุดย่อยของ , แคชผลลัพธ์ทั้งหมดในต้นไม้ไบนารีที่มีขนาดแล้วมองไปทางขวา ส่งผลให้ (ในเวลา ) เมื่อคุณได้รับ? {1,2,...,n}2nO(n)A
mjqxxxx

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

mjqxxxx และ Tsuyoshi: ฉันเห็นด้วยกับคุณทั้งคู่ ฉันเขียนข้อความใหม่เพื่อที่ฉันหวังว่ามันจะชัดเจนยิ่งขึ้นว่าฉันเห็นด้วย :)
Radu GRIGore

3

บางทีคุณสามารถใช้เทคนิค "การดึงข้อมูล": ในช่วงการประมวลผลล่วงหน้าสร้างดัชนีกลับหัว (ในกรณีของคุณง่าย ๆอาร์เรย์สองมิติก็เพียงพอแล้ว) ที่แมปองค์ประกอบให้กับชุดในที่มี:\}n×|X|xi{1,...,n}Xinv(xi)={XjX|xiXj}

ตั้งค่าเป็นจำนวนเต็มอาร์เรย์ของความยาว.occ|X|

แล้วสำหรับแต่ละดึงและสำหรับแต่ละทำyiAinv(yi)Xjinv(yi)occ[j]=occ[j]+1

ในตอนท้ายชุดที่คุณต้องการเป็นผู้ที่[เจ]|Xj|=occ[j]

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

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