ฉันจะสร้างเครื่องกำเนิดไฟฟ้าแบบ "สุ่ม" ที่มีอคติกับเหตุการณ์ก่อนหน้าได้อย่างไร


37

ฉันกำลังมองหาที่จะใช้ระบบตามโอกาสซึ่งเป็นลำเอียงจากเหตุการณ์ก่อนหน้านี้

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

ระบบประเภทนี้ทำให้ฉันทึ่งมากในเวลานี้และตอนนี้ฉันอยู่ในสถานการณ์ที่ต้องการวิธีแก้ปัญหาดังกล่าว

นี่คือปัญหาของฉัน:

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

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

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


4
หากคุณต้องการคำตอบที่เหมาะสมยิ่งหรือมีความซับซ้อนคุณอาจมีคำถามเพิ่มเติมที่ Mathematics.SE นักคณิตศาสตร์มีความสะดวกสบายในการตอบคำถามที่ซับซ้อนเกี่ยวกับความน่าจะเป็น math.stackexchange.com
Kevin - Reinstate Monica


6
ทางเลือกในการเว็บไซต์คณิตศาสตร์ที่คุณต้องการมีแนวโน้มที่จะเข้าใจคำตอบคือProgrammers.SE การออกแบบอัลกอริทึมไม่ได้อยู่ในหัวข้อทางคณิตศาสตร์เป็นพิเศษและคุณอาจต้องมีการออกแบบเบื้องต้นเพื่อรับข้อมูลที่มีประโยชน์
Lilienthal

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

1
ในขณะที่ฉันใช้ตัวเลขในคำตอบบางข้อที่นี่ฉันพบว่ามีข้อ จำกัด ที่แตกต่างกันจำนวนมากและการแก้ปัญหาที่แก้ปัญหาทั้งหมดอาจทำให้ฉันซับซ้อนกว่าที่คุณต้องการ ข้อมูลเฉพาะเพิ่มเติมเกี่ยวกับกรณีการใช้งานของคุณอาจช่วย จำกัด ทางเลือกที่ดีที่สุด ตัวอย่างเช่นความน่าจะเป็นของกิจกรรมของคุณค่อนข้างใกล้เคียงกัน (เช่น 5 ผลลัพธ์ที่ต่างกันโดยมีโอกาส 20% ต่อครั้ง) หรือแตกต่างกันมาก (เช่น 10% พลาด 80% ถึง 10% วิกฤติ) คุณต้องการลดจำนวนการวิ่ง (เช่น. 3 ครั้งในหนึ่งแถว) หรือกลุ่ม / รอ (เช่น 3 พลาดจาก 8 ครั้งหรือ 20 ครั้งก่อนที่ฉันจะได้รับวิกฤติ)
DMGregory

คำตอบ:


19

โดยทั่วไปสิ่งที่คุณต้องการคือตัวสร้างเหตุการณ์แบบ "กึ่งสุ่ม" ที่สร้างเหตุการณ์ด้วยคุณสมบัติต่อไปนี้:

  1. อัตราเฉลี่ยที่แต่ละเหตุการณ์เกิดขึ้นระบุไว้ล่วงหน้า

  2. เหตุการณ์เดียวกันมีโอกาสเกิดขึ้นสองครั้งติดต่อกันน้อยกว่าที่จะสุ่ม

  3. เหตุการณ์ไม่สามารถคาดเดาได้ทั้งหมด

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


สำหรับเครื่องกำเนิดไฟฟ้าเหตุการณ์ที่ไม่สุ่มเราสามารถใช้ง่ายditheringอัลกอริทึม โดยเฉพาะให้p 1 , p 2 , ... , p nเป็นความน่าจะเป็นของเหตุการณ์ที่ 1 ถึงnและให้s = p 1 + p 2 + ... + p nเป็นผลรวมของน้ำหนัก จากนั้นเราสามารถสร้างลำดับเหตุการณ์ที่ไม่เท่าเทียมกันสูงสุดแบบสุ่มโดยใช้อัลกอริทึมต่อไปนี้:

  1. เริ่มแรกให้e 1 = e 2 = ... = e n = 0

  2. หากต้องการสร้างเหตุการณ์ให้เพิ่มแต่ละe iด้วยp iและเอาท์พุทเหตุการณ์kที่e kใหญ่ที่สุด (แบ่งความสัมพันธ์ในแบบที่คุณต้องการ)

  3. ลดe k by sและทำซ้ำจากขั้นตอนที่ 2

ตัวอย่างเช่นเมื่อได้รับสามเหตุการณ์ A, B และ C ด้วยp A = 5, p B = 4 และp C = 1 อัลกอริทึมนี้จะสร้างสิ่งที่คล้ายกับลำดับของผลลัพธ์ต่อไปนี้:

A B A B C A B A B A A B A B C A B A B A A B A B C A B A B A

ขอให้สังเกตว่าลำดับเหตุการณ์ 30 เหตุการณ์นี้ประกอบด้วย 15 As, 12 Bs และ 3 Cs อย่างไร มันไม่ได้ค่อนข้างดีที่สุดจำหน่าย - มีเกิดขึ้นเพียงไม่กี่แห่งที่สองในขณะที่แถวซึ่งจะได้รับการหลีกเลี่ยง - แต่จะได้รับใกล้


ตอนนี้ในการเพิ่มการสุ่มให้กับลำดับนี้คุณมีตัวเลือก (ไม่จำเป็นต้องไม่เกิดร่วมกัน):

  • คุณสามารถทำตามคำแนะนำของ Philippและรักษา "สำรับ" ของเหตุการณ์ที่จะมาถึงNสำหรับหมายเลขN ที่เหมาะสม ทุกครั้งที่คุณต้องการสร้างเหตุการณ์คุณเลือกสุ่มเหตุการณ์จากเด็คแล้วแทนที่ด้วยเอาท์พุตเหตุการณ์ถัดไปโดยอัลกอริธึมการทำ dithering ด้านบน

    การใช้สิ่งนี้กับตัวอย่างด้านบนด้วยN = 3 ก่อให้เกิดเช่น:

    A B A B C A B B A B A B C A A A A B B A B A C A B A B A B A

    ในขณะที่N = 10 ให้ผลที่ดูสุ่มมากกว่า:

    A A B A C A A B B B A A A A A A C B A B A A B A C A C B B B

    สังเกตว่าเหตุการณ์ทั่วไป A และ B จบลงด้วยการวิ่งมากขึ้นเนื่องจากการสับในขณะที่เหตุการณ์ C ที่หายากยังคงอยู่ในระยะที่ค่อนข้างดี

  • คุณสามารถฉีดสุ่มลงในอัลกอริทึม dithering โดยตรง ตัวอย่างเช่นแทนที่จะเพิ่มe iโดยp iในขั้นตอนที่ 2 คุณสามารถเพิ่มได้โดยp i × random (0, 2) โดยที่ random ( a , b ) คือการสุ่มตัวเลขที่กระจายอย่างสม่ำเสมอระหว่างaและb ; นี้จะให้ผลผลิตเช่นต่อไปนี้:

    A B B C A B A A B A A B A B A A B A A A B C A B A B A C A B

    หรือคุณสามารถเพิ่มe iโดยp i + สุ่ม (- c , c ) ซึ่งจะสร้าง (สำหรับc = 0.1 × s ):

    B A A B C A B A B A B A B A C A B A B A B A A B C A B A B A

    หรือสำหรับc = 0.5 × s :

    B A B A B A C A B A B A A C B C A A B C B A B B A B A B C A

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

  • หรือคุณสามารถรบกวนเอาท์พุทของอัลกอริทึมการทำ dithering โดยบางครั้งการแทนที่เหตุการณ์k ที่เลือกด้วยการสุ่ม (เลือกตามน้ำหนักดิบp i ) ตราบใดที่คุณยังใช้kเดียวกันในขั้นตอนที่ 3 ในขณะที่คุณส่งออกในขั้นตอนที่ 2 กระบวนการ dithering จะยังคงมีความผันผวนแบบสุ่ม

    ตัวอย่างเช่นนี่คือตัวอย่างผลลัพธ์ที่มีโอกาส 10% ของแต่ละเหตุการณ์ที่ถูกสุ่มเลือก:

    B A C A B A B A C B A A B B A B A B A B C B A B A B C A B A

    และนี่คือตัวอย่างที่มีโอกาส 50% ของแต่ละเอาต์พุตเป็นแบบสุ่ม:

    C B A B A C A B B B A A B A A A A A B B A C C A B B A B B C

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

ps ต่อไปนี้คือลำดับเหตุการณ์ที่สุ่มสมบูรณ์ซึ่งมีอัตราเฉลี่ยเดียวกันสำหรับการเปรียบเทียบ:

A C A A C A B B A A A A B B C B A B B A B A B A A A A A A A
B C B A B C B A A B C A B A B C B A B A A A A B B B B B B B
C A A B A A B B C B B B A B A B A A B A A B A B A C A A B A

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

พล็อต
พล็อตของกลยุทธ์หลายประการในการสร้างการพลิกเหรียญแบบกึ่งสุ่ม (โดยมีอัตราส่วน 50:50 ต่อหัวต่อหางโดยเฉลี่ย) แกนนอนคือจำนวนของการโยนแกนในแนวตั้งคือระยะทางสะสมจากอัตราส่วนที่คาดไว้วัดเป็น (หัว - ก้อย) / 2 = หัว - พลิก / 2

เส้นสีแดงและสีเขียวบนเนื้อเรื่องแสดงอัลกอริธึมที่ไม่ขึ้นกับสำรับสองแบบสำหรับการเปรียบเทียบ:

  • เส้นสีแดง, สิ่งที่กำหนดขึ้นอย่างชัดเจน : ผลลัพธ์ที่มีเลขคู่มักเป็นหัวเสมอ, ผลลัพธ์เลขคี่จะเป็นแบบก้อยเสมอ
  • สายสีเขียวการสุ่มแบบสุ่มอิสระ : แต่ละผลลัพธ์จะถูกเลือกแบบสุ่มโดยมีโอกาส 50% ที่จะมีหัวและโอกาส 50% ที่จะก้อย

อีกสามบรรทัด (สีฟ้าสีม่วงและสีฟ้า) แสดงผลลัพธ์ของกลยุทธ์ที่ใช้สำรับสามสำรับดำเนินการโดยใช้ไพ่ 40 ใบซึ่งในตอนแรกจะเต็มไปด้วยไพ่ "หัว" 20 ใบและไพ่ "หาง" 20 ใบ:

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

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

(ในความเป็นจริงการเบี่ยงเบนของเส้นสีน้ำเงินสีม่วงและสีฟ้าห่างจากศูนย์จะถูก จำกัด ด้วยขนาดของเด็คอย่างเคร่งครัด: เส้นสีน้ำเงินไม่สามารถลอยห่างจากศูนย์ได้เกินกว่า 10 ขั้นตอนสายสีม่วงจะได้ 15 ก้าวจากศูนย์ และเส้นสีฟ้าสามารถลอยห่างออกไปไม่เกิน 20 ขั้นตอนแน่นอนในทางปฏิบัติเส้นใด ๆ ที่ถึงขีด จำกัด จริง ๆ แล้วไม่น่าเป็นไปได้อย่างยิ่งเนื่องจากมีแนวโน้มที่แข็งแกร่งสำหรับพวกเขาที่จะกลับเข้าใกล้ศูนย์หากพวกเขาเดินไกลเกินไป ปิด.)

ไม่มีความแตกต่างที่เห็นได้ชัดระหว่างกลยุทธ์บนดาดฟ้าที่แตกต่างกัน (แม้ว่าโดยเฉลี่ยแล้วเส้นสีน้ำเงินจะอยู่ใกล้กับเส้นสีแดงค่อนข้างมากและเส้นสีฟ้ายังคงอยู่ไกลออกไป) แต่การตรวจสอบเส้นสีน้ำเงินอย่างใกล้ชิดยิ่งขึ้น ไม่เปิดเผยรูปแบบการกำหนดที่แตกต่าง: ทุก ๆ 40 การวาด (ทำเครื่องหมายด้วยเส้นแนวตั้งสีเทาประ) เส้นสีน้ำเงินตรงตามเส้นสีแดงที่ศูนย์ทุกประการ เส้นสีม่วงและสีฟ้าไม่ได้ถูก จำกัด อย่างเข้มงวดและสามารถอยู่ห่างจากศูนย์ได้ทุกเวลา

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


คำตอบที่ซับซ้อนมาก การเพิ่มปัจจัยสุ่มลงไปในอัลกอริธึมการทำ dithering นั้นดูเหมือนตรงไปตรงมา :)
Sonaten

ตัดสินใจที่จะไปกับคำตอบของคุณ :) แต่ฉันขอแนะนำให้คุณใส่ส่วนเพิ่มเติมของภาพรวมวิธีการที่ด้านบน สิ่งที่ฉันจะทำตามคำตอบของคุณคือลองทั้งโซลูชัน "สีแดง" และ "สีม่วง"
Sonaten

53

อย่าทอยลูกเต๋าแจกไพ่

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

ผลลัพธ์จะยังคงถูกกระจายอย่างสม่ำเสมอ แต่ผลลัพธ์แต่ละรายการจะไม่ทำซ้ำเว้นแต่ว่ารายการสุดท้ายจะเกิดขึ้นเป็นครั้งแรกของรายการถัดไป

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


1
ค้นหา "ถุงสับเปลี่ยน" (บนเว็บไซต์นี้)
jhocking

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

2
@DMGregory: ที่จริงแล้วมันเป็นเรื่องที่สมบูรณ์แบบที่จะผสมในการ์ดใหม่ก่อนที่เด็คจะว่างเปล่า (และอันที่จริงฉันแนะนำให้ทำแบบนี้เพื่อให้ได้ผลลัพธ์ที่เป็นธรรมชาติและยากต่อการคาดเดา) สิ่งสำคัญคือการทำให้แน่ใจว่าเศษส่วน (เฉลี่ย) ของไพ่ใหม่ที่สับเข้าไปในสำรับเท่ากับเศษส่วนที่ต้องการที่คุณต้องการดึงออกจากมัน
Ilmari Karonen

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

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

17

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

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

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

ตัวอย่างเช่นหากคุณมีสามเหตุการณ์:

  Critical, P = 0.1
  Hit,      P = 0.3
  Miss,     P = 0.6

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

  Critical -> Critical,   P = 0.0
  Critical -> Hit,        P = 0.35
  Critical -> Miss,       P = 0.65

แก้ไข: ตามความเห็นที่กล่าวด้านล่างโมเดลนี้ไม่ซับซ้อนพอที่จะรับพฤติกรรมที่ต้องการ คุณอาจต้องเพิ่มสถานะเพิ่มเติมหลายรัฐแทน!


1
แบบแผนการทำให้หนักที่คุณเสนอไม่ได้รักษาความน่าจะเป็นที่ต้องการของแต่ละรัฐ ทำแบบทดสอบเชิงประจักษ์กับตัวเลขเหล่านี้คิดถึงเกิดขึ้นประมาณ 41% ของเวลาและที่สำคัญเกี่ยวกับ 25% วิธีออกจากค่าอินพุต การเปลี่ยนไปยังสถานะที่เหลือตามสัดส่วนของความน่าจะเป็น (เช่นนางสาวมีโอกาส 25% ที่จะไป Crit และโอกาส 75% ที่จะไปโจมตี) ทำได้ดีกว่าเล็กน้อยโดยมีอัตราพลาด 44% และ 17% crit แต่ก็ยัง ไม่สะท้อนความน่าจะเป็นที่ต้องการในอินพุต
DMGregory

ฉันลืมกฎ Bayes :( จะคำนวณใหม่อีกครั้งในภายหลังมันอาจเป็นไปไม่ได้ที่จะรักษาการกระจายความน่าจะเป็นก่อนหน้านี้เนื่องจากโมเดลการเปลี่ยนแปลงเนื่องจากแยกลำดับที่เป็นไปได้ออกเช่น CCHM หรือ CHHM หรือ MMHM ที่มีโอกาสมาก ฯลฯ
mklingen

ข้อ จำกัด "ไม่ซ้ำ" อาจผูกมือของคุณไว้ที่นี่โดยคำนึงถึงน้ำหนักสูงและต่ำมาก หากคุณต้องการให้ 1 ใน 10 ครั้งจะเป็นจุดวิกฤติวิธีเดียวที่วิธีนี้สามารถทำได้คือการสลับ 5 Misses & 5 Hit ซึ่งบิดเบือนความน่าจะเป็นของ Hit & Miss ไปทางค่าเฉลี่ย ไม่มีลำดับที่ไม่มีการขาดหายไปติดต่อกันสามารถสนองความต้องการของอินพุตได้
DMGregory

4
@ mklingen ฉันเห็นด้วยกับ DMGregory "ไม่ซ้ำอย่างเคร่งครัด" ไม่ต้องการที่นี่ แต่พวกเขาต้องการความน่าจะเป็นของโซ่ยาวของผลลัพธ์เดียวกันที่จะมีโอกาสน้อยกว่าที่มันน่าจะเป็นกับความน่าจะเป็นแบบสุ่ม คุณสามารถทำเช่นนี้กับห่วงโซ่มาร์คอฟ (ซึ่งเป็นผู้กำกับ) ที่มีลักษณะเช่นนี้ สิ่งนี้ใช้หลายสถานะเพื่อแสดงเหตุการณ์ซ้ำ ๆ ซึ่งความน่าจะเป็นของการเปลี่ยนจาก "Hit 1" เป็น "Hit 2" และ "Hit 2" เป็น "Hit 3+" จะลดลงและความน่าจะเป็นของการเปลี่ยนกลับเป็น "Hit 1" และ "Crit 1 "ขึ้นไป
nwellcome

@nwellcome เป็นความคิดที่ดี
mklingen

3

นี่คือการใช้งานที่ฉันสร้างใน C # ซึ่งจะ:

  • เปิดใช้งานกิจกรรมตามความน่าจะเป็น
  • ปรับความน่าจะเป็นเหล่านั้นเพื่อลดโอกาสเกิดเหตุการณ์ซ้ำ
  • ไม่หลงทางไกลเกินไปจากความน่าจะเป็นดั้งเดิม

ฉันได้เพิ่มความคิดเห็นเล็กน้อยเพื่อให้คุณสามารถเห็นสิ่งที่ฉันทำ

    int percentageEvent1 = 15; //These are the starter values. So given a scenario, the
    int percentageEvent2 = 40; //player would have around a 15 percent chance of event
    int percentageEvent3 = 10; //one occuring, a 40 percent chance of event two occuring
    int percentageEvent4 = 35; //10 percent for event three, and 35 percent for event four.

    private void ResetValues()
    {
        percentageEvent1 = 15;
        percentageEvent2 = 40;
        percentageEvent3 = 10;
        percentageEvent4 = 35;
    }

    int resetCount = 0; //Reset the probabilities every so often so that they don't stray too far.

    int variability = 1; //This influences how much the chance of an event will increase or decrease
                           //based off of past events.

    Random RandomNumberGenerator = new Random();

    private void Activate() //When this is called, an "Event" will be activated based off of current probability.
    {
        int[] percent = new int[100];
        for (int i = 0; i < 100; i++) //Generate an array of 100 items, and select a random event from it.
        {
            if (i < percentageEvent1)
            {
                percent[i] = 1; //Event 1
            }
            else if (i < percentageEvent1 + percentageEvent2)
            {
                percent[i] = 2; //Event 2
            }
            else if (i < percentageEvent1 + percentageEvent2 + percentageEvent3)
            {
                percent[i] = 3; //Event 3
            }
            else
            {
                percent[i] = 4; //Event 4
            }
        }
        int SelectEvent = percent[RandomNumberGenerator.Next(0, 100)]; //Select a random event based on current probability.

        if (SelectEvent == 1)
        {
            if (!(percentageEvent1 - (3 * variability) < 1)) //Make sure that no matter what, probability for a certain event
            {                                                //does not go below one percent.
                percentageEvent1 -= 3 * variability;
                percentageEvent2 += variability;
                percentageEvent3 += variability;
                percentageEvent4 += variability;
            }
        }
        else if (SelectEvent == 2)
        {
            if (!(percentageEvent2 - (3 * variability) < 1))
            {
                percentageEvent2 -= 3 * variability;
                percentageEvent1 += variability;
                percentageEvent3 += variability;
                percentageEvent4 += variability;
            }
        }
        else if (SelectEvent == 3)
        {
            if (!(percentageEvent3 - (3 * variability) < 1))
            {
                percentageEvent3 -= 3 * variability;
                percentageEvent1 += variability;
                percentageEvent2 += variability;
                percentageEvent4 += variability;
            }
        }
        else
        {
            if (!(percentageEvent4 - (3 * variability) < 1))
            {
                percentageEvent4 -= 3 * variability;
                percentageEvent1 += variability;
                percentageEvent2 += variability;
                percentageEvent3 += variability;
            }
        }

        resetCount++;
        if (resetCount == 10)
        {
            resetCount = 0;
            ResetValues();
        }

        RunEvent(SelectEvent); //Run the event that was selected.
    }

หวังว่านี่จะช่วยได้โปรดแนะนำการปรับปรุงรหัสนี้ในความคิดเห็นขอบคุณ!


1
โครงร่างการ reweighting นี้มีแนวโน้มที่จะนำเหตุการณ์ไปสู่การสวมใส่ได้ การรีเซ็ตตุ้มน้ำหนักเป็นระยะ ๆ เป็นเพียงเครื่องช่วยรัดที่ จำกัด การรับน้ำหนักในขณะที่มั่นใจว่า 1 ใน 10 ม้วนจะไม่ได้รับประโยชน์ใด ๆ จากการปรับน้ำหนัก นอกจากนี้อัลกอริทึมหนึ่งหมายเหตุ: คุณกำลังเสียงานมากโดยการกรอกตาราง 100 รายการเพื่อทำการเลือกแบบสุ่มของคุณ แต่คุณสามารถสร้างการหมุนแบบสุ่มจากนั้นวนซ้ำ 4 ผลลัพธ์โดยรวมความน่าจะเป็นของพวกเขาไปด้วย ทันทีที่ม้วนน้อยกว่าผลรวมคุณก็จะได้ผลลัพธ์ ไม่จำเป็นต้องกรอกตาราง
DMGregory

3

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

บอกว่ามีnเหตุการณ์ที่เป็นไปได้ที่มีความน่าจะp_1, p_2, ..., p_nเป็น เมื่อเหตุการณ์iเกิดขึ้นความน่าจะเป็นของมันจะลดลงด้วยปัจจัย0≤a_i≤1/p_i(สิ่งหลังมีความสำคัญมิฉะนั้นคุณจะต้องมีความน่าจะเป็นที่มากกว่าหนึ่งและเหตุการณ์อื่น ๆ จะต้องมีความน่าจะเป็นเชิงลบซึ่งโดยทั่วไปหมายถึง " ต่อต้าน " a_i<1เป็นปกติ ตัวอย่างเช่นคุณสามารถเลือกa_i=p_iได้ซึ่งหมายถึงความน่าจะเป็นของเหตุการณ์ที่เกิดขึ้นในครั้งที่สองคือความน่าจะเป็นแบบดั้งเดิมเหตุการณ์ที่เกิดขึ้นอย่างแม่นยำสองครั้งในแถวเช่นการโยนเหรียญที่สองจะมีความน่าจะเป็น 1/4 แทน 1/2 ในอีกทางหนึ่งคุณสามารถมีบางอย่างa_i>1ซึ่งจะหมายถึงการเรียก "จังหวะของโชค / ความโชคร้าย"

เหตุการณ์อื่น ๆ ทั้งหมดจะยังคงมีความเป็นไปได้อย่างเท่าเทียมกันเมื่อเทียบกับอีกเหตุการณ์หนึ่งนั่นคือทั้งหมดจะต้องได้รับการช่วยเหลือจากปัจจัยเดียวกันb_iเช่นผลรวมของความน่าจะเป็นทั้งหมดเท่ากับหนึ่งเช่น

1 = a_i*p_i + b_i*(1-p_i)  # Σ_{j≠i) p_j  = 1 - p_i
 b_i = (1 - a_i*p_i) / (1 - p_i).   (1)

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

ปล่อย

        / p_i * b_i * p_j  (ji)
p_ij = <
        \ a_i * (p_i     (j=i)

แสดงความน่าจะเป็นของเหตุการณ์ที่jเกิดขึ้นหลังจากเหตุการณ์iและทราบว่าp_ij≠p_jiเว้นแต่b_i=b_j (2)(ซึ่งโดย(1)นัยa_j = 1 - a_i*p_i + (1-a_i)*p_i/p_j) นี่ก็เป็นสิ่งที่ทฤษฎีบทของเบย์ต้องการและสิ่งนี้ก็มีความหมายเช่นกัน

Σ_j p_ij = p_i * b_i * (1 - p_i) + a_i * (p_i
         = b_i * p_i + (a_i - b_i) * (p_i
         = p_i  # using (1)

ตามที่ต้องการ เพียงแค่สังเกตว่าสิ่งนี้หมายถึงวิธีหนึ่งa_iแก้ไขทั้งหมดอื่น ๆ


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

a) ลืมเหตุการณ์แรกและแท่นขุดน้ำมันราวกับว่ามีเหตุการณ์ที่สองเกิดขึ้นเช่น

         / p_ij * a_j * p_j  (j=k)
p_ijk = <
         \ p_ij * b_j * p_l  (jk)

โปรดทราบว่าสิ่งนี้มักละเมิดเบย์เนื่องจากเช่นp_jik≠p_ikjในกรณีส่วนใหญ่

b) ใช้ใช้ความน่าจะเป็นp_ij(สำหรับการแก้ไขi) เป็นความน่าจะเป็นใหม่pi_jที่คุณได้รับความน่าจะเป็นใหม่pi_jkสำหรับเหตุการณ์ที่kจะเกิดขึ้นต่อไป ไม่ว่าคุณจะปรับเปลี่ยนai_jหรือไม่ขึ้นอยู่กับคุณ แต่ทราบว่าใหม่เป็นมั่นเหมาะที่แตกต่างกันเนื่องจากการปรับเปลี่ยนbi_j pi_jจากนั้นอีกครั้งตัวเลือกของai_jอาจถูก จำกัด โดยกำหนดให้พีชคณิตทั้งหมดที่ijkเกิดขึ้นด้วยความน่าจะเป็นเดียวกัน มาดูกัน...

         / p_ij * bi_j * pi_k  (jk)
p_ijk = <
         \ (p_ij * ai_j      (j=k)

         / b_i * bi_j * p_i * p_j * pi_k  (ijki)
         | b_i * ai_j * p_i * (p_j      (ij=k)
      = <  a_i * (p_i * bi_i * pi_k     (i=jk)
         | b_i * p_i * bi_j * p_k * pi_i  (i=kj)
         \ a_i * ai_i * (p_i * pi_i     (i=k=j)

และการเรียงสับเปลี่ยนแบบวนรอบซึ่งจะต้องเท่ากันในแต่ละกรณี

ฉันเกรงว่าการดำเนินการต่อของฉันจะต้องรอสักครู่ ...


การทดสอบสังเกตุนี้ยังคงส่งผลให้เกิดความผิดเพี้ยนจากความน่าจะเป็นที่ป้อนเข้าของการทำงานหลายอย่าง หาก a_i / p_i = 0.5 เช่น (และใช้ตัวเลขจากคำตอบของ mklingen) อัตราการพลาดอินพุต 60% จะกลายเป็นอัตราที่สังเกตได้ที่ 50.1% และอัตราการวิกฤติของอินพุต 10% นั้น 13.8% คุณสามารถตรวจสอบสิ่งนี้ได้โดยนำเมทริกซ์การเปลี่ยนแปลงที่เกิดขึ้นไปสู่พลังงานสูง การเลือกอัตราส่วนของ a_i: p_i ใกล้เคียงกับ 1 จะทำให้เกิดความผิดเพี้ยนน้อยลง แต่ยังลดประสิทธิภาพในการลดการไหล
DMGregory

@DMGregory ข้อดี: คุณไม่สามารถรับพลังของเมทริกซ์การเปลี่ยนแปลงได้ ฉันจะขยายคำตอบของฉันในภายหลังว่า
Tobias Kienzler

@DMGregory ฉันเริ่มอธิบายกระบวนการเต็มรูปแบบ (ตัวแปร b)) แต่มันค่อนข้างน่าเบื่อและตอนนี้ฉันก็ตรงเวลา: /
Tobias Kienzler

1

ฉันคิดว่าตัวเลือกที่ดีที่สุดคือการใช้การเลือกรายการแบบถ่วงน้ำหนัก มีการนำไปใช้งานสำหรับ C # ที่นี่แต่สามารถพบหรือสร้างขึ้นได้อย่างง่ายดายสำหรับภาษาอื่นเช่นกัน

แนวคิดจะลดน้ำหนักตัวเลือกทุกครั้งที่เลือกและเพิ่มขึ้นทุกครั้งที่ไม่ได้เลือก

ตัวอย่างเช่นหากคุณลดน้ำหนักของตัวเลือกที่เลือกโดยNumOptions-1และเพิ่มน้ำหนักของตัวเลือกอื่น ๆ ทั้งหมด 1 (ระมัดระวังในการลบรายการที่มีน้ำหนัก <0 และอ่านพวกเขาเมื่อพวกเขาสูงกว่า 0)ทุกตัวเลือกจะถูกเลือกโดยประมาณ จำนวนครั้งเท่ากันในช่วงเวลานาน แต่ตัวเลือกที่เพิ่งถูกเลือกจะมีโอกาสน้อยกว่ามากที่จะเลือก


ปัญหาเกี่ยวกับการใช้การเรียงลำดับแบบสุ่มตามที่แนะนำโดยคำตอบอื่น ๆ อีกมากมายคือหลังจากทุกตัวเลือก แต่ได้ถูกเลือกแล้วคุณสามารถคาดเดาได้ด้วยความมั่นใจ 100% ตัวเลือกใดจะถูกเลือกถัดไป มันไม่ได้สุ่มมาก


1

คำตอบของฉันไม่ถูกต้องการทดสอบของฉันมีข้อบกพร่อง

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

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

วิธีที่ง่ายที่สุดที่จะบรรลุนี้คือการเปลี่ยนแปลงของน้ำหนักทั้งหมดสำหรับแต่ละม้วนโดยการลดน้ำหนักสำหรับค่าเฉพาะรีดและเพิ่มน้ำหนักอื่น

ตัวอย่างเช่นสมมติว่าคุณมีน้ำหนัก 4 อย่าง: คลำ, มิส, Hit และ Crit ให้บอกว่าน้ำหนักโดยรวมที่คุณต้องการสำหรับพวกเขาคือ Fumble = 10%, Miss = 50%, Hit = 30% และ Crit = 10%

หากคุณใช้ตัวสร้างตัวเลขสุ่ม (RNG) เพื่อสร้างค่าระหว่าง 1 ถึง 100 แล้วเปรียบเทียบค่านั้นกับที่มันอยู่ภายในช่วงนี้ (1-10 Fumble, 11-60 miss, 61-60 hit, 91-100 crit ) คุณกำลังสร้างการหมุนของแต่ละบุคคล

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

หากคุณทำเช่นนี้สำหรับแต่ละม้วนคุณจะยังคงมีโอกาสเกิดริ้ว แต่พวกเขาจะลดลงอย่างมากเพราะสำหรับแต่ละม้วนคุณเพิ่มโอกาสที่ม้วนอนาคตจะเป็นอย่างอื่นนอกเหนือจากม้วนปัจจุบัน คุณสามารถเพิ่มเอฟเฟกต์นี้และลดโอกาสที่จะเกิดริ้วรอยโดยการเพิ่ม / ลดน้ำหนักด้วยปัจจัยที่มากขึ้น (เช่นลดกระแส 6 และเพิ่มอีก 2)

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

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

โปรดทราบว่าตัวอย่างนี้ผลิตโดยใช้. NET System.Random class ซึ่งไม่ใช่ RNG ที่ดีกว่าตัวใดตัวหนึ่งในนั้นดังนั้นคุณอาจได้ผลลัพธ์ที่แม่นยำมากขึ้นโดยใช้ RNG ที่ดีกว่า โปรดทราบว่า 32000 เป็นผลลัพธ์สูงสุดที่ฉันสามารถสร้างกราฟด้วยเครื่องมือนี้ได้ แต่เครื่องมือทดสอบของฉันสามารถสร้างผลลัพธ์มากกว่า 500 ล้านรายการที่มีรูปแบบโดยรวมเหมือนกัน


โปรดทราบว่าจะใช้งานได้ก็ต่อเมื่อ +1 ของคุณถูกนำไปใช้เทียบกับน้ำหนักเดิมแทนที่จะเป็นน้ำหนักที่ใช้ล่าสุด (การปรับเปลี่ยนน้ำหนักอย่างสม่ำเสมออย่างต่อเนื่องเช่นนี้ทำให้พวกมันล่องลอยไปสู่การสวมใส่ได้) ในขณะที่สิ่งนี้คงความน่าจะเป็นที่เป้าหมายไว้ในระยะยาว แต่ก็มีน้อยมากที่จะลดการวิ่ง ระบุว่าฉันพลาดครั้งเดียวโอกาสที่ฉันจะพลาดอีกสองครั้งติดต่อกันคือ 22% กับโครงการนี้เทียบกับ 25% ที่มีการจับฉลากอิสระ การเพิ่มการเปลี่ยนน้ำหนักสำหรับเอฟเฟกต์ที่ใหญ่กว่า (พูดกับ + 3 / -9) จะทำให้ความน่าจะเป็นระยะยาวเพิ่มขึ้น
DMGregory

จริง ๆ แล้วข้อมูลที่นำเสนอข้างต้นใช้ + 1 / -3 กับน้ำหนักล่าสุดทุกครั้งที่มีการประมวลผลม้วน ดังนั้นหากคุณพลาดครั้งแรกที่น้ำหนัก 50% ครั้งแรกน้ำหนักต่อไปจะเป็น 47% และหากคุณพลาดอีกครั้งน้ำหนักต่อไปนี้จะเป็น 44% และอื่น ๆ มันลดการวิ่ง (ตัวชี้วัดที่แยกต่างหากคือการติดตามการวิ่งพบมากเท่ากับการลดลง 24% ในการวิ่ง) แต่พวกเขาก็ยังคงหลีกเลี่ยงไม่ได้เนื่องจากโครงการนี้ยังคงมีโอกาสที่แข็งแกร่งในการออกจากน้ำหนักแต่ละ 4 เช่นสี่ crits ต่อเนื่องจะทำให้น้ำหนักของ crit นั้นไม่มีโอกาสเกิดขึ้น)
David C Ellis

หากนั่นคือเจตนาของคุณการดำเนินการของคุณจะมีข้อผิดพลาด ดูกราฟ - น้ำหนักคลำหาจะตีกลับระหว่าง 7 ถึง 11 เท่านั้นโดยไม่มีค่าใด ๆ เลย ฉันใช้การจำลองโดยใช้การดัดแปลงอย่างต่อเนื่องที่คุณอธิบายและกราฟมีความแตกต่างกันอย่างมากโดยความน่าจะเป็นของแต่ละรัฐรวมกันเป็น 25% ในแต่ละการทดลองร้อยครั้งแรก
DMGregory

Dangit จริง ๆ แล้วมันก็บั๊กเมื่อคุณชี้ให้เห็น ตอบคำถามนี้
David C Ellis

@DavidCEllis คุณกำลังบอกว่าการดำเนินการของคุณมีข้อบกพร่องหรือความคิดของตัวเองคืออะไร? สัญชาตญาณด้านหลังของฉันมาจากแบบจำลองที่คุณอธิบายคร่าวๆ (ปรับความน่าจะเป็นลงเมื่อวาดแล้วค่อยคืนค่าความน่าจะเป็นทั้งหมดกลับคืนสู่ค่าดั้งเดิมเมื่อเวลาผ่านไป) และมันก็สมเหตุสมผลสำหรับฉัน
dimo414

0

คุณสามารถทำสิ่งที่เป็นตัวกรองเป็นหลัก ติดตามเหตุการณ์ที่ผ่านมา n ความน่าจะเป็นคือตัวกรองบางตัวที่ใช้กับเหตุการณ์เหล่านั้น ตัวกรองที่ 0 คือความน่าจะเป็นพื้นฐานถ้าเป็น 0 คุณจะหลบถ้าคุณล้มเหลว สมมุติว่าฐานเป็น 25% และตัวกรองลดลงครึ่งหนึ่งโดยการทำซ้ำแต่ละครั้ง ตัวกรองของคุณจะเป็น:

[.25 .125 .0625 .03125] 

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

x=p+(1-x)*(p/2+p/4+p/8)

แก้สำหรับ x หนึ่งที่พบว่าคำตอบคือหรือสำหรับกรณีที่ได้รับของเราp(1+1/2+1/4+1/8)/(1+p(1/2+1/4+1/8) x=0.38461538461แต่สิ่งที่คุณต้องการคือการหา p ให้ x กลายเป็นปัญหาที่ยากขึ้นไปอีก หากคุณสันนิษฐานตัวกรองอนันต์จะกลายเป็นปัญหาหรือx+x*p=2*p p=x/(2-x)ดังนั้นการเพิ่มตัวกรองของคุณคุณสามารถแก้ไขตัวเลข p ซึ่งโดยเฉลี่ยแล้วจะให้ผลลัพธ์ที่เหมือนกัน แต่ในอัตราที่ขึ้นอยู่กับความสำเร็จที่เพิ่งเกิดขึ้น

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


-1

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

นี่คือการดำเนินการนี้ใน Java

import java.util.Map;
import java.util.Random;

/**
 * A psuedorandom weighted outcome generator
 * @param <E> object type to return
 */
public class WeightedRandom<E> {

    private Random random;
    private Map<E, Double> weights;

    public WeightedRandom(Map<E, Double> weights) {
        this.random = new Random();
        this.weights = weights;
    }

    /**
     * Returns a random outcome based on the weight of the outcomes
     * @return
     */
    public E nextOutcome() {
        double totalweight = 0;

        // determine the total weigth
        for (double w : weights.values()) totalweight += w;

        // determine a value between 0.0 and the total weight
        double remaining = random.nextDouble() * totalweight;

        for (E entry : weights.keySet()) {
            // subtract the weight of this entry
            remaining -= weights.get(entry);

            // if the remaining is smaller than 0, return this entry
            if (remaining <= 0) return entry;
        }

        return null;
    }

    /**
     * Returns the weight of an outcome
     * @param outcome the outcome to query
     * @return the weight of the outcome, if it exists
     */
    public double getWeight(E outcome) {
        return weights.get(outcome);
    }

    /**
     * Sets the weight of an outcome
     * @param outcome the outcome to change
     * @param weight the new weigth
     */
    public void setWeight(E outcome, double weight) {
        weights.put(outcome, weight);
    }
}

แก้ไข ในกรณีที่คุณต้องการปรับน้ำหนักโดยอัตโนมัติตัวอย่างเช่นเพิ่มโอกาสของ A เมื่อผลลัพธ์คือ B คุณสามารถ

  1. เปลี่ยนพฤติกรรมของnextOutcome()วิธีการดังนั้นจึงปรับเปลี่ยนน้ำหนักตามผล
  2. ใช้setWeight()เพื่อปรับเปลี่ยนน้ำหนักของตามผล

ฉันคิดว่าคุณอาจเข้าใจผิดคำถาม: OP ไม่ได้ถามว่าจะสร้างผลลัพธ์แบบสุ่มถ่วงน้ำหนักได้อย่างไร แต่จะปรับน้ำหนักอย่างไรเพื่อลดโอกาสในการเกิดผลลัพธ์เดียวกันหลายครั้งติดต่อกัน
Ilmari Karonen

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