2012-05-10 18 views
7

मेरे एल्गोरिदम में मेरे पास दो मान हैं जिन्हें मुझे यादृच्छिक रूप से चुनने की आवश्यकता है लेकिन प्रत्येक को एक पूर्व निर्धारित संख्या का चयन करना होगा।दो मानों के यादृच्छिक विकल्प

अब तक मेरा समाधान वेक्टर में विकल्पों को सही संख्या में रखना है और फिर इसे घुमाएं। सी ++ में:

// Example choices (can be any positive int) 
int choice1 = 3; 
int choice2 = 4; 

int number_of_choice1s = 5; 
int number_of_choice2s = 1; 

std::vector<int> choices; 
for(int i = 0; i < number_of_choice1s; ++i) choices.push_back(choice1); 
for(int i = 0; i < number_of_choice2s; ++i) choices.push_back(choice2); 
std::random_shuffle(choices.begin(), choices.end()); 

तब मैं choices के लिए एक इटरेटर रखने के लिए और जब भी मैं एक नया एक की जरूरत है मैं iterator बढ़ाने के लिए और है कि मूल्य हड़पने।

यह काम करता है लेकिन ऐसा लगता है कि एक और अधिक प्रभावी तरीका हो सकता है। चूंकि मैं हमेशा जानता हूं कि मैं कितने मूल्य का उपयोग करूंगा, मैं सोच रहा हूं कि मूल्यों को संग्रहीत करने के बजाय ऐसा करने के लिए और अधिक एल्गोरिदमिक तरीका है या नहीं।

+0

मैं कामकाजी समाधान के साथ रहूंगा जब तक कि ऐसा कोई अच्छा कारण न हो। क्या यह एक बाधा या ऐसा कुछ के रूप में प्रोफाइल किया गया है? – amit

+0

एक तरीका है लेकिन यह कम स्पष्ट और संक्षिप्त होगा। मैं इस तकनीक के साथ रहना होगा। –

+0

मुझे वास्तव में वास्तव में इस समाधान को पसंद है। अन्य सभी समाधान जो ध्यान में आते हैं (लगभग 5 सेकंड के लिए सोचने के बाद) यादृच्छिक संख्या जनरेटर शामिल हैं। लेकिन चूंकि आपके पास प्रत्येक विकल्प की पूर्व निर्धारित संख्या है, इसलिए ये समाधान असुरक्षित होंगे क्योंकि आखिरकार उनकी पसंद के बाद मूल्यों को अनदेखा करना शुरू हो जाएगा। (माना जाता है कि शफल विधि संभावित रूप से एक सीपीयू नाली है, लेकिन आप इसे कम से कम एक अनुमानित चलने का समय बना सकते हैं, जिसे आप ऊपर के बारे में सोच रहे समाधानों के साथ नहीं कर सकते हैं) – gnomed

उत्तर

10

आप अनावश्यक रूप से इतनी मेमोरी का उपयोग कर रहे हैं।

int number_of_choice1s = 5; 
int number_of_choice2s = 1; 

अब बस randomize:

int result = rand() % (number_of_choice1s + number_of_choice2s); 
if(result < number_of_choice1s) { 
    --number_of_choice1s; 
    return choice1; 
} else { 
    --number_of_choice2s; 
    return choice2; 
} 

यह बहुत अच्छी तरह से यादृच्छिक आमंत्रण बीस लाख मापता है आप दो चर है।

+0

एक बार काउंटर 0 तक पहुंचने के बाद आप शेष प्रक्रिया को शॉर्ट सर्किट कर सकते हैं –

+0

पूर्वाग्रह कैसे है? यह सिर्फ – BrokenGlass

+2

से एन एल्गोरिदम से +1 के क्यूथ के चयन एम के कस्टमाइज्ड संस्करण की तरह दिखता है लेकिन ध्यान दें कि यदि आपकी मानक लाइब्रेरी में खराब 'रैंड' कार्यान्वयन होता है (उदाहरण के लिए, छोटे मॉड्यूलस के साथ रैखिक संयोग), '%' इस तरह पूर्वाग्रह पेश कर सकते हैं। साथ ही, 'RAND_MAX' 32767 जितना छोटा हो सकता है (माइक्रोसॉफ्ट की मानक लाइब्रेरी में' रैंड 'में यह संपत्ति है) और यदि आपके पास बड़ी संख्या में विकल्प हैं तो आप पूरी तरह खो देंगे। –

1

आप थोड़ा और बस इस लिख सकते हैं:

std::vector<int> choices(number_of_choice1s, choice1); 
choices.resize(number_of_choice1s + number_of_choice2s, choice2); 
std::random_shuffle(choices.begin(), choices.end()); 
0

एक पक्षपाती यादृच्छिक वितरण (विकल्प है कि सबसे कम और कम मौका उठाए जा सकें है चुना गया था जिसके परिणामस्वरूप सेट पर आदेश के कुछ प्रकार रखेंगे अगला), जो पक्षपातपूर्ण परिणाम देता है (विशेष रूप से यदि आपको पहले मूल्य को चुनने के लिए समय की संख्या दूसरी मान की तुलना में बड़ी है, तो आप इस तरह से कुछ खत्म कर देंगे {1,1,1,2,1,1 , 1,1,2}

यहां कोड है, जो @ टोमाज़ नर्कविचज़ द्वारा लिखे गए एक जैसा दिखता है, लेकिन एक साधारण/विषमता का उपयोग करके जो 50/50 को या तो चुनने का मौका देना चाहिए लूस।

int result = rand(); 

if (result & 1 && number_of_choice1s > 0) 
{ 
number_of_choice1s--; 
return choice1; 
}else if (number_of_choice2s>0) 
{ 
number_of_choice2s--; 
return choice2; 
} 
else 
{ 
return -1; 
} 
संबंधित मुद्दे