อัลกอริทึมเพื่อผสานสองอาร์เรย์ที่เรียงลำดับด้วยจำนวนการเปรียบเทียบขั้นต่ำ


24

ป.ร. ให้ไว้สองอาร์เรย์เรียง, BประเภทTที่มีขนาดnและม. ฉันกำลังมองหาอัลกอริทึมที่ผสานสองอาร์เรย์เข้ากับอาร์เรย์ใหม่ (ขนาดสูงสุด n + m)

หากคุณมีการเปรียบเทียบราคาถูกนี่ค่อนข้างง่าย เพียงนำจากอาเรย์ที่มีอิลิเมนต์แรกที่ต่ำที่สุดจนกระทั่งหนึ่งหรือทั้งสองอาร์เรย์ถูกสำรวจอย่างสมบูรณ์จากนั้นเพิ่มอิลิเมนต์ที่เหลือ บางสิ่งเช่นนี้/programming/5958169/how-to-merge-two-sorted-arrays-into-a-sorted-array

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

ในกรณีนี้คุณต้องการที่จะผสานสองอาร์เรย์มีจำนวนต่ำสุดของการเปรียบเทียบองค์ประกอบ นี่คือตัวอย่างบางส่วนที่คุณควรจะทำได้ดีกว่าอัลกอริธึมการผสานอย่างง่าย:

a = [1,2,3,4, ... 1000]
b = [1001,1002,1003,1004, ... 2000]

หรือ

a = [1,2,3,4, ... 1000]
b = [0,100,200, ... 1000]

มีบางกรณีที่อัลกอริทึมการผสานอย่างง่ายจะเหมาะสมที่สุดเช่น

a = [1,3,5,7,9,....,999]
b = [2,4,6,8,10,....,1000]

ดังนั้นอัลกอริธึมจึงควรลดระดับลงอย่างงดงามและทำการเปรียบเทียบสูงสุด n + m-1 ในกรณีที่อาร์เรย์ถูกอินเตอร์ลีบหรืออย่างน้อยก็ไม่ได้แย่ลงอย่างมีนัยสำคัญ

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

สิ่งเดียวที่มีให้สำหรับองค์ประกอบคือฟังก์ชั่นการสั่งซื้อ (รวม) ดังนั้นจึงไม่สามารถใช้รูปแบบการเปรียบเทียบที่ถูกกว่าได้

ความคิดใด ๆ

ฉันได้มาด้วยบิตนี้ในกาลา ฉันเชื่อว่าเป็นสิ่งที่ดีที่สุดเกี่ยวกับจำนวนการเปรียบเทียบ แต่มันเกินความสามารถในการพิสูจน์มัน อย่างน้อยก็เป็นมากง่ายกว่าสิ่งที่ฉันได้พบในวรรณคดี

และตั้งแต่การโพสต์ต้นฉบับฉันเขียนบล็อกโพสต์เกี่ยวกับวิธีการทำงาน


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

5
@ Mephy: ให้ความกระจ่างแก่เราและให้เราพิสูจน์อย่างเป็นทางการได้โปรด หรือถ้าคุณทำไม่ได้ให้พิจารณาลบ (หรืออย่างน้อยปรับแต่ง) ความคิดเห็นของคุณ
Doc Brown

4
@DocBrown ถ้าฉันมีหลักฐานอย่างเป็นทางการฉันจะให้คำตอบไม่ใช่ความคิดเห็น อย่างไรก็ตามมันเป็นปัญหาเชิงเส้นที่ชัดเจนเนื่องจากการพยายามหาวิธีแก้ปัญหาที่ดีกว่าเชิงเส้นต้องใช้เวลาเชิงเส้นอย่างน้อย
Mephy

4
@Mephy: ฉันขอแนะนำให้คุณสละเวลาอ่านคำตอบด้านล่างและลองคิดดูอีกครั้งเกี่ยวกับสิ่งที่คุณเขียน
Doc Brown

4
@Mephy สิ่งที่เห็นได้ชัดที่สุด ("คุณไม่สามารถคูณในเวลาน้อยกว่า O (n ^ 2)", "ถ้าฉันเปลี่ยนประตูที่ฉันเลือกฉันจะไม่เพิ่มโอกาสในการชนะราคา" , "คุณสามารถ ไม่เรียงลำดับน้อยกว่า O (n log n) ", .. ) ผิด การใช้วิธีการค้นหาแบบไบนารีในรายการตัวอย่างที่สั้นกว่าน่าจะช่วยปรับปรุงกรณีโดยเฉลี่ย
Voo

คำตอบ:


31

อัลกอริทึมการเรียงลำดับการผสานปกติ - ขั้นตอนการผสานโดยปกติจะใช้การเปรียบเทียบ n + m -1 โดยที่หนึ่งรายการมีขนาด n และรายการอื่น ๆ มีขนาด m การใช้อัลกอริทึมนี้เป็นวิธีที่ง่ายที่สุดในการรวมรายการที่เรียงลำดับสองรายการ

หากการเปรียบเทียบมีราคาแพงเกินไปคุณสามารถทำสองสิ่งได้ไม่ว่าคุณจะลดจำนวนการเปรียบเทียบหรือลดต้นทุนการเปรียบเทียบ

มามุ่งเน้นที่การลดต้นทุนการเปรียบเทียบให้น้อยที่สุด คุณและคุณเท่านั้นที่สามารถตัดสินใจได้ว่าข้อมูลที่คุณเปรียบเทียบนั้นสามารถนำมาคำนวณปริมาณได้หรือไม่ หากคุณสามารถหาจำนวนพวกมันซึ่งเป็นรูปแบบหนึ่งของการใช้วิธีแฮชซึ่งกำลังทำการสั่งซื้ออยู่ เช่นถ้าข้อมูลของคุณถูกเปรียบเทียบด้วยชื่อจากนั้นชื่อแรกแล้ว ... คุณสามารถใช้ชื่อแรกเป็นชื่อ "Klaehn, Ruediger" และลด / คำนวณปริมาณข้อมูลองค์ประกอบของคุณเป็น "Kl.Ru" หากคุณเปรียบเทียบ ถึง "Packer," คุณรักษาการสั่งซื้อ "Pa.Th" - ตอนนี้คุณสามารถใช้อัลกอริทึมการเปรียบเทียบที่ถูกกว่าโดยเปรียบเทียบค่าที่ลดลง แต่ถ้าคุณพบ "Kl.Ru" อีกตัวตอนนี้คุณมีค่าใกล้และคุณอาจเปลี่ยนไปใช้วิธีการที่แพงกว่าเมื่อเปรียบเทียบองค์ประกอบเหล่านี้

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

ฉันยังกล่าวถึงวิธีอื่นเพื่อลดการเปรียบเทียบของคุณ

ฉันได้ดูหนังสือคลาสสิก TAOCP- เล่มที่ 3 การเรียงลำดับและการค้นหา (pp.197-207 มาตรา 5.3.2) ซึ่งมี 10 หน้าเต็มในหัวข้อนี้ ฉันพบสองการอ้างอิงถึงอัลกอริทึมที่เร็วกว่าการเปรียบเทียบ n + m-1

อย่างแรกคืออัลกอริธึมการรวม Hwang-Lin และการปรับปรุงครั้งที่สองโดย Glenn K Manacher - ทั้งคู่อ้างโดย TAOCP เช่นเดียวกับอัลกอริทึมของ Christen ซึ่งเข้าใกล้การเปรียบเทียบที่จำเป็นในเงื่อนไขพิเศษบนความยาว n และ m ของรายการ

อัลกอริทึมของ Manacher ถูกนำเสนอในวารสารของ ACM ฉบับ 26 หมายเลข 3 ในหน้า 434-440: "การปรับปรุงที่สำคัญของอัลกอริทึมการผสาน" Hwan-Lin " รายการที่มีรายการ m และรายการที่มี n รายการอาจมีความยาวแตกต่างกัน แต่พวกเขาจะต้องได้รับการดมกลิ่นด้วยจำนวนองค์ประกอบที่มี m <= n

อัลกอริทึม Hwang-Lin แบ่งรายการเพื่อรวมนอกเหนือจากรายการที่มีขนาดเล็กกว่าและเรียงลำดับรายการโดยการเปรียบเทียบองค์ประกอบแรกของแต่ละรายการย่อยและเพื่อพิจารณาว่าองค์ประกอบบางอย่างในรายการย่อยจำเป็นต้องทำการเปรียบเทียบหรือไม่ หากรายการแรกมีขนาดเล็กกว่ารายการที่สองโอกาสจะสูงองค์ประกอบที่ต่อเนื่องกันของรายการที่ยาวขึ้นสามารถโอนเข้าสู่รายการผลลัพธ์โดยไม่มีการเปรียบเทียบ หากองค์ประกอบแรกของ ist ขนาดเล็กมากกว่าองค์ประกอบแรกของรายการขนาดใหญ่ที่แยกองค์ประกอบทั้งหมดที่อยู่ด้านหน้าของรายการย่อยสามารถคัดลอกได้โดยไม่มีการเปรียบเทียบ

การวิเคราะห์กรณีโดยเฉลี่ยของการรวมกันของอโลลิ ธ ของ Hwang และ Lin (Vega, Frieze, Santha)ในส่วนที่ 2 คุณสามารถค้นหารหัสเทียมของอัลกอริธึม HL ไหนดีกว่าคำอธิบายของฉันมาก และคุณสามารถดูว่าทำไมมีการเปรียบเทียบน้อยกว่า - อัลกอริทึมใช้การค้นหาแบบไบนารีเพื่อค้นหาดัชนีซึ่งจะแทรกองค์ประกอบจากรายการที่สั้นกว่า

หากรายการต่าง ๆ ไม่เหมือนในตัวอย่างสุดท้ายของคุณคุณควรมีขนาดเล็กกว่าและรายการขนาดใหญ่ที่เหลือในกรณีส่วนใหญ่ นี่คือเมื่ออัลกอริทึม HL เริ่มทำงานได้ดีขึ้น


ขอบคุณสำหรับความคิดเห็นของคุณเกี่ยวกับเรื่องนี้ - ฉันตรวจสอบคำตอบของฉันและพบว่า Knuth ใช้จ่ายเต็มหน้า 10 ในหัวข้อนี้ และจากนั้นฉันก็หยิบ The JACM จากชั้นวางหนังสือและมองไปข้างหน้ามากกว่านี้ ฉันจะปรับปรุงคำตอบของฉัน - ไม่จำเป็นสำหรับการ downvoting อัลกอริทึม hash- (quantizer) เป็นแนวคิดง่าย ๆ ซึ่งสามารถนำไปใช้กับชุดข้อมูลจำนวนมาก - แต่มีเพียงคนที่ถามว่าเป็นคนเดียวที่ตัดสินใจได้ว่ามันเหมาะสมกับข้อมูลของเขาหรือไม่
thepacker

4
หลังจากที่คุณปรับปรุงคำตอบของคุณทุกคนที่ลงคะแนนคุณจะได้รับโอกาสที่จะโหวตคุณอีกครั้ง ;-)
Doc Brown

+1 สำหรับการสังเกตว่าหากขนาดแตกต่างกันมากการผสานมาตรฐานจะไม่เหมาะสม
Florian F

1

สมมติว่าทั้งสองอาร์เรย์มีองค์ประกอบ N และ M, N ≥ M และองค์ประกอบทั้งหมดจะแตกต่างกัน

หากอาร์เรย์ที่เรียงลำดับมีองค์ประกอบ x ของ N ตามด้วยองค์ประกอบ y ของ M หรือในทางกลับกันดังนั้น x และ y ต้องถูกเปรียบเทียบมิฉะนั้นเราจะไม่ทราบว่าเรียงลำดับใด (ไม่สามารถมีองค์ประกอบอื่น ๆ พูดว่า a, b, c ซึ่งเรารู้ว่า x <a <b <c <y เช่นเนื่องจากไม่มีองค์ประกอบระหว่าง x และ y ดังนั้นจึงต้องเปรียบเทียบ x และ y โดยตรง.

ถ้า N> M เป็นไปได้ที่จะมีอาร์เรย์ที่แต่ละองค์ประกอบของ M นำหน้าและตามด้วยองค์ประกอบของ N ซึ่งหมายความว่าต้องมีการเปรียบเทียบอย่างน้อย 2M - แม้ว่าคุณจะใช้อัลกอริทึมการเรียงลำดับที่ไม่สามารถกำหนดได้ การเดาที่สมบูรณ์แบบที่จะเปรียบเทียบตัวเลข (หมายความว่าอะไร: สมมติว่าคุณมี N large, M = 1 การค้นหาแบบไบนารี่ใช้ขั้นตอน O (log2 N) อัลกอริทึมแบบไม่กำหนดค่าจะเดาได้ว่าองค์ประกอบสองอย่างที่องค์ประกอบหนึ่งของอาร์เรย์ลำดับที่สองเป็นสมาชิก ยืนยันการเดา)

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