สมมติว่าคุณต้องการใช้<random>สิ่งอำนวยความสะดวกC ++ ในโปรแกรมที่ใช้งานจริง (สำหรับคำจำกัดความของ "การปฏิบัติ" บางข้อ จำกัด ที่นี่เป็นส่วนหนึ่งของคำถามนี้) คุณได้รับรหัสคร่าว ๆ เช่นนี้:
int main(int argc, char **argv) {
int seed = get_user_provided_seed_value(argc, argv);
if (seed == 0) seed = std::random_device()();
ENGINE g(seed); // TODO: proper seeding?
go_on_and_use(g);
}
คำถามของฉันคือคุณควรใช้แบบENGINEไหน
ฉันเคยพูดเสมอ
std::mt19937เพราะมันพิมพ์ได้อย่างรวดเร็วและมีการจดจำชื่อ แต่ทุกวันนี้ดูเหมือนว่าทุกคนกำลังพูดว่า Mersenne Twister นั้นหนักและแคชไม่เป็นมิตรและไม่ผ่านการทดสอบทางสถิติทั้งหมดที่คนอื่นทำฉันต้องการพูด
std::default_random_engineเพราะเป็น "ค่าเริ่มต้น" ที่ชัดเจน แต่ฉันไม่รู้ว่ามันแตกต่างจากแพลตฟอร์มหนึ่งไปอีกแพลตฟอร์มหรือไม่และฉันไม่รู้ว่ามันดีทางสถิติหรือไม่เนื่องจากทุกคนอยู่บนแพลตฟอร์ม 64 บิตวันนี้อย่างน้อยเราควรจะใช้
std::mt19937_64มากกว่าstd::mt19937หรือไม่ฉันต้องการที่จะพูด
pcg64หรือxoroshiro128เพราะพวกเขาดูดีและมีน้ำหนักเบา แต่พวกเขาไม่ได้อยู่ใน<random>นั้นผมไม่ทราบอะไรเกี่ยวกับ
minstd_rand,minstd_rand0,ranlux24,knuth_bฯลฯ - แน่นอนพวกเขาจะต้องดีสำหรับบางสิ่งบางอย่าง?
เห็นได้ชัดว่ามีข้อ จำกัด บางอย่างในการแข่งขันที่นี่
ความแข็งแรงของเครื่องยนต์ (
<random>ไม่มี PRNG ที่แข็งแกร่งในการเข้ารหัส แต่ยังบางส่วนของมาตรฐานที่ได้รับการ "อ่อนแอ" กว่าคนอื่นใช่มั้ย?)sizeofเครื่องยนต์operator()ความเร็วของความง่ายในการเพาะ
mt19937เป็นการยากที่จะหว่านเมล็ดอย่างเหมาะสมเนื่องจากมีสถานะมากในการเริ่มต้นความสะดวกในการพกพาระหว่างผู้จำหน่ายห้องสมุด หากผู้ขายรายหนึ่ง
foo_engineผลิตหมายเลขที่แตกต่างจากผู้จำหน่ายรายอื่นfoo_engineนั่นไม่ดีสำหรับบางแอปพลิเคชัน (หวังว่านี่จะเป็นข้อยกเว้นdefault_random_engineบางอย่างออกไป)
การชั่งน้ำหนักข้อ จำกัด เหล่านี้ให้มากที่สุดเท่าที่คุณจะทำได้คุณจะพูดว่าอะไรคือคำตอบที่ดีที่สุด "คำตอบที่ดีที่สุดสำหรับการอยู่ภายในห้องสมุดมาตรฐาน" ฉันควรจะใช้ต่อstd::mt19937ไปหรืออะไรนะ?