2013-10-28 4 views
5

मेरा लक्ष्य क्या है कोशिश कर रहा हूँ है निम्नलिखित:छोटी रेंज से यादृच्छिक न दोहराई पूर्णांकों उत्पन्न

मैं एक अपेक्षाकृत छोटे श्रृंखला से, पूर्णांकों का एक वेक्टर बनाते हैं, और पूर्णांकों कि कोई भी सुनिश्चित करना चाहते हैं एक ही पूर्णांक के बाद होगा।

यानी, यह एक "कानूनी" वेक्टर है: [1 3 4 2 5 3 2 3 5 4]

और यह एक "अवैध" वेक्टर (के बाद से 5 में से 5 इस प्रकार) है: [1 3 4 2 5 5 2 3 5 4]

मैं randperm साथ रूपों के सभी प्रकार randi के साथ प्रयोग किया गया है, और, और मैं हमेशा अटक जाते हैं जब मैं 100 के आसपास तत्वों का एक वेक्टर उत्पन्न करने के लिए प्रयास करते हैं, एक छोटे से सीमा से (यानी, 1 और 5 के बीच पूर्णांक)।

फ़ंक्शन बस बहुत लंबे समय तक चलता है।

यहाँ प्रयास है कि मैं कर दिया है में से एक है:

function result = nonRepeatingRand(top, count) 

    result = randi(top, 1, count); 

    while any(diff(result) == 0) 
     result = randi(top, 1, count);  
    end 

end 

किसी भी और सभी मदद की बहुत सराहना की जाएगी। धन्यवाद !

+2

सिर्फ एक छोटे से टिप्पणी का आनंद लें। गैर-दोहराव की स्थिति का मतलब है कि आपका वेक्टर कम "यादृच्छिक" – bla

उत्तर

11

अनुक्रम की तरह आप के लिए मतभेद1 से top - 1 को पैदा करने और उसके बाद की गणना संचयी योग द्वारा परिभाषित किया जा सकता देख रहे मापांकtop, एक यादृच्छिक प्रारंभिक मूल्य से शुरू:

function result = nonRepeatingRand(top, count) 

    diff = randi(top - 1, 1, count); 
    result = rem(cumsum(diff) + randi(1, 1, count) - 1, top) + 1; 

end 

पर मेरी मशीन, यह 0.58 सेकंड में 1: 5 में से 10 मिलियन संख्याओं का एक गैर-दोहराव अनुक्रम उत्पन्न करती है।

+0

+1 बहुत चालाक समाधान! –

+0

मैं वास्तव में यह नहीं समझ सकता कि आप इसके साथ कैसे आए ...? किसी भी तरह से, मेरे द्वारा एक +1! –

+1

यह मेरे लिए हुआ कि पोस्टर लागू करना चाहता है बाधा के संबंध में सबसे आसानी से व्यक्त किया जाता है। तो क्यों पहले diff उत्पन्न और उस से अनुक्रम उत्पन्न नहीं करते हैं। –

0

यह कैसे?

top = 5; 
count = 100; 
n1 = nan; 
out = []; 
for t = 1: count 
    n2 = randi(top); 
    while n1 == n2 
     n2 = randi(top); 
    end 
    out = [out, n2]; 
    n1 = n2; 
end 
1

प्रत्येक बार अनुक्रम को पुन: उत्पन्न न करें, लेकिन पुनरावृत्ति को ठीक करें। 5 1.6 सेकंड में: उदा .:

function result = nonRepeatingRand(top, count) 

    result = randi(top, 1, count); 

    ind = (diff(result) == 0); 
    while any(ind) 
     result(ind) = []; 
     result(end + 1 : count) = randi(top, 1, count - numel(result)); 

     ind = (diff(result) == 0); 
    end 

end 

मेरी मशीन पर, यह 10 लाख नंबर की किसी न दोहराई अनुक्रम 1 से बाहर उत्पन्न करता है।

+1

है, मुझे लगता है कि मेरा दूसरा उत्तर बेहतर है: तेज़, और अधिक सुरुचिपूर्ण। –

0

क्या पुनरावृत्ति के बिना इस "यादृच्छिक" अनुक्रम को बनाने का संभावित विकल्प है, ताकि सभी मूल्यों को समान रूप से वितरित किया जा सके (जैसे कि रैंडपर्म के साथ)?

रैंडपर्म सीमित लगता है, और मैं केवल थोड़ी देर में पहले फंक्शंस को कॉल करने के बारे में सोच सकता हूं, जब तक कि मेरा "बराबर वितरण क्रिट्रियन" पूरा नहीं हो जाता .. लेकिन क्या इसे जल्दी किया जा सकता है?

2

आप निम्नलिखित कोड के लिए गैर एम

randperm (एम) को 1 से यादृच्छिक संख्या दोहरा उत्पन्न उपयोग कर सकते हैं;

और कश्मीर गैर एम

randperm (एम, कश्मीर) के लिए 1 से यादृच्छिक संख्या दोहरा के लिए;

+1

धन्यवाद, लेकिन: जैसा कि आपने शायद देखा है, प्रश्न (बहुत सुंदरता से) एक साल पहले उत्तर दिया गया था और सही उत्तर इस तरह चिह्नित किया गया था। दूसरा, मुझे डर है कि आपने मुझसे पूछे गए प्रश्न का उत्तर नहीं दिया - अगर मुझे 1-4 की सीमा में 100 गैर-दोहराने वाले यादृच्छिक पूर्णांक के अनुक्रम की आवश्यकता है, तो 'रैंडपर्म (4,100)' निश्चित रूप से एक त्रुटि देता है। –

+0

आपका उत्तर बहुत आसान है, लेकिन आप सबसे अच्छे प्रिय हैं, चीयर्स – Christina

संबंधित मुद्दे