ฉันต้องการเติมเต็มคำตอบที่ยอดเยี่ยมของ Angry Shoe และ peterchen ด้วยภาพรวมสั้น ๆ เกี่ยวกับความทันสมัยในปี 2015:
ทางเลือกที่ดีบางอย่าง
randutils
randutils
ห้องสมุด(นำเสนอ)เป็นความแปลกใหม่ที่น่าสนใจที่นำเสนออินเตอร์เฟซที่เรียบง่ายและ (ประกาศ) ความสามารถในการสุ่มที่แข็งแกร่ง มีข้อเสียที่เพิ่มการพึ่งพาโครงการของคุณและยังใหม่ไม่ได้รับการทดสอบอย่างกว้างขวาง อย่างไรก็ตามการฟรี (ใบอนุญาต MIT) และส่วนหัวเท่านั้นฉันคิดว่ามันคุ้มค่าที่จะลอง
ตัวอย่างน้อยที่สุด: ม้วนตาย
#include <iostream>
#include "randutils.hpp"
int main() {
randutils::mt19937_rng rng;
std::cout << rng.uniform(1,6) << "\n";
}
แม้ว่าใครจะไม่สนใจห้องสมุด แต่เว็บไซต์ ( http://www.pcg-random.org/ ) มีบทความที่น่าสนใจมากมายเกี่ยวกับรูปแบบของการสร้างตัวเลขสุ่มโดยทั่วไปและไลบรารี C ++ โดยเฉพาะ
เพิ่ม. สุ่ม
Boost.Random
(เอกสาร)เป็นห้องสมุดที่เป็นแรงบันดาลใจC++11
's <random>
ซึ่งหุ้นมากของอินเตอร์เฟซ ในขณะที่ในทางทฤษฎียังเป็นการพึ่งพาภายนอก แต่Boost
ตอนนี้มีสถานะเป็นไลบรารี "กึ่งมาตรฐาน" และRandom
โมดูลของมันอาจถือได้ว่าเป็นตัวเลือกคลาสสิกสำหรับการสร้างตัวเลขสุ่มที่มีคุณภาพดี มีข้อดีสองประการเกี่ยวกับC++11
โซลูชัน:
- พกพาสะดวกมากขึ้นเพียงแค่ต้องการการสนับสนุนคอมไพเลอร์สำหรับ C ++ 03
random_device
ใช้วิธีการเฉพาะของระบบเพื่อให้ได้เมล็ดที่มีคุณภาพดี
ข้อบกพร่องเล็ก ๆ เพียงอย่างเดียวคือการเสนอขายโมดูลไม่ได้เป็นส่วนหัวเท่านั้นหนึ่งมีการรวบรวมและเชื่อมโยงrandom_device
boost_random
ตัวอย่างน้อยที่สุด: ม้วนตาย
#include <iostream>
#include <boost/random.hpp>
#include <boost/nondet_random.hpp>
int main() {
boost::random::random_device rand_dev;
boost::random::mt19937 generator(rand_dev());
boost::random::uniform_int_distribution<> distr(1, 6);
std::cout << distr(generator) << '\n';
}
แม้ว่าตัวอย่างขั้นต่ำจะทำงานได้ดี แต่โปรแกรมจริงควรใช้การปรับปรุงสองอย่าง:
- ทำให้: กำเนิดคืออวบค่อนข้าง (> 2 KB) และจะดีกว่าไม่ได้จัดสรรในกอง
mt19937
thread_local
- เมล็ดพันธุ์ที่
mt19937
มีจำนวนเต็มมากกว่าหนึ่งจำนวน: Mersenne Twister มีสถานะใหญ่และสามารถใช้ประโยชน์จากเอนโทรปีได้มากขึ้นในระหว่างการเริ่มต้น
ทางเลือกที่ไม่ดีบางอย่าง
ไลบรารี C ++ 11
แม้ว่าจะเป็นวิธีการแก้ปัญหาที่เป็นสำนวนที่สุด แต่<random>
ห้องสมุดก็ไม่ได้เสนออะไรมากมายเพื่อแลกกับความซับซ้อนของอินเทอร์เฟซแม้แต่กับความต้องการขั้นพื้นฐาน ข้อบกพร่องอยู่ที่std::random_device
: Standard ไม่ได้กำหนดคุณภาพขั้นต่ำสำหรับเอาต์พุต (ตราบเท่าที่entropy()
ส่งคืน0
) และในปี 2015 MinGW (ไม่ใช่คอมไพเลอร์ที่ใช้มากที่สุด แต่แทบจะไม่เป็นตัวเลือกที่ลึกลับ) จะพิมพ์4
บนตัวอย่างที่น้อยที่สุดเสมอ
ตัวอย่างน้อยที่สุด: ม้วนตาย
#include <iostream>
#include <random>
int main() {
std::random_device rand_dev;
std::mt19937 generator(rand_dev());
std::uniform_int_distribution<int> distr(1, 6);
std::cout << distr(generator) << '\n';
}
หากการใช้งานไม่เน่าเสียโซลูชันนี้ควรเทียบเท่ากับ Boost หนึ่งและใช้คำแนะนำเดียวกัน
วิธีแก้ปัญหาของ Godot
ตัวอย่างน้อยที่สุด: ม้วนตาย
#include <iostream>
#include <random>
int main() {
std::cout << std::randint(1,6);
}
นี่เป็นวิธีแก้ปัญหาที่ง่ายมีประสิทธิภาพและเรียบร้อย มีข้อบกพร่องเท่านั้นจะใช้เวลารวบรวมสักครู่ - ประมาณสองปีโดยให้ C ++ 17 ออกตามเวลาและrandint
ฟังก์ชันการทดลองได้รับการอนุมัติในมาตรฐานใหม่ ในเวลานั้นการรับประกันคุณภาพการเพาะเมล็ดจะดีขึ้นด้วย
ตัวอย่างน้อยที่สุด: ม้วนตาย
#include <cstdlib>
#include <ctime>
#include <iostream>
int main() {
std::srand(std::time(nullptr));
std::cout << (std::rand() % 6 + 1);
}
โซลูชัน C แบบเก่าถือว่าเป็นอันตรายและด้วยเหตุผลที่ดี (ดูคำตอบอื่น ๆ ที่นี่หรือการวิเคราะห์โดยละเอียดนี้ ) ถึงกระนั้นก็มีข้อดีคือใช้งานง่ายพกพาได้รวดเร็วและซื่อสัตย์ในแง่ที่เป็นที่ทราบกันดีว่าตัวเลขสุ่มที่ได้มานั้นแทบจะไม่เหมาะสมดังนั้นจึงไม่มีใครอยากใช้เพื่อจุดประสงค์ที่จริงจัง
โซลูชันการหมุนรอบบัญชี
ตัวอย่างน้อยที่สุด: ม้วนตาย
#include <iostream>
int main() {
std::cout << 9;
}
ในขณะที่ 9 เป็นผลลัพธ์ที่ค่อนข้างผิดปกติสำหรับการม้วนแบบธรรมดา แต่เราต้องชื่นชมการผสมผสานที่ยอดเยี่ยมของคุณสมบัติที่ดีในโซลูชันนี้ซึ่งจัดการได้เร็วที่สุดง่ายที่สุดเป็นมิตรกับแคชและพกพาได้มากที่สุด ด้วยการแทนที่ 9 ด้วย 4 อันจะได้เครื่องกำเนิดไฟฟ้าที่สมบูรณ์แบบสำหรับ Dungeons and Dragons ทุกชนิดในขณะที่ยังคงหลีกเลี่ยงค่าสัญลักษณ์ที่รับภาระ 1, 2 และ 3 ข้อบกพร่องเล็ก ๆ เพียงอย่างเดียวคือเนื่องจากอารมณ์ไม่ดีของโทรลล์บัญชีของ Dilbert โปรแกรมนี้ก่อให้เกิดพฤติกรรมที่ไม่ได้กำหนด