การคำนวณความแตกต่างระหว่างชุดใหญ่สองชุด


14

ฉันมีจำนวนเต็มและB จำนวนมาก แต่ละชุดมีประมาณหนึ่งล้านรายการและแต่ละรายการเป็นจำนวนเต็มบวกที่มีความยาวสูงสุด 10 หลัก AB

อัลกอริทึมที่ดีที่สุดในการคำนวณและB Aคืออะไร กล่าวอีกนัยหนึ่งฉันจะคำนวณรายการของAที่ไม่มีในBและในทางกลับกันได้อย่างมีประสิทธิภาพได้อย่างไร อะไรคือโครงสร้างข้อมูลที่ดีที่สุดในการเป็นตัวแทนของสองชุดนี้เพื่อให้การดำเนินการเหล่านี้มีประสิทธิภาพABBAAB

วิธีที่ดีที่สุดที่ฉันสามารถทำได้คือเก็บสองชุดนี้เป็นรายการที่เรียงลำดับแล้วเปรียบเทียบทุกองค์ประกอบของกับทุกองค์ประกอบของBในแบบเชิงเส้น เราทำได้ดีกว่านี้ไหมAB


หากคุณยินดีเก็บไว้ต่างกันคุณอาจได้ผลลัพธ์ที่ดีกว่า
Realz Slaw

นอกจากนี้หากคุณเต็มใจที่จะรับผลลัพธ์เป็นโครงสร้างข้อมูลโดยปริยาย คุณสามารถสร้างโครงสร้างที่สอบถามทั้งสองชุดเพื่อตอบแบบสอบถามแต่ละชุด
Realz Slaw

1
@ user917279 ประเด็นสำคัญข้อหนึ่งคือ: โดยปกติคุณสามารถแลกเปลี่ยนเวลาก่อนการผลิต / การสร้างเวลาการสืบค้นและการใช้หน่วยความจำซึ่งกันและกัน คุณแก้ไขโครงสร้างบ่อยครั้ง แต่สืบค้นบ่อยหรือไม่ รอบทางอื่น ๆ ? หน่วยความจำเป็นปัญหาหรือไม่? คำถามดังกล่าวสามารถตอบได้จากมุมมองของภาคปฏิบัติและแจ้งทางเลือกของโครงสร้าง "ถูกต้อง" "ตามหลักทฤษฎี"
กราฟิลส์

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

1
@ user917279 หากคุณพิจารณาตัวอย่างของชุดใหญ่สองชุดที่เหมือนกันดังนั้นโครงสร้างข้อมูลใด ๆ ที่สร้างขึ้นโดยใช้ hash-consing จะสนับสนุนการทดสอบความเท่าเทียมกันใน O (1) เนื่องจากโครงสร้างที่เท่ากันจะถูกผสานเมื่อสร้างขึ้นและแบ่งปันตำแหน่งหน่วยความจำเดียวกัน ชุดที่ต่อเนื่องกันมาบรรจบกันใช้ประโยชน์จาก hash-consing เช่นกันเมื่อทั้งสองโครงสร้างมีค่าเกือบเท่ากัน ความซับซ้อนเป็นสิ่งที่ดีที่สุดที่ฉันเคยเห็นสำหรับชุดที่สั่งมา
Smossen

คำตอบ:


9

หากคุณยินดีจัดเก็บชุดข้อมูลไว้ในโครงสร้างข้อมูลเฉพาะคุณอาจได้รับความซับซ้อนที่น่าสนใจ

ให้I=O(min(|A|,|B|,|AΔB|))

จากนั้นคุณสามารถดำเนินการชุดB , B , BและΔ Bในแต่ละO (ผมเข้าสู่ระบบ| | + | B |AB,AB,ABAΔBเวลาที่คาดหวัง โดยพื้นฐานแล้วคุณจะได้ขนาดต่ำสุดของสองชุดหรือขนาดของความแตกต่างแบบสมมาตรแล้วแต่จำนวนใดจะน้อยกว่า สิ่งนี้ดีกว่าแบบเส้นตรงถ้าความแตกต่างแบบสมมาตรมีขนาดเล็ก กล่าวคือ หากพวกเขามีทางแยกที่มีขนาดใหญ่ ในความเป็นจริงสำหรับการดำเนินการที่แตกต่างกันสองชุดที่คุณต้องการสิ่งนี้มีความอ่อนไหวในทางปฏิบัติเนื่องจากพวกมันรวมกันเป็นขนาดของความแตกต่างแบบสมมาตรO(ผมเข้าสู่ระบบ|A|+|B|ผม)

ดูชุดข้อมูลและแผนที่แบบต่อเนื่องโดย Olle Liljenzin (2013) สำหรับข้อมูลเพิ่มเติม


Treaps ในกระดาษได้รับคำสั่งค้นหาต้นไม้ ฉันจะไม่นับพวกเขาเป็นโครงสร้างข้อมูลที่ไม่เรียง
Smossen

@smossen จริงพอฉันแก้ไขที่ออก
Realz Slaw

6

การสแกนเชิงเส้นเป็นวิธีที่ดีที่สุดที่ฉันรู้ว่าจะต้องทำอย่างไรหากชุดนั้นแสดงเป็นรายการเชื่อมโยงที่เรียงลำดับ เวลาทำงานเป็น )O(|A|+|B|)

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

ในรายละเอียดเพิ่มเติมคุณสามารถสร้างอัลกอริทึมแบบเรียกซ้ำดังต่อไปนี้เพื่อคำนวณโดยสมมติว่าAและBแสดงเป็นรายการที่เชื่อมโยงกับค่าในลำดับที่เรียงลำดับ:ABAB

difference(A, B):
    if len(B)=0:
        return A # return the leftover list
    if len(A)=0:
        return B # return the leftover list
    if A[0] < B[0]:
        return [A[0]] + difference(A[1:], B)
    elsif A[0] = B[0]:
        return difference(A[1:], B[1:])  # omit the common element
    else:
        return [B[0]] + difference(A, B[1:])

ฉันได้แสดงสิ่งนี้ในหลอก -Python หากคุณไม่ได้อ่านหลามA[0]เป็นหัวหน้าของรายการที่เชื่อมโยงA, A[1:]ส่วนที่เหลือของรายการและ+แสดงให้เห็นถึงการเรียงต่อกันของรายการ สำหรับเหตุผลด้านประสิทธิภาพหากคุณทำงานใน Python คุณอาจไม่ต้องการนำไปใช้ตามที่ระบุไว้ข้างต้นตัวอย่างเช่นอาจใช้เครื่องกำเนิดไฟฟ้าได้ดีกว่าเพื่อหลีกเลี่ยงการสร้างรายการชั่วคราวจำนวนมาก - แต่ฉันต้องการ แสดงแนวคิดในรูปแบบที่ง่ายที่สุด รหัสหลอกนี้มีวัตถุประสงค์เพื่อแสดงให้เห็นถึงอัลกอริทึมไม่ใช่เสนอการใช้งานที่เป็นรูปธรรม

ABAB


น่าอัศจรรย์เรามีตัวเลือกอื่น ๆ ไหมถ้ามีการยกเลิกข้อ จำกัด ที่จะจัดเก็บชุดรายการที่เรียงลำดับหรือไม่
user917279

2

หาก A และ B มีขนาดเท่ากันให้แยกและ interleaved (เช่นตัวเลขคี่ใน A และเลขคู่ใน B) จากนั้นการเปรียบเทียบแบบคู่ของรายการในเวลาเชิงเส้นอาจเหมาะสมที่สุด

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

http://arxiv.org/abs/1301.3388


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

1
เอ้ยคุณเชื่อมโยงกระดาษเดียวกันกับฉัน (ฉันก็เหมือนกับคุณ) ... ตั้งชื่อลิงก์ของคุณในครั้งต่อไป: D
Realz Slaw

@smossen อัศจรรย์เพื่อความรู้อะไร (?) ที่ฉันมีฉันแสดงพวกเขาเป็นรายการเรียง แต่จะเจียมยินดีคำแนะนำอื่น ๆ ด้วย
user917279

2

nA-Ba¯a,


1010รายการที่เป็นไปได้บิตเวคเตอร์ไม่ได้ใช้งานได้จริง
กราฟิลส์

1
อาร์คิดถึงจุดนั้น หนึ่งlongสามารถเก็บองค์ประกอบ 32 หรือ 1 byte, 8 องค์ประกอบ ดังนั้นรายการ 1M สามารถเก็บไว้ใน ~ 125K RAM เท่านั้น! การจัดเก็บข้อมูลที่สามารถอย่างมีนัยสำคัญที่มีประสิทธิภาพมากขึ้นกว่าการแสดงอื่น ๆ ขึ้นอยู่กับว่าปัญหาได้รับการดำเนินการ ...
vzn

ดังนั้นคุณต้องมีชุดมากกว่า 12MB สำหรับ OP ที่สนใจซึ่งจะทำให้แคชทั้งหมด (ปัจจุบัน) และจะน่ากลัวสำหรับชุดเบาบาง โดยเฉพาะอย่างยิ่งการสร้างชุดว่างจะควบคุมการทำงานอื่น ๆ ทั้งหมด (สำหรับชุดที่กระจาย) Knuth จัดการปัญหานี้ใน TAoCP โดยวิธีการ
กราฟิลส์

12MB? ฮะ? โปสเตอร์บอกว่าเขามีแค่ 2 ชุด โปสเตอร์ไม่ได้ระบุความหนาแน่น / ความหนาแน่นของฉาก นี่เป็นคำตอบของฉัน คุณสมมติว่าเขามีฉากโปรยปราย? ไม่มีคำตอบที่ถูกต้องอย่างใดอย่างหนึ่งวิธีการที่จะชี้ให้เห็นว่าเป็นตัวเลือกทางเลือกที่อาจมีประโยชน์ขึ้นอยู่กับสถานการณ์ มันไม่ได้ถูกใช้อย่างผิดปกติในบริบทนี้ ...
vzn

ฉันขอแนะนำให้คุณอ่านคำถามอีกครั้ง: "แต่ละชุดมีประมาณหนึ่งล้านรายการและแต่ละรายการเป็นจำนวนเต็มบวกที่มีความยาวสูงสุด 10 หลัก" มี1010 different numbers that can occur, and there are about 106สิ่งที่อยู่ในรายการ นั่นหมายความว่ามีเพียง 0.01% ของรายการทั้งหมดในบิตเวกเตอร์ของคุณคือ 1 - ผมเรียกว่ากระจัดกระจายมาก ๆ (ปรากฎว่า 12MB ของฉันต่ำเกินไปคุณต้องการแน่นอน10101.15GB.)
Raphael
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.