ตัวเลขสุ่มบน C ++


12

เมื่อเร็ว ๆ นี้ฉันคุ้นเคยกับภาษาสมัยใหม่ซึ่งรวมถึงตัวสร้างแบบสุ่มที่ดีซึ่งมักจะเป็น Mersenne Twister; ตอนนี้ฉันกลับไปที่ C ++ ฉันต้องตัดสินใจว่าจะใช้อะไร

ฉันค้นหาการใช้งานของ Mersenne Twister และฉันสังเกตเห็นว่ามีอยู่มากมาย: มีสิ่งหนึ่งที่ใช้กันอย่างแพร่หลายและแพร่หลายกว่าหรือฉันควรจะเลือกอย่างใดอย่างหนึ่งโดยสมมติว่าพวกเขาทั้งหมดดีพอ ๆ กัน?


1
ฉันชอบภาษา C ++ และภาษาสมัยใหม่ของคุณ
jcora

2
อาจจะพูดว่า "ระดับที่สูงขึ้น" นั้นเหมาะสมกว่า
o0 '

ฉันคิดว่าคำถามนี้เป็นของ stackoverflow
TravisG

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

คำตอบ:


19

C ++ 11 มีตัวสร้าง Mersenne Twister เป็นค่าเริ่มต้นซึ่งเป็นส่วนหนึ่งของ<random>อินเทอร์เฟซใหม่ ตัวอย่างเช่นในการสร้างจำนวนเต็มอย่างสม่ำเสมอระหว่าง [-10, 10] โดยใช้ MT:

std::mt19937 eng; // This is the Mersenne Twister
std:::uniform_int_distribution<int> dist(-10, 10)
for (int i = 0; i < 10; ++i)
    std::cout << dist(eng) << std::endl;

ส่วนใหญ่นี้ยังมีอยู่ในคอมไพเลอร์ใด ๆ ที่เสนอ TR1 แม้ว่าชื่อจะแตกต่างกันเล็กน้อย และstd::tr1::mt19937std::tr1::uniform_int<int>

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

ฉันได้เขียนตัวสร้าง xorshift ที่เป็นไปตามมาตรฐาน C ++ 11 - xorshift.hpp , xorshift.cpp - และวางไว้ในโดเมนสาธารณะ คุณสามารถเสียบมันเข้ากับฟังก์ชั่นการสุ่มตัวอย่าง C ++ 11 ใด ๆ ข้างต้น:

xorshift eng;
std:::uniform_int_distribution<int> dist(-10, 10)
for (int i = 0; i < 10; ++i)
    std::cout << dist(eng) << std::endl;

5
ใช่นั่นคือคำตอบที่ฉันกำลังมองหานั่นคือเหตุผลที่ฉันโพสต์ที่นี่ใน gamedev:)
o0 '

1
เพียงแค่ต้องการที่จะทราบว่าไม่มีอะไรในไฟล์ที่คุณเชื่อมโยงบ่งบอกว่าพวกเขาอยู่ในโดเมนสาธารณะ วิธีการทำงานของกฎหมายลิขสิทธิ์มีความจำเป็นต้องทราบอย่างชัดเจนเกี่ยวกับเรื่องนี้เนื่องจากกฎหมายถือว่า "การสงวนสิทธิ์ทั้งหมด" โดยค่าเริ่มต้น จริง ๆ แล้วมันปลอดภัยยิ่งขึ้นที่จะใช้บางอย่างเช่นใบอนุญาต MIT หรือ BSD 2 ข้อเนื่องจากเขตอำนาจศาลบางแห่งไม่ยอมรับว่า "นี่เป็นสาธารณสมบัติ" เนื่องจากมีผลผูกพันทางกฎหมาย หากคุณสนใจที่จะเห็นคนใช้รหัสของคุณมันอาจคุ้มค่าที่จะดูแลมัน
Sean Middleditch

1
@seanmiddleditch: ฉันชัดเจนเกี่ยวกับที่นี่ หากคุณต้องการภายใต้ลิขสิทธิ์แบบ MIT ฉันจะทำตามคำสั่งของ SQLite และมอบให้คุณในราคาเพียง $ 1,000

การขาดถ้าส่วนหัวในรหัสประกาศอะไร (ซึ่ง SQLite ทำ, iirc) เป็นปัญหาหลัก ถ้าคุณไม่สนใจนั่นก็เจ๋ง เพียงแค่ให้คำแนะนำที่เป็นมิตรกับคุณ
Sean Middleditch

1

RNG ผมเคยใช้มาก่อนสำหรับวัตถุประสงค์ gamedev ก็คือบ๊อบเจนกินส์ 'เล็ก' RNG อธิบายที่นี่

(นอกจากนี้เขายังมีความแข็งแกร่งของการเข้ารหัสลับ RNG เรียกว่า ISAAC แต่มันใหญ่กว่าและช้ากว่าและเกมไม่ต้องการความแข็งแกร่งระดับนั้น)


1
ที่ดูมีราคาแพงกว่า xorshift (4 xors และ 3 กะเทียบกับ 4 เพิ่ม 6 กะ 2 ors และ xor) มีระยะเวลาแย่ลงและมีความเสี่ยงรอบสั้นมากที่มีการเริ่มต้นบางอย่าง มันดูเร็ว แต่ไม่เร็ว ระยะเวลาโอเค แต่ไม่มีที่ไหนใกล้ดีที่สุด; คุณภาพการกระจายพื้นฐานเช่นเดียวกับ xorshift; ฉันไม่เห็นเหตุผลที่จะใช้มัน

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