2008-10-10 7 views
6

मुझे डुप्लिकेशंस के साथ लगातार 1 - 10000 रेंज में यादृच्छिक संख्याएं उत्पन्न करने की आवश्यकता है। कोई सिफारिशें?सी ++ में ओपन सोर्स यादृच्छिक संख्या पीढ़ी एल्गोरिदम?

विवरण: हम अपने आवेदन के लिए एक नया संस्करण बना रहे हैं, जो स्क्लाइट डीबी में रिकॉर्ड बनाए रखता है। हमारे आवेदन के अंतिम संस्करण में, हमारे पास प्रत्येक रिकॉर्ड के लिए अद्वितीय कुंजी नहीं थी। लेकिन अब नए अपग्रेड किए गए संस्करण के साथ, हमें अंतिम संस्करण के डीबी से आयात सुविधा का समर्थन करने की आवश्यकता है। तो हम क्या करते हैं, हम पुराने डीबी से प्रत्येक रिकॉर्ड पढ़ते हैं और अद्वितीय कुंजी के लिए एक यादृच्छिक संख्या उत्पन्न करते हैं और इसे नए डीबी में स्टोर करते हैं। यहां हमें कई को लगातार 10000 रिकॉर्ड आयात करने की आवश्यकता है।

+2

आप नए डीबी के लिए रिकॉर्ड अनुक्रमिक अद्वितीय कुंजी क्यों नहीं देंगे? मैं नहीं देख सकता कि यादृच्छिक कुंजी का उपयोग करके आपको क्या लाभ मिलता है। – TimB

+0

बिल्कुल - अनुक्रमिक कुंजी का उपयोग क्यों नहीं करें? संख्याओं को यादृच्छिक बनाना कुंजी-कुंजी के लिए व्यर्थ है। यह सुरक्षा या विश्वसनीयता में वृद्धि नहीं करता है ... – Toybuilder

+0

दरअसल समस्या यह है कि पहले आवेदन में एमएफसी (सीरियलाइज्ड) ऑब्जेक्ट डीबी था और अब हम इसे SQLite पर ले जा रहे हैं, इसलिए संगतता कारण के लिए, हम इस संस्करण में दोनों डीबी प्रदान कर रहे हैं। इसके अलावा हमें पुराने डीबी आयात करने की आवश्यकता है (इसमें अनन्य कुंजी नहीं है) और नई डीबी फाइलें (अनन्य कुंजी शामिल हैं) –

उत्तर

5

ठीक है, अंत में आपको या तो उन्हें उत्पन्न करना बंद कर देगा, या आप उन्हें डुप्लिकेट करने जा रहे हैं।

कंप्यूटर पर आपके विकल्प छद्म यादृच्छिक संख्या जेनरेटर (पीआरएनजी) तक सीमित हैं, और आपकी बाधा दी गई है कि वे कभी भी दोहराना नहीं चाहते हैं तो एक पीआरएनजी आपका सबसे अच्छा विकल्प है - असली यादृच्छिक डेटा कभी-कभी किसी संख्या को डुप्लिकेट करेगा।

आपके मामले में, मैं आपके 10,000 नंबरों को घुमाने के लिए एक बड़े पीआरएनजी (32 बिट या बड़े) का उपयोग करने पर विचार करता हूं, और फिर संख्याओं को शफल क्रम में भेजता हूं।

एक बार उनका उपयोग हो जाने के बाद आप फिर से घुमा सकते हैं - चूंकि पीआरएनजी इतना बड़ा है कि आप अनुक्रम को डुप्लिकेट करने से पहले 10k संख्याओं से गुजरने में सक्षम होंगे।

हमें क्या करना है इसके बारे में अधिक जानकारी दें और हम एक बेहतर उत्तर के साथ आ सकते हैं।

-Adam

5

Mersenne ट्विस्टर सबसे अच्छा वर्तमान (हालांकि मैं किसी भी वास्तव में नई खोजों के पीछे कुछ ही हफ्तों के हो सकता है) है। लगभग हर भाषा में स्रोत कहीं भी उपलब्ध है, और एमटी बूस्ट here

+0

मेरसेन ट्विस्टर को फास्ट एंड परफेक्ट पीआरएनजी के बीच एक अच्छा समझौता माना जाता है, जहां तक ​​मुझे पता है। –

+3

यह कुछ एप्लिकेशन के लिए केवल 'सर्वश्रेष्ठ' है, यानी सबकुछ क्रिप्टो नहीं है (ओपी के उपयोग मामले या सिमुलेशन की तरह)। – Roel

+0

क्रिप्टो के लिए, [ब्लम ब्लम शुब] (http://en.wikipedia.org/wiki/Blum_Blum_Shub) काफी लोकप्रिय है। समुद्री डाकू सामग्री के साथ धार साइटों को जोड़ने के लिए –

2

Boost.Random एक अच्छा विकल्प है और मेरे लिए ठीक काम करता है। हालांकि, अगर आपको कई यादृच्छिक संख्या जनरेटर और वितरण की आवश्यकता नहीं है तो आप पूरे बूस्ट पैकेज को इंस्टॉल न करने के लिए किसी अन्य लाइब्रेरी की तलाश कर सकते हैं।

2

कितना यादृच्छिक है? स्पष्ट रूप से रैंड() है, ओएस विशिष्ट सामान भी है (उदाहरण के लिए विंडोज़ क्रिप्टोएपीआई में कुछ है)। क्या आप कुछ लिख रहे हैं (अनुशंसित नहीं), या सिर्फ उपयोग करने के लिए पूर्व-मौजूदा फ़ंक्शन की तलाश कर रहे हैं?

3

TR1 में अच्छा यादृच्छिक संख्या समर्थन है - यदि आपका कंपाइलर इसका समर्थन करता है।

अन्यथा Boost

यह TR1 बन मूल रूप से क्या है।

जहां तक ​​डुप्लिकेट नहीं मिल रहा है - आप शफल चाहते हैं। यह बहुत आसान हो सकता है, लेकिन अगर आप इसे सही नहीं करते हैं तो कुछ नुकसान हैं। जेफ Atwood एक अच्छा लिखने अप एक समय पहले किया था:

http://www.codinghorror.com/blog/archives/001015.html

3

बूस्ट शायद ऐसा कुछ करता है जो गारंटीकृत संख्याओं को गारंटी देता है। लेकिन यहां थोड़ी मस्ती के लिए मेरा विचार है।

नोट: मैं उस दिशा में अपनी रैंड को चलाने और उत्पन्न करने की कोशिश नहीं करता पागलपन है।

#include <iostream> 
#include <vector> 
#include <algorithm> 


class GaranteedNoRepeatRandom 
{ 
    public: 
     GaranteedNoRepeatRandom(int limit) 
      :data(limit) 
      ,index(0) 
     { 
      for(int loop=0;loop < limit;++loop) 
      { data[loop] = loop; 
      } 
      // Note: random_shuffle optionally takes a third parameter 
      // as the rand number generator. 
      std::random_shuffle(&data[0],&data[0]+limit); 
     } 

     unsigned int rand() 
     { 
      unsigned int result = data[index]; 
      index = (index+1) % data.size(); 

      // Add code to re-shuffle after index wraps around 
      return result; 
     } 
    private: 
     std::vector<unsigned int>    data; 
     std::vector<unsigned int>::size_type index; 
}; 

int main() 
{ 
    GaranteedNoRepeatRandom  gen(10000); 

    for(int loop =0;loop < 10;++loop) 
    { 
     std::cout << gen.rand() << "\n"; 
    } 
} 
0

Numerical Recipes in C में यादृच्छिक संख्या पीढ़ी को समर्पित एक पूरा अध्याय है। वहां कुछ कार्यान्वयन हैं। अच्छी सांख्यिकीय संपत्तियों के साथ सरल और सीधे आगे से जटिल तक।

+0

-1 –

2

क्या डेटाबेस रिकॉर्ड के लिए अनन्य कुंजी के रूप में यादृच्छिक संख्या का उपयोग करने के पूरे विचार पर सवाल करना ठीक है? मैं स्क्लाइट से परिचित नहीं हूं, लेकिन यह जांच करने लायक है कि यह आंतरिक रूप से किसी प्रकार का अद्वितीय कॉलम पहचानकर्ता का समर्थन करता है या नहीं। SQL सर्वर में 'पहचान' कॉलम हैं, उदाहरण के लिए, और ओरेकल में 'अनुक्रम' हैं, जिनमें से दोनों एक ही उद्देश्य की सेवा करते हैं।

2

बड़ी यादृच्छिक संख्याएं उत्पन्न करें। 128 बिट्स कहें। 10000 के सेट में दो ऐसी संख्याओं की बाधाएं हास्यास्पद रूप से छोटी हैं (एन^2/2^बी के क्रम पर, जहां n = संख्याओं की संख्या आवश्यक है और बी = उपयोग की जाने वाली बिट्स की संख्या)। पर्याप्त बिट्स को देखते हुए, आपके बम की बाधाओं की तुलना में बाधाएं एक ब्रह्मांडीय किरण से दूषित हो जाएंगी जैसे कि आपका एल्गोरिदम वैसे भी विफल हो जाता है। सावधान रहें कि जिस स्थान पर आप यादृच्छिक संख्याएं खींच रहे हैं, उसमें वास्तव में बिट्स की संख्या है जिसे आप ढूंढ रहे हैं। 32 बिट्स के पूल से गलती से 128 बिट संख्याएं उत्पन्न करना आसान है (यानी, केवल 2^32 संभावनाएं हैं भले ही आप संख्या 1 से 2^128 उत्पन्न कर रहे हों)। बूस्ट लाइब्रेरी में यादृच्छिक संख्या जनरेटर यह आपके लिए सही तरीके से कर सकते हैं। बीटीडब्ल्यू: यदि आपको 128 बिट्स पसंद नहीं हैं, तो 256 बिट्स या इससे अधिक का उपयोग करें जब तक कि आप आरामदायक न हों कि हैशिंग टक्कर का कोई व्यावहारिक मौका नहीं है। यदि आपको केवल एक बार ऐसा करना है, तो पहले पिछले जवाब में पहले से उल्लिखित शफल विधि का उपयोग करें। इसका एक आदर्श हैश उत्पन्न करने का लाभ होगा।

2

आप एक आवश्यकता मानों को दोहराने नहीं है के एक दृश्य उत्पन्न करने के लिए हो सकता है की जरूरत है, तो आप "यादृच्छिक" परिणाम फोन नहीं कर सकते हैं। अनुक्रम में मूल्यों के वितरण के साथ पुनरावृत्ति की कमी के साथ सच यादृच्छिकता को कम करना पड़ता है।

5

यदि यह वास्तव में दोहराने के बिना 1 से 10,0000 की सीमा में होना चाहिए, लेकिन गैर-अनुक्रमिक तो संभवतः पहले 10000 तत्वों की अनुक्रमिक सरणी बनाने के लिए सबसे अच्छा होगा, और फिर उन्हें घुमाएं।

हालांकि, मुझे मूल प्रश्न पर टिप्पणियों से सहमत होना चाहिए। मुझे उन्हें अनुक्रमिक बनाने में कोई मूल्य नहीं दिखता है।

वैकल्पिक रूप से, अद्वितीय & गैर-अनुक्रमिक महत्वपूर्ण हैं, तो 1 से 10,000 रेंज संदिग्ध हो जाती है। यह सिर्फ GUID का उपयोग करने के लिए सबसे अच्छा होगा।

2

यादृच्छिक संख्याओं की पीढ़ी मौका छोड़ने के लिए बहुत महत्वपूर्ण है। - रॉबर्ट आर कोवेयो, ओक रिज नेशनल लेबोरेटरी