สมมติว่าคุณต้องการใช้<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
ไปหรืออะไรนะ?