कौन से <random> के यादृच्छिक संख्या इंजनों को वास्तव में व्यवहार में उपयोग करना चाहिए? std :: mt19937?


21

मान लें कि आप C ++ <random>सुविधाओं का उपयोग एक व्यावहारिक कार्यक्रम में करना चाहते हैं ("व्यावहारिक" की कुछ परिभाषा के लिए - यहाँ की बाधाएँ इस प्रश्न का एक प्रकार है)। आपको कोड इस तरह मिला है:

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था क्योंकि यह टाइप करने के लिए जल्दी था और नाम पहचान था। लेकिन इन दिनों ऐसा लगता है कि हर कोई कह रहा है कि मेर्सनी ट्विस्टर बहुत भारी है और कैश-अनफ्रेंडली है और वह सभी सांख्यिकीय परीक्षण भी पास नहीं करता है जो अन्य करते हैं।

  • मैं कहना चाहूंगा 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, या क्या?


2
आपके अंतिम बिंदु पर, सभी मानक इंजन एडेप्टर एक निर्मित डिफ़ॉल्ट के विशेष रूप से लगातार आह्वान पर एक विशेष मूल्य को वापस करने के लिए निर्दिष्ट हैं, इसलिए उन्हें पोर्टेबल होना चाहिए।
1201ProgramAlarm

जवाबों:


15

C ++ संदर्भ उन सभी यादृच्छिक इंजनों को सूचीबद्ध करता है जो वर्तमान में C ++ द्वारा प्रदान किए गए हैं। हालांकि, इंजनों का चयन वांछित होने के लिए बहुत कुछ छोड़ देता है (जैसे, उच्च गुणवत्ता वाले यादृच्छिक जनरेटर की मेरी सूची देखें )। उदाहरण के लिए:

  • default_random_engine कार्यान्वयन-परिभाषित है, इसलिए यह अज्ञात है कि क्या इंजन में सांख्यिकीय खामियां हैं जिनके बारे में आवेदन परवाह कर सकता है।
  • linear_congruential_engineरैखिक रैखिक जनरेटर को लागू करता है। हालांकि, वे खराब गुणवत्ता वाले होते हैं जब तक कि मापांक प्रमुख और बहुत बड़ा नहीं होता है (कम से कम 64 बिट्स)। इसके अलावा, वे अपने मापांक से अधिक बीज स्वीकार नहीं कर सकते।
  • minstd_rand0और minstd_randकेवल 2 ^ 31 बीज के बारे में स्वीकार करें। knuth_bएक लपेटता है minstd_rand0और एक Bays-Durham इसे फेरबदल करता है।
  • mt19937और mt19937_64यदि वे बेहतर इनिशियलाइज़ेड थे (जैसे, केवल एक नहीं, तो std::seed_seqकई आउटपुट के साथ शुरू करके) बहुत अधिक बीज स्वीकार कर सकते हैं random_device, लेकिन वे लगभग 2500 बाइट्स का उपयोग करते हैं।
  • ranlux24और ranlux48राज्य के लगभग 577 बिट्स का उपयोग करते हैं लेकिन वे धीमी गति से होते हैं (वे कुछ को ध्यान में रखते हुए और अन्य छद्म आयामी आउटपुट को त्याग कर काम करते हैं)।

हालाँकि, C ++ में दो इंजन भी हैं जो इसके यादृच्छिकता गुणों को बेहतर बनाने के लिए एक और इंजन लपेटते हैं:

  • discard_block_engine किसी दिए गए यादृच्छिक इंजन के कुछ आउटपुट को छोड़ देता है।
  • shuffle_order_engine एक बेतरतीब इंजन के एक बेस-डरहम फेरबदल को लागू करता है।

उदाहरण के लिए, इसके बारे में एक बेस-डरहम फेरबदल करना संभव, कहते हैं, है mt19937, ranlux24या कस्टम linear_congruential_engineके साथ shuffle_order_engine। शायद लिपटे इंजन मूल एक की तुलना में बेहतर गुणवत्ता है। हालांकि, नए इंजन की सांख्यिकीय गुणवत्ता का परीक्षण किए बिना भविष्यवाणी करना कठिन है

इस प्रकार, ऐसे परीक्षण लंबित हैं, ऐसा लगता है कि mt19937यह C ++ मानक के लिए अब तक का सबसे व्यावहारिक इंजन है। मुझे पता है, हालांकि, C ++ के भविष्य के संस्करणों में एक और यादृच्छिक संख्या इंजन जोड़ने का कम से कम एक प्रस्ताव है (देखें C ++ पेपर P2075 )।


1

के अनुसार सी ++ संदर्भ , default_random_engine:

क्या पुस्तकालय कार्यान्वयन एक जनरेटर का चयन है जो अपेक्षाकृत आकस्मिक, अनुभवहीन और / या हल्के उपयोग के लिए कम से कम स्वीकार्य इंजन व्यवहार प्रदान करता है

तो हल्के उपयोग के लिए आपको किसी भी चीज़ के बारे में चिंता करने की ज़रूरत नहीं है, बीज के default_random_engineसाथ Epoch Time (time(0))और यह काफी ठीक होगा;)


मेरा मानना ​​है कि यहां मुद्दा पोर्टेबिलिटी का है। जबकि डिफ़ॉल्ट एक इंजन हो सकता है जो अच्छा प्रदर्शन करता है, यह दूसरे प्लेटफ़ॉर्म पर पुन: प्रयोज्य नहीं हो सकता है।
bremen_matt

@bremen_matt हम्म ... खैर, हमें "यादृच्छिक" संख्या को पुन: पेश करने की आवश्यकता क्यों है?
फारबोड अहमदन

2
परिक्षण। परीक्षण उद्देश्यों के लिए, आपको पुन: प्रयोज्य इनपुट की आवश्यकता है। उसी समय, आप उन इनपुट्स को यादृच्छिक रूप से चाहते या ले सकते हैं। उदाहरण के लिए, अधिकांश मशीन लर्निंग एल्गोरिदम मान लेते हैं कि पैरामीटर बेतरतीब ढंग से आरंभिक हैं। रैंसैक, सीएनएन, डीएनएन, ... कई एल्गोरिदम को यादृच्छिक मापदंडों की आवश्यकता होती है।
bremen_matt
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.