โครงสร้างข้อมูลสำหรับการแยกชุด?


21

มีโครงสร้างข้อมูลใดบ้างที่รักษาชุดของชุด (ของชุดดิน จำกัด ) สนับสนุนการดำเนินการดังต่อไปนี้หรือไม่? เวลาในการทำงานช่วงล่างใด ๆ จะได้รับการชื่นชม?

  1. เริ่มต้นชุดที่ว่างเปล่า
  2. เพิ่มองค์ประกอบให้กับชุด
  3. ให้สองชุดรายงานว่าพวกเขาตัดกัน

1
นี่เป็นคำถามทั่วไปเพราะโครงสร้างข้อมูลใด ๆ ที่สามารถรองรับการดำเนินการเหล่านั้นด้วยโดเมนที่ จำกัด คุณจะเจาะจงเจาะจงมากกว่านี้หน่อยได้ไหม? เช่น. คุณต้องการความซับซ้อนอะไรคุณต้องเสียสละอะไรบ้างเพื่อเตรียมปฏิบัติการเป็นต้น
Bartosz Przybylski

คำตอบ:


13

หากแต่ละชุดรักษาระเบียนของชุดอื่น ๆ ที่มีอยู่และคุณมีจำนวนชุดคุณสามารถเปลี่ยนโครงสร้างข้อมูลใด ๆ สำหรับคอลเลกชัน ( เช่นแผนภูมิการค้นหาแบบไบนารี่ฯลฯ ) เป็นชุดที่คุณสามารถเรียกคืนได้ องค์ประกอบของจุดตัดของสองชุดในเวลาs)s>0O(logs)

  • แต่ละชุดควรมีตัวระบุที่ไม่ซ้ำกันจากชุดที่สั่งทั้งหมดบางชุด หากคุณตั้งชื่อชุดของคุณอย่างชัดเจนตัวระบุอาจเป็นดัชนีได้S1,S2,

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

  • แต่ละชุดยังรักษา "ดัชนี" ของแต่ละชุดอื่น ๆ - ไม่ใช่สำเนาของพวกเขา แต่ค่อนข้างโครงสร้างข้อมูลที่จัดทำดัชนีโดยป้ายชื่อของชุดอื่น ๆ ดัชนีนี้จะถูกใช้ในการรักษาสำหรับแต่ละชุดต้นไม้ค้นหาแบบทวิภาคของทุกองค์ประกอบของS_k (ทั้งสองชุดและแบ่งปันแผนภูมิการค้นหาหนึ่งสำเนา)S k S jS k S j S kSjSkSjSkSjSk

การเริ่มต้น

การเริ่มต้นของชุดประกอบด้วยการดำเนินงานเพื่อเริ่มต้นต้นไม้ขององค์ประกอบการดำเนินงานในขณะที่คุณเริ่มต้น (คัดลอกจากรีจิสทรี) ดัชนีสำหรับชุดและการดำเนินงานในขณะที่คุณสำรวจรีจิสทรีเพื่อเพิ่มลงในดัชนีของแต่ละชุดอื่น ๆS_jในดัชนีของเราจะสร้างค้นหาซึ่งเป็นตัวแทนของสำหรับชุดอื่น ; เราคัดลอกตัวชี้เหมือนกันสำหรับดัชนีของS_jO ( 1 ) O ( s ) T O ( s บันทึกs ) T S j T T S j = S j S jT=O(1)O(s)TO(slogs)TSjTTSj=SjSj

การเพิ่มองค์ประกอบให้กับชุดT

การเพิ่มให้กับชุดต้องใช้เวลาตามปกติโดยที่. นอกจากนี้เรายังทดสอบการเป็นสมาชิกของในแต่ละชุดอื่น ๆซึ่งต้องใช้เวลาที่คือขนาดของจักรวาล (หรือชุดที่ใหญ่ที่สุด ) และคือจำนวนชุดในรีจิสทรี สำหรับแต่ละชุดเช่นว่ายังแทรกลงในดัชนีสำหรับชุดT สำหรับแต่ละชุดดังกล่าวT O ( บันทึกn T ) n T = | T | x S 1 , S 2 , O ( บันทึกn S 1 + บันทึกn S 2 + ) O ( s บันทึกn ) , n = | V | S j s S j x S jxVTO(เข้าสู่ระบบnT)nT=|T|xS1,S2,...

O(เข้าสู่ระบบnS1+เข้าสู่ระบบnS2+)O(sเข้าสู่ระบบn),
n=|V|SJsSJxSJS เจT S J O ( บันทึกs + บันทึกn T ) S T x S เจT S 1 , S 2 , ... O ( s ล็อกs + s บันทึกn T ) S V s « n O ( s log n )xSJTSJสิ่งนี้ใช้เวลาเพื่อค้นหา ในดัชนีของและแทรกใน ; ทั่วทุกชุดนี้ต้องใช้เวลาn_T) ถ้าเราคิดว่าจำนวนของชุดมีมากน้อยกว่าขนาดของจักรวาล (นั่นคือถ้าเราคิดว่า ) เวลารวมสำหรับการแทรกองค์ประกอบแล้วn)O(เข้าสู่ระบบs+เข้าสู่ระบบnT)SJTxSJTS1,S2,...O(sเข้าสู่ระบบs+sเข้าสู่ระบบnT)SJVs«nO(sเข้าสู่ระบบn)

หากคุณไม่อนุญาตให้ซ้ำกันในชุดเราสามารถประหยัดเวลาในกรณีที่แล้วโดยละทิ้งการทดสอบการเป็นสมาชิกและการแทรกสำหรับชุดอื่น ๆT"แทรก" ในกรณีที่มีอยู่แล้วจากนั้นใช้เวลาเพียงn_T)T x O ( log n T )xSTxO(เข้าสู่ระบบnT)

การทดสอบทางแยก

ดัชนีของแต่ละชุดได้รับการดูแลรักษาอย่างแม่นยำเพื่อให้สามารถประเมินได้อย่างรวดเร็วว่ามีสองชุดและตัดกันหรือไม่ สำหรับชุดเพียงแค่ตรวจสอบดัชนีของชุดเราไม่สามารถตัดสินได้เฉพาะในเวลาไม่ว่าตัดกันแต่เราสามารถดึงต้นไม้ไบนารีที่มีทั้งชุดS_kS k S j S k O ( บันทึกs ) S j S k S jS kSJSkSJSkO(เข้าสู่ระบบs)SJSkSJSk

การกำจัดองค์ประกอบ

ในการลบองค์ประกอบออกจากชุดเราไม่เพียง แต่ลบออกจากการค้นหาสำหรับตัวแต่จากจุดตัดแต่ละสำหรับชุดในดัชนี สิ่งนี้ต้องใช้เวลาโดยที่.T T S jT S j O ( s บันทึกn T ) n T = | T |xTTSJTSJO(sเข้าสู่ระบบnT)nT=|T|

ตั้งค่าการลบ

เนื่องจากค่าใช้จ่ายในการค้นหารีจิสทรีหากคุณมีหลายชุดคุณอาจต้องการลบชุดเมื่อไม่จำเป็นต้องใช้อีกต่อไป โดยการข้ามรีจิสทรีทั้งหมดเราอาจลบออกจากดัชนีของชุดอื่น ๆ ทั้งหมดในเวลาซึ่งมีค่าใช้จ่ายในการลบการค้นหาที่เป็นตัวแทนของสำหรับชุดอื่น ๆ แต่ละโดยที่.S j O ( s n T ) S jT S j n T = | T |SSJO(snT)SJTSJnT=|T|

หมายเหตุ

หากคุณคาดว่าจะใช้จำนวนชุดคงที่เท่านั้นดังนั้นเวลาทำงานข้างต้นจะลดลงเป็น:

  • การเริ่มต้น:O(1)

  • การแทรกองค์ประกอบ:O(เข้าสู่ระบบn)

  • การทดสอบทางแยก (และการดึงของทางแยก):O(1)

  • การลบองค์ประกอบ:O(เข้าสู่ระบบnT)

  • การลบการตั้งค่า:O(nS)

โดยที่คือขนาดของชุดที่ใหญ่ที่สุดในรีจิสตรีและn T = | T | สำหรับชุดTที่คุณใช้งานnnT=|T|T

หากคุณคาดว่าจะมีการตั้งค่าโดยที่Vคือจักรวาลของคุณคุณอาจต้องการโครงสร้างข้อมูลที่แตกต่างกันหากคุณต้องการให้การดำเนินการเหล่านี้ทำงานในเวลาเชิงเส้นย่อย อย่างไรก็ตามหากคุณมีคู่ของชุดที่มีจุดตัดคุณรู้ว่าคุณจะไม่ทดสอบคุณอาจลดขนาดของดัชนีสำหรับชุด (โดยไม่รวมชุดที่คุณจะทดสอบ) หรือใช้มากกว่าหนึ่งรีจิสทรี ( หนึ่งชุดสำหรับชุดแต่ละชุดที่มีสี่แยกที่คุณอาจทดสอบ) ในความเป็นจริงแล้วรีจิสทรีจะมีประโยชน์ก็ต่อเมื่อคุณต้องการควบคุมจากส่วนกลางเพื่อให้แน่ใจว่าแต่ละชุดมีการบันทึกของกันและกันในดัชนี: มันอาจเป็นประโยชน์ในบางกรณีเมื่อเริ่มต้นชุดSเพียงบันทึกO(|V|)VSเฉพาะกิจแต่ละชุดใหม่เข้าไปในดัชนีของชุดอื่นซึ่งมีจุดตัดกับS ที่คุณสนใจTS


6

มีโครงสร้างข้อมูลที่อนุญาตให้คุณทำสิ่งนี้ในเวลาที่น้อยกว่าเชิงเส้นแม้แต่ในกรณีที่เลวร้ายที่สุด ดูhttp://research.microsoft.com/pubs/173795/vldb11intersection.pdf (และเอกสารอ้างอิงในนั้น)

หากทั้งสองชุด S และ T ของคุณมีจุดตัดขนาดใหญ่และคุณมีพจนานุกรมสำหรับ S การค้นหาองค์ประกอบของ T ตามลำดับแบบสุ่มควรให้องค์ประกอบทั่วไปอย่างรวดเร็ว กรณีที่ยากที่สุดคือเมื่อขนาดทางแยกเป็น 0 หรือ 1


3

โดยปกติภาษาการเขียนโปรแกรมที่คุณเลือกจะสนับสนุนโครงสร้างข้อมูลที่มีองค์ประกอบที่ไม่ซ้ำกัน โดยทั่วไปมีสามวิธีที่ได้รับความนิยม: ต้นไม้แฮชและบิตมาสก์ องค์ประกอบแบบต้นไม้จะต้องเปรียบเทียบกันได้องค์ประกอบแบบแฮชจะต้องเป็นแบบแฮชและองค์ประกอบแบบ Bitmask จะต้องมีวิธีการแปลงเป็นจำนวนเต็ม

ชุดต้นไม้จะรองรับการแทรกใน O (log n) และการทดสอบจุดตัดในกรณีที่แย่ที่สุด O (n log n)

ชุดแฮชจะรองรับการแทรกใน Amortized O (1 * h) โดยที่ 'h' เป็นเวลาทำงานของอัลกอริทึมการแปลงแป้นพิมพ์และการทดสอบการแยกในกรณีที่เลวร้ายที่สุด O (n)

โดยทั่วไปแล้วชุด Bitmask ไม่ได้ใช้เหมือนชุดต้นไม้และชุดแฮช


2
นี่จะเป็นคำตอบที่ดีสำหรับStack Overflowแต่ที่นี่เราต้องการรายละเอียดเกี่ยวกับวิธีการและสาเหตุของการทำงาน
กราฟิลส์

3

หากกรณีของคุณอนุญาตคำตอบที่เป็นเท็จฉันจะใช้Bloom Filterพร้อมฟังก์ชันแฮชเดียว

คุณสามารถใช้มันได้ดังต่อไปนี้:

เริ่มต้นชุดที่ว่างเปล่า

  • = อาร์เรย์บิตของ nบิตทั้งหมดตั้งค่าเป็น 0 ( nควรเลือกตามจำนวนองค์ประกอบที่เป็นไปได้)Bnn

เพิ่มองค์ประกอบให้กับชุด

  • B[ชั่วโมงasชั่วโมง(อีล.อีม.อีnเสื้อ)]=1

รับสองชุด (B1, B2) ให้รายงานว่าพวกเขาตัดกันหรือไม่

  • ตรวจสอบว่าA N D B 2 = 0B1 Aยังไม่มีข้อความD B2 = 0

ความซับซ้อน

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