มีอัลกอริทึม "การเรียงลำดับ" ซึ่งส่งกลับค่าการสุ่มเมื่อใช้ตัวเปรียบเทียบแบบพลิกเหรียญหรือไม่?


9

แรงบันดาลใจจากคำถามนี้ที่ผู้ถามต้องการทราบว่าเวลาทำงานเปลี่ยนไปเมื่อตัวเปรียบเทียบที่ใช้ในอัลกอริธึมการค้นหามาตรฐานถูกแทนที่ด้วยการพลิกเหรียญอย่างยุติธรรมและความล้มเหลวที่โดดเด่นของ Microsoft ในการเขียนเครื่องกำเนิดการเปลี่ยนแปลงแบบสม่ำเสมอ :

มีอัลกอริทึมการเรียงลำดับแบบอิงซึ่งจะขึ้นอยู่กับการนำไปใช้ของตัวเปรียบเทียบ:

  1. คืนองค์ประกอบในลำดับที่เรียงเมื่อใช้ตัวเปรียบเทียบที่แท้จริง (นั่นคือการเปรียบเทียบทำตามที่เราคาดหวังในอัลกอริทึมการเรียงลำดับมาตรฐาน)
  2. ส่งคืนการเปลี่ยนแปลงการสุ่มอย่างสม่ำเสมอขององค์ประกอบเมื่อตัวเปรียบเทียบถูกแทนที่ด้วยการพลิกเหรียญอย่างยุติธรรม (นั่นคือกลับx < y = trueด้วยความน่าจะเป็น 1/2 โดยไม่คำนึงถึงค่าของ x และ y)

รหัสสำหรับอัลกอริทึมการเรียงลำดับจะต้องเหมือนกัน มันเป็นเพียงรหัสในการเปรียบเทียบ "กล่องดำ" ที่ได้รับอนุญาตให้เปลี่ยน


ดูคำถามนี้ด้วย
Raphael

2
ดูเพิ่มเติมคำถามที่น่าสนใจดังต่อไปนี้: cstheory.stackexchange.com/questions/5321/...
Yuval Filmus

1
คุณต้องการให้เครื่องมือเปรียบเทียบแบบสุ่มของคุณมีความประพฤติดีหรือไม่? นี่เป็นวิธีที่เป็นไปได้สองวิธี (1) เมื่อเปรียบเทียบทำให้ขึ้นใจว่าแล้วเสมอและยัง x (2) เหมือนกัน แต่ถ้าผู้เปรียบเทียบเปรียบเทียบตัดสินใจว่าและมันก็จะตกลงที่ (และ ) ในทั้งสองกรณีแบบสอบถามที่ไม่มีข้อ จำกัด แต่ละแบบสอบถามจะสุ่มโดยสมบูรณ์ x<yx<yy>xx<yy<zx<zz>x
Yuval Filmus

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

1
ดูที่นี่สำหรับการแสดงผลที่ดี
ราฟาเอล

คำตอบ:


3

อัลกอริธึมที่กำหนดขึ้นเอง (โดยไม่มีตัวเปรียบเทียบ) ต่อไปนี้ใช้สำหรับ tuple อินพุต (a1,...,an):

  1. ทำการสับเปลี่ยน Fisher-Yatesโดยใช้เครื่องมือเปรียบเทียบกับคู่คงที่บางตัว (พูดa1<a2) เป็นการพลิกเหรียญ (ทำการสุ่มตัวอย่างปฏิเสธการยอมรับ) ถ้าตัวเปรียบเทียบเอาท์พุท1 ในครั้งแรกให้ใช้มันคว่ำเพื่อหลีกเลี่ยงการปฏิเสธการวนซ้ำในกรณีที่กำหนดขึ้น
  2. (เร่งความเร็วเพิ่มเติม: ลองคู่เดียว n ครั้งที่ไหน nคือความยาวหรืออินพุตของคุณ หากสองผลลัพธ์ใด ๆ กลับต่างกันจะได้การเปลี่ยนแปลงที่ได้ใน (1)
  3. จัดเรียงอาร์เรย์ของคุณโดยใช้การจัดเรียงผสาน

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

เมื่อมีการพลิกเหรียญจริงเมื่อเปรียบเทียบ (1) อนุญาตอาร์เรย์ที่มีความน่าจะเป็นเท่ากันสำหรับการเปลี่ยนแปลงแต่ละครั้งและถ้าคุณต้องทำจริง ๆ (3) (คุณออกไป (2) หรือ (2) ล้มเหลวในการพิจารณาแบบสุ่ม) นี่ไม่ใช่ เป็นอันตรายเนื่องจากการกระจายของผลลัพธ์ขึ้นอยู่กับลำดับของอินพุตที่กระจายอย่างสม่ำเสมอในทุกวิธีเรียงสับเปลี่ยนเนื่องจาก (1) ดังนั้นผลลัพธ์ของอัลกอริธึมทั้งหมดจึงกระจายอย่างสม่ำเสมอ จำนวนครั้งที่ต้องสุ่มตัวอย่างการปฏิเสธการตอบรับซ้ำแต่ละครั้งมีการกระจายเชิงเรขาคณิต (ปฏิเสธด้วยความน่าจะเป็น<12) และดังนั้นจึงมีค่าที่คาดหวัง <2. การทำซ้ำแต่ละครั้งจะใช้อย่างมากที่สุดเข้าสู่ระบบnบิตดังนั้นการวิเคราะห์รันไทม์เกือบเช่นเดียวกับในกรณีที่กำหนด แต่เราเท่านั้นที่จะได้รับการรันไทม์คาดของO(nเข้าสู่ระบบn)ด้วยความเป็นไปได้ของการกำจัด (สิ้นสุดเพียงเกือบแน่นอน )


ดังที่โจชี้: ถ้าคุณไม่ชอบการทดสอบบิตแรกใน (1) ให้ทำ (3) จากนั้น (1) และใช้ an<a1 ซึ่งเป็นเสมอ 0เนื่องจากอาร์เรย์ถูกเรียงลำดับแล้วในกรณีที่กำหนดขึ้น นอกจากนี้คุณต้องลบจำนวนสุ่มของคุณจากขอบเขตบนของช่วงในลูปเนื่องจากขอบเขตบนของหมายเลขสุ่มจะทำให้เกิดการเปลี่ยนแปลงที่เหมือนกัน แต่โปรดระวังว่า (2) นั้นเป็นสิ่งต้องห้ามเพราะคุณจะต้องสับเปลี่ยนในกรณีเรียกค่าไถ่เสมอ


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


อัลกอริทึมต่อไปนี้ไม่มีเฟสที่แตกต่างกันในการสุ่มและเรียงลำดับ แต่ช้าลงแบบไม่แสดงอาการ มันเป็นหลักจัดเรียงแทรกกับการค้นหาแบบไบนารี ฉันจะใช้a=(a1,...,an) เพื่อแสดงถึงอินพุตและ k=(k,1,...,k,k) เพื่อแสดงผลลัพธ์หลังจาก k- รอบที่:

  1. ชุด 1,1=a1
  2. ถ้า a2<a1 แล้วก็ 2=(a2,a1) และ (,d)=(2,1) อื่น 2=(a1,a2) และ (,d)=(1,2). ไม่ว่าในกรณีใดad<a จะเป็น 0 (เช่นเท็จ) สำหรับเครื่องมือเปรียบเทียบแบบไม่สุ่ม
  3. ที่จะได้รับ k สำหรับ k3 ได้รับ k-1 เป็นครั้งแรก
  4. ปล่อย ล.=ล.โอก.2k และ k'=2ล.เช่น k' เป็นพลังที่น้อยที่สุด 2 ไม่เล็กกว่า k.
  5. ปล่อย ผม0=0. สำหรับทุกคนJ{1,...,ล.} ปล่อย
    ij={ij1+2ljij1+2lj>k1ad<aผมJ-1ผมJ-1+2ล.-J>k-1¬(ad<a)ผมJ-1+2ล.-JผมJ-1+2ล.-Jk-1k-1,ผมJ-1+2ล.-J<akผมJ-1ผมJ-1+2ล.-Jk-1¬(k-1,ผมJ-1+2ล.-J<ak)
  6. ถ้า ผมล.>k ทำซ้ำ (5. ) อื่น ๆ k=(k-1,1,...,k-1,ผมล.-1,ak,k-1,ผมล.,...,k-1,k-1)
  7. เอาท์พุต n

กรณีสุ่ม: 5 + ถ้าข้อ 6 เป็นตัวอย่างการยอมรับ - ปฏิเสธเป็นหลัก อัลกอริทึมที่เหลือคือการสลับแบบไร้เดียงสา: สับเปลี่ยนเป็นอันดับแรกk-1 องค์ประกอบและเพิ่ม kองค์ประกอบ -th ของแต่ละตำแหน่งที่มีความน่าจะเป็นที่เท่ากัน หากเราใช้การเรียงลำดับการแทรกแบบปกติเราจะได้การแจกแจงแบบทวินามแทน

โปรดทราบว่าอัลกอริทึมนี้ไม่มีประสิทธิภาพในทั้งสองโหมดเมื่อเปรียบเทียบกับการสับเปลี่ยนแบบ Fisher-Yates และการเรียงแบบผสานขณะที่การแทรกองค์ประกอบไปยังตำแหน่งที่กำหนดเองจะมีราคาแพงหากใช้อาร์เรย์และการค้นหาแบบไบนารี่ต้องการเวลาเชิงเส้น แต่บางทีการดัดแปลง heap sort หรือ tree sort ในทำนองเดียวกันอาจทำให้อัลกอริทึมเร็วขึ้น


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

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

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

ความคิดเห็นแรก: โปรดทราบว่าฉันไม่ทิ้งบิตตัวอย่างแรกนั่นคือ "ใช้คู่" ฉันคิดถึงการย้อนกลับทุกๆ 2 บิต แต่นั่นจะไม่ป้องกันการวนซ้ำไม่รู้จบ ในความเป็นจริงบางรูปแบบที่ผิดปกติเป็นสิ่งจำเป็นและอาจปฏิเสธรายการมากขึ้น แน่นอนว่าฉันสามารถ XOR สองบิตล่าสุดแทนบิตแรกและบิตล่าสุด แต่นั่นไม่ได้แตกต่างกันจริงๆ
frafl

ความคิดเห็นที่สอง: คำสั่งซื้อ (1) กับ (3) มีความสำคัญเฉพาะถ้าคุณใช้ขั้นตอน (2) เพราะในกรณีสุ่มคุณต้องมั่นใจว่าการสับเปลี่ยนเสร็จสิ้นด้วยความน่าจะเป็น 1 มิฉะนั้นการแจกจ่ายแบบสม่ำเสมอจะถูกละเมิด ทำไมมันต้องขึ้นอยู่กับผม? ในกรณีนี้an<a1 มักจะตอบ 0นั่นคือทั้งหมดที่เราต้องการ
frafl

4

ไม่เป็นไปไม่ได้นอกจาก n2. ความน่าจะเป็นที่การเปลี่ยนแปลงเกิดขึ้นโดยอัลกอริทึมของคุณโดยใช้เครื่องมือเปรียบเทียบแบบสุ่มคือ dyadic เช่นรูปแบบA/2Bในขณะที่น่าจะเป็น 1/n!. เมื่อไหร่n>2ไม่มีวิธีเขียน 1/n! ในรูปแบบ A/2B.


1
แต่สิ่งนี้จะเก็บไว้ก็ต่อเมื่อเราต้องการขอบเขตที่แน่นอนในรันไทม์ซึ่งไม่ได้ถูกร้องขอในคำถาม หากเราต้องการให้รันไทม์ที่คาดหวังเท่านั้นที่จะ จำกัด ซึ่งจะไม่มีปัญหา
frafl

1
คุณตระหนักถึงอัลกอริทึมการเรียงลำดับที่สมเหตุสมผลซึ่งไม่ได้ยุติในเวลาพหุนามหรือไม่
Yuval Filmus

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

@YuvalFilmus ทำไมต้นไม้การตัดสินใจต้องมี 2kใบไม้?
Joe

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