โครงสร้างข้อมูลที่มีประสิทธิภาพรองรับการแทรกการลบและ MostFrequent


14

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

  • แทรกเข้า ,(d,k)D
  • ลบสมาชิก (ไม่จำเป็นต้องค้นหาเพื่อค้นหาเช่นชี้ไปที่สมาชิกใน )eeeD
  • MostFrequent ซึ่งส่งคืนสมาชิกเช่นนั้นเป็นหนึ่งในคีย์ที่พบบ่อยที่สุดใน (โปรดทราบว่าคีย์ที่บ่อยที่สุดไม่จำเป็นต้องไม่ซ้ำกัน)eDe.keyD

การใช้โครงสร้างข้อมูลนี้อย่างมีประสิทธิภาพคืออะไร

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

สิ่งนี้สามารถให้สำหรับการดำเนินการสองครั้งแรกและสำหรับครั้งที่สาม (เวลาที่เลวร้ายที่สุดในการรันกรณี)Θ(lgn)Θ(1)

ฉันสงสัยว่ามีวิธีแก้ปัญหาที่มีประสิทธิภาพมากกว่านี้ไหม (หรือโซลูชันที่เรียบง่ายกว่าที่มีประสิทธิภาพเท่ากันใช่หรือไม่)


คุณสามารถใช้โครงสร้างการค้นหาแบบทวิภาคที่มีความสมดุลแทนการใช้ตารางแฮชได้หากต้องการ
Joe

ตารางแฮชใช้พื้นที่ที่ไม่ต่อเนื่องมากมายฉันจะเสนอคิวลำดับความสำคัญ มันจะให้ความซับซ้อนในเวลาเดียวกันกับการแทรกและลบ แต่ความซับซ้อนของหน่วยความจำจะดีกว่า
Bartosz Przybylski

@ Joe การใช้ BST แทนตารางแฮชจะทำให้การดำเนินงาน MostFrequent มีประสิทธิภาพลดลง แต่นั่นอาจเป็นการแลกเปลี่ยนที่สมเหตุสมผลสำหรับหน่วยความจำ
Kaveh

2
หากใช้การเปรียบเทียบเท่านั้นอย่างน้อยหนึ่งใน Insert / MostFrequent จะต้องมีการตัดจำหน่ายเนื่องจากขอบเขตที่ต่ำกว่าสำหรับปัญหาความแตกต่างขององค์ประกอบ Ω(logn)
Aryabhata

1
นอกจากนี้ยังมีโครงสร้างที่น่าสนใจในโมเดลการสตรีม springerlink.com/content/t17nhd9hwwry909p
Joe

คำตอบ:


7

ในรูปแบบการเปรียบเทียบตามการคำนวณคุณอาจใช้คิวลำดับความสำคัญโดยใช้ฟีโบนักชีฮีปแทนฮีปทั่วไป สิ่งนี้จะทำให้คุณมีขอบเขตดังต่อไปนี้: เวลาตัดจำหน่ายสำหรับแทรกและเวลาตัดจำหน่ายO ( ล็อกn )สำหรับการดำเนินการลบO(1)O(logn)

ถ้าคุณออกจากรูปแบบการเปรียบเทียบตามและนำมาใช้รูปแบบ RAM ที่ปุ่มได้รับการยกย่องเป็นสตริงไบนารีแต่ละคนมีอยู่ในหนึ่งคำหรือมากกว่าเครื่องคุณอาจใช้คิวลำดับความสำคัญของคุณใน ) แน่นอนคุณสามารถบรรลุทั้งการแทรกและลบการดำเนินการO ( o(logn)และเวลาO(1)สำหรับการดำเนินการ findMin Thorup พิสูจน์แล้วว่าO(loglogn)O(1)

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

ดู M. Thorup ความเท่าเทียมกันระหว่างคิวลำดับความสำคัญและการเรียงลำดับ 2002 ใน Proc FOCS 2002

เนื่องจากเราสามารถจัดเรียงในเวลาที่คาดหวังและพื้นที่เชิงเส้นดังที่แสดงโดยO(nloglogn)

วาย. ฮันและเอ็มทอร์รุป การเรียงลำดับจำนวนเต็มในเวลาที่คาดหวังและพื้นที่เชิงเส้น ใน Proc. FOCS 2002O(nloglogn)

ขอบเขตที่พิสูจน์แล้ว


1

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

โซลูชันด้านล่างของฉันเป็นเพียงโซลูชันของคุณด้วยคิวลำดับความสำคัญ "ไม่มีประสิทธิภาพ" ที่ทำงานได้ดีสำหรับกรณีนี้: คิวลำดับความสำคัญสูงสุดที่ใช้เป็นรายการที่เชื่อมโยงสองครั้งของกลุ่มของคีย์มี O (1) insertMin, deleteMax, removeFaxBucket increaseKey


รักษารายการที่เชื่อมโยงเป็นสองเท่าของที่เก็บข้อมูลโดยที่ที่ฝากข้อมูลแต่ละชุดมีชุดแฮชของคีย์ที่ไม่ว่างเปล่า (ซึ่งฉันจะเรียก Cohort) และจำนวนเต็มบวก (ที่ฉันจะเรียก ValCount) ในถังขแต่ละคีย์ k ในกลุ่มของ b มีจำนวนค่าที่ไม่ซ้ำกันซึ่งเกี่ยวข้องกับค่าในชุดที่คุณกำลังบำรุงรักษา ตัวอย่างเช่นหากชุดของคุณมีคู่ (a, apple), (a, อะโวคาโด), (b, กล้วย), (c, แตงกวา), (d, แก้วมังกร) ซึ่งตัวอักษรเดียวเป็นกุญแจและผลไม้ ค่าจากนั้นคุณจะมีสองถัง: หนึ่งถังจะมี ValCount เป็น 2 และ Cohort ที่ประกอบด้วยคีย์เดียวเท่านั้น: Bucket อื่นจะมี ValCount เป็น 1 และ Cohort ซึ่งประกอบด้วยสามปุ่ม b, c และ d

รายการถังที่เชื่อมโยงเป็นทวีคูณควรได้รับคำสั่งจาก ValCount มันจะเป็นสิ่งสำคัญที่เราสามารถค้นหาหัวและส่วนท้ายของรายการในเวลาและเราสามารถประกบกันในถังใหม่ในเวลาO ( 1 )ถ้าเรารู้ว่าเพื่อนบ้าน ในทางกลับกันฉันจะเรียกรายชื่อ Bucketets the BucketListO(1)O(1)

นอกเหนือจาก BucketList เราจะต้องใช้ SetMap ซึ่งเป็นคีย์การแมปแฮชกับ ValueBuckets ValueBucket เป็นคู่ที่ประกอบด้วยชุดค่า (ชุดแฮชที่ไม่ว่างเปล่าของค่า) และตัวชี้ที่ไม่ใช่ค่าว่างไปยังที่ฝากข้อมูล ชุดค่าที่เกี่ยวข้องกับคีย์ k มีค่าเฉพาะทั้งหมดที่เกี่ยวข้องกับ k ตัวชี้ Bucket ที่เกี่ยวข้องกับ ValueSet มี Cohort เท่ากับขนาดของ ValueSet ที่ฝากข้อมูลที่เชื่อมโยงกับคีย์ k ใน SetMap นั้นเชื่อมโยงกับคีย์ k ใน BucketList ด้วย

ใน C ++:

struct Bucket {
    unsigned ValCount;
    unordered_set<Key> Cohort;
    Bucket * heavier;
    Bucket * lighter;
};
Bucket * BucketListHead;
Bucket * BucketListTail;

struct ValueBucket {
  unordered_set<Value> ValueSet;
  Bucket * bucket;
};
unordered_map<Key, ValueBucket> SetMap;

ในการหาคู่คีย์ - ค่าความถี่สูงสุดเราเพียงแค่ต้องดูที่หัวของ BucketList ค้นหาคีย์ใน Cohort ค้นหาคีย์นั้นใน SetMap และค้นหาค่าใน ValueSet ของ ValueBucket (วุ้ย!)

การแทรกและการลบคู่คีย์ - ค่าเป็นเรื่องยุ่งยาก

ในการแทรกหรือลบคู่คีย์ - ค่าอันดับแรกเราจะแทรกหรือลบใน SetMap สิ่งนี้จะเปลี่ยนขนาดของ ValueSet ดังนั้นเราต้องแก้ไข Bucket ที่เกี่ยวข้องกับกุญแจ บุ้งกี๋เดียวที่เราจะต้องดูเพื่อทำการเปลี่ยนแปลงนี้จะเป็นเพื่อนบ้านทันทีของกลุ่มกุญแจที่เคยมีอยู่มีหลายกรณีที่นี่และพวกเขาอาจจะไม่คุ้มกับการสะกดคำอย่างสมบูรณ์แม้ว่าฉันจะมีความสุข ทำอย่างละเอียดหากคุณยังคงมีปัญหา


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

ต่อไปนี้เป็นอีกวิธีในการคิดถึงโซลูชันของฉัน: เป็นเพียงโซลูชันของคุณที่มีลำดับความสำคัญ "ไม่มีประสิทธิภาพ" ที่ทำงานได้ดีสำหรับกรณีนี้ คิวลำดับความสำคัญสูงสุดมีการใช้งานเป็นรายการที่เชื่อมโยงสองครั้งของที่เก็บคีย์ที่มี O (1) insertMin, deleteMax, removeFromBucket และเพิ่มคีย์
jbapple

วิธีที่มีประสิทธิภาพมากที่สุด (ในกรณีที่แย่ที่สุด) ในการรักษาการแมปจากคีย์สำหรับ ValueBuckets น่าจะเป็นแผนผังการค้นหา
กราฟิลส์

Raphael - ฉันไม่แน่ใจว่าคุณกำลังทำอะไรอยู่ คุณกำลังบอกว่าตารางแฮชมีราคาแพงในทางปฏิบัติหรือว่าพวกเขามีประสิทธิภาพที่ไม่ดีในกรณีที่เลวร้ายที่สุดหรือบางสิ่งที่สาม?
jbapple

-3

ความซับซ้อนกรณีที่เลวร้ายที่สุด

O(1)

O(1)

O(1)

O(loglogn)

O(n)

พิสูจน์

[0,N) O(log log min{n,N})

ซึ่งจัดตั้งขึ้นด้วยการรวมกันของ:

τ(n,N) n[0,N) τ(n,N)τ(N,N)τ

และ:

ทฤษฎีบท 6. ทฤษฎีบท 6. เราสามารถใช้ลำดับความสำคัญคิวที่มีn คีย์จำนวนเต็มในช่วง [0,ยังไม่มีข้อความ)ในพื้นที่เชิงเส้นสนับสนุนFi ครั้งนาที , แทรกและธันวาคมที่สำคัญในเวลาที่คงที่และลบในO(1+ล.โอก. ล.โอก. n-ล.โอก. ล.โอก. Q) เวลาสำหรับตำแหน่งที่สำคัญ Q.

การอ้างอิง

Thorup, Mikkel “ คิวลำดับความสำคัญของเลขจำนวนเต็มที่มีคีย์ลดลงในเวลาคงที่และปัญหาเส้นทางที่สั้นที่สุดที่มาเดียว” ในการดำเนินการประชุมวิชาการ ACM ประจำปีครั้งที่สามสิบห้าเกี่ยวกับทฤษฎีการคำนวณ, 149–158 STOC '03 New York, NY, USA: ACM, 2003


โปรดทราบว่าในคิวลำดับความสำคัญทั้งหมดจะไม่สำคัญที่จะย้ายไปยังโครงสร้างที่รองรับ 'get-min' และ 'extract-min' ไปยังโครงสร้างที่รองรับ 'get-max' และ 'extract-max'
AT

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