ค้นหาว่าใครจะซื้อครัวซองต์บ้าง


9

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

ข้อ จำกัด สมมติฐานและวัตถุประสงค์:

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

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

แหล่งกำเนิดสินค้า: หาผู้ที่จะซื้อครัวซองต์โดยFlorian Margaine การปฏิรูปของฉันที่นี่มีข้อกำหนดแตกต่างกันเล็กน้อย


1
คำถามอะไรกันแน่ เราสามารถสันนิษฐานได้หรือไม่ว่าผู้คนไม่อยู่กันมากหรือน้อยกว่ากัน? เกิดอะไรขึ้นกับการเอาคนที่ทำสิ่งนี้มาน้อยที่สุดหรือเป็นแค่คนสุ่ม?
Pål GD

@ PålGDสมมติว่าผู้คนไม่อยู่ด้วยปริมาณเท่ากันจะเป็นการทำให้เข้าใจง่าย ทำได้ถ้าคุณต้องการ แต่ถ้าอัลกอริทึมของคุณใช้กับตัวจับเวลาได้ดีกว่า การให้บุคคลที่ทำสิ่งนี้น้อยที่สุดเป็นวิธีแก้ไขปัญหาหนึ่ง (แม้ว่าจะคำนึงถึงความต้องการที่พวกเขารู้ล่วงหน้าหนึ่งวัน คนที่สุ่มก็สามารถทำงานได้เช่นกัน แต่การสุ่มทำให้เกิดการเบี่ยงเบนจากความเป็นธรรมซึ่งคุณอาจต้องการผูกมัด
Gilles 'หยุดความชั่วร้าย'

อะไร? ไม่มีภาพน้ำลายไหล? คุณต้องการให้เราเป็นทาสที่โต๊ะทำงานของเราทำคณิตศาสตร์แทนที่จะลื่นไถลไปที่ร้านเบเกอรี่?
คาเลบ

@Gilles - FYI กำลังดำเนินการทดสอบกับ P.SE กับรุ่นของคำถามนี้ ตอนนี้เว็บไซต์ทั้งสองเก่ากว่านี้ฉันอยากรู้ว่าคำตอบของแต่ละชุมชนเป็นอย่างไร

คำตอบ:


7

มีสองประเภทของการแก้ปัญหาในการเรียงลำดับของปัญหานี้ที่ฉันรู้คือสลากลำเอียงและกรอง / ลำดับที่สร้างแบบสุ่ม

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

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

ดังนั้นในการแก้ปัญหาทั้งสองประเภท

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

    case class Employee(var bias: Double) {
      def eat         { bias -= 1 }
      def buy(n: Int) { bias += n }
      def roll        = bias + stdev * Random.nextGaussian
    }
    

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

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

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

    หากคุณใช้การสลับแบบมาตรฐานคุณสามารถหาปริมาณการสุ่มได้อย่างง่ายดายเมื่อไม่มีวันหยุดพักผ่อน หากคุณเลือกคนโดยสมบูรณ์แบบสุ่มความรู้ของผู้ที่จะนำมาต่อไปจะมีlog2(N) บิตของข้อมูลถ้ามี Nพนักงาน อย่างไรก็ตามแทนเท่านั้นN! แทน NN อนุญาตลำดับที่เป็นไปได้ดังนั้นข้อมูลจะถูกลดลง log2[(N!NN)1/N]1log(2)+log22π/NN1.4 บิต (สำหรับขนาดใหญ่ N; สำหรับN=10 มันเป็น  1.14)

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


4

ปล่อย {P1,...,Pn}เป็นชุด byers ของครัวซองต์ ปล่อยvik1 เป็นจำนวนเงินที่ใช้ไป Pi ในครัวซองต์ถึงวันที่ k(อาจเป็นจำนวนครั้งที่เขาซื้อครัวซองต์ถ้าพวกเขาใช้เงินเท่าเดิมไม่ว่าจะมีคนกี่คนในโลกนี้ซึ่งดูไม่ฉลาดพอสำหรับคนรักครัวซองต์ของเรา) 1 มีไว้สำหรับการเริ่มต้นและเพื่อหลีกเลี่ยงการหารด้วย 0.

สำหรับบางพารามิเตอร์ l, ปล่อย vk=i=1n(vik)l.

ในเวลากลางวัน kพวกเขาเลือกผู้ซื้อครัวซองต์ในวันถัดไปโดยการสุ่มตัวแปรที่เป็นผลลัพธ์ i ด้วยความน่าจะเป็น 1(vik)lvk. หากคนที่เลือกไม่ได้อยู่ที่นี่ (วันนี้หรือวันหลังจากนั้น) พวกเขาโยนเหรียญอีกครั้งจนกว่าพวกเขาจะพบคนที่เหมาะสม (เขามีอยู่เพราะพวกเขาส่วนใหญ่อยู่ที่นี่ทุกวัน ... )

และพวกเขาใช้ชีวิตอย่างมีความสุขจนกระทั่งพบว่า P1คนขี้ขลาดนั้นอยู่ที่นั่นแค่วันเดียวกับสองวันและดังนั้นอย่าซื้อครัวซองต์!

หลังจากการไตร่ตรองบางอย่าง (และอาจเป็นการทรมานเล็กน้อย P1 ดังนั้นเขาจึงคืนเงินให้ครัวซองต์ที่เขากินโดยไม่จ่ายเงิน) พวกเขาปรับเปลี่ยนอัลกอริทึมของพวกเขา

พวกเขาคำนวณราคาเฉลี่ยของครัวซองต์ที่พวกเขาจ่ายทุกวันและเรียกมันว่า v.

ในวันแรกพวกเขาคำนวณการวางแผนผู้ซื้อสำหรับวันต่อ ๆ ไป เมื่อต้องการทำเช่นนั้นพวกเขาจะทำเหมือนก่อนหน้ากับตัวแปรสุ่มและการปรับปรุงvik โดยราคาที่พวกเขาควรจะจ่ายในวันที่ kคือการเพิ่ม vทุกครั้งที่พวกเขาวางแผนที่จะไปทำขนมปัง เพราะพวกเขาฉลาดและพวกเขาไม่ต้องการจ่ายมากเกินไปพวกเขายังจำได้ว่าพวกเขาจ่ายเงินจริงๆเท่าไหร่ในแต่ละวันk ดังนั้นเมื่อพวกเขาจะอัพเดทการวางแผนจะไม่มีใครถูกลงโทษ

พวกเขาวางแผนจนกระทั่งทุกคน Pi มีวันที่ในอนาคตที่เขาควรซื้อครัวซองต์

ถ้า Pi มีแผนจะซื้อครัวซองต์ในวันที่ k+1 แต่ประกาศว่าเขาไม่สามารถในวันที่ k (หรือถ้าเขาไม่ได้อบอุ่น) เขาให้ที่อยู่กับใครบางคนที่ไม่มีภาระผูกพันในวันรุ่งขึ้นเช่น Pj และเขาจะเลี้ยวต่อไปของ Pj.

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

และเมื่อสิ่งนี้ดำเนินไปตลอดไปพวกเขามีความสุขและแบ่งปันราคาของครัวซองต์อย่างเท่าเทียมกัน

แต่ P1ไม่มีความสุข แน่นอนเขาคิดว่าเลือกlมีขนาดเล็กเกินไปและความน่าจะเป็นที่จะต้องจ่ายสองครั้งติดต่อกันใหญ่เกินไป อะไรก็ตาม ... คนอื่น ๆ ให้เขาเลือกlมีขนาดใหญ่เท่าที่เขาต้องการ เพราะเขาไม่พอใจ แต่ไม่ได้โง่เขาเลือกl=k เมื่อเวลาผ่านไปแม้ว่าอัตราส่วนระหว่างผู้จ่ายเงินรายใหญ่และผู้เล่นรายเล็กจะไม่ได้รับการพิจารณา l มักจะเน้นมัน

ยังคง P1 ไม่มีความสุขมากเขาอยู่ที่นั่นเพียงครึ่งเดียวของวัน (ดังนั้นครึ่งหนึ่งของครัวซองต์) และต้องจ่ายเท่าที่ P2ที่นี่ทุกวัน ที่ไม่เป็นธรรม!

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

Ps: ขออภัยสำหรับภาษาอังกฤษที่ไม่ดี แต่ฉันไม่ใช่เจ้าของภาษาและมันก็สาย ...โปรดอย่าลังเลที่จะแก้ไขข้อผิดพลาด (และอาจเพิ่มเครื่องเทศให้กับเรื่องราว ... )


2

ซ้ำทุกครั้งที่คุณมี

  • รายชื่อของคนที่มีอยู่และพร้อมที่จะซื้อ
  • ผู้ซื้อก่อนหน้านี้

หากคุณเลือกบุคคลโดยการสุ่มในหมู่คนในรายการและไม่รวมผู้ซื้อรายก่อนหน้านี้คุณจะบรรลุวัตถุประสงค์ของคุณ:

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

อัลกอริทึมอื่น ๆ ที่ฉันเคยเห็นมีการสุ่มน้อยหรือยุติธรรมน้อย:

  1. อัลกอริธึม "Deck shuffle" ไม่สุ่มอย่างแท้จริงในแง่ที่ความน่าจะเป็นที่จะต้องจ่ายไม่คงที่ (1 / N ในการเลือกครั้งแรก 1 / (N-1) ในครั้งที่สอง ... 1 ที่การเลือก Nth - - หากยังไม่มีใครเลือก) นอกจากนี้หากคุณเลือกก่อนคุณจะมีโอกาสเลือกเป็นศูนย์สำหรับ N ครั้งถัดไป ระบบแตกง่ายโดยการเข้ามาไม่ค่อยได้จนกว่าจะถูกเลือกและต่อเนื่องตลอดเวลา

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


กับ N คนและ m พนักงานปัจจุบันเฉลี่ยต่อวันส่วนเบี่ยงเบนในจำนวนครั้งจะประมาณ N/m. เนื่องจากการแก้ปัญหาอยู่ที่ไม่เคยเบี่ยงเบนมากกว่า1นี่คือคำจำกัดความที่แปลกประหลาดของ "ยุติธรรม" (โดยเฉพาะอย่างยิ่งเมื่อมันถูกระบุว่าเป็น "หลาย ๆ ครั้ง")
Rex Kerr

Nซื้อแน่นอนไม่ใช่คน
Rex Kerr

@RexKerr ทำไมคุณถึงซื้อครัวซองต์มากกว่าพนักงาน
Sklivvz

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