दिलचस्प पोस्ट
पायथन में JSON पार्स करें आंशिक सीमा के साथ HTML5 / CSS3 मंडल मजबूत पासवर्ड सत्यापन के लिए PHP नियमित अभिव्यक्ति मैं विशिष्ट वर्ग लोडर में लोड किए गए सभी कक्षाओं को कैसे सूचीबद्ध कर सकता हूं यूट्यूब वीडियो WebView में नहीं खेल रहा है डायनेमिक। क्लासपाथ झंडा क्या करता है? (IntelliJ परियोजना सेटिंग्स) JSON और भागने के पात्रों जावा में फास्ट और सरल स्ट्रिंग एन्क्रिप्ट / डिक्रिप्ट अजाक्स अनुरोध 200 ओके रिटर्न देता है, लेकिन सफलता के बजाय एक त्रुटि ईवेंट निकाल दिया गया है इंटरफ़ेस बिल्डर के साथ UIScrollView बनाने के लिए चरण नेमस्पेस 'System.Web.Mvc' में टाइप या नेमस्पेस नाम मौजूद नहीं है जावास्क्रिप्ट: टाइमआउट के साथ लूप के लिए एकल निरर्थक तर्क के साथ जावा varargs विधि कॉलिंग? हटाए जाने वाले कॉलबैक रननबल को रोक नहीं सकते हैं Android पर नोडजेएस चलाने के लिए व्यवहार्य विकल्प (अगस्त 2017)

कोई डुप्लिकेट के साथ यादृच्छिक संख्या बनाना

इस मामले में, अधिकतम केवल 5 है, इसलिए मैं डुप्लिकेट को एक-एक करके देख सकता हूं, लेकिन मैं इसे सरल तरीके से कैसे कर सकता हूं? उदाहरण के लिए, क्या होगा अगर अधिकतम में 20 का मान है? धन्यवाद।

int MAX = 5; for (i = 1 , i <= MAX; i++) { drawNum[1] = (int)(Math.random()*MAX)+1; while (drawNum[2] == drawNum[1]) { drawNum[2] = (int)(Math.random()*MAX)+1; } while ((drawNum[3] == drawNum[1]) || (drawNum[3] == drawNum[2]) ) { drawNum[3] = (int)(Math.random()*MAX)+1; } while ((drawNum[4] == drawNum[1]) || (drawNum[4] == drawNum[2]) || (drawNum[4] == drawNum[3]) ) { drawNum[4] = (int)(Math.random()*MAX)+1; } while ((drawNum[5] == drawNum[1]) || (drawNum[5] == drawNum[2]) || (drawNum[5] == drawNum[3]) || (drawNum[5] == drawNum[4]) ) { drawNum[5] = (int)(Math.random()*MAX)+1; } } 

Solutions Collecting From Web of "कोई डुप्लिकेट के साथ यादृच्छिक संख्या बनाना"

सबसे आसान तरीका संभव संख्या (1..20 या जो भी) की एक सूची बनाने के लिए होगा और फिर उन्हें Collections.shuffle साथ घसीटना। शफल तो फिर बस आप चाहते हैं कि कई तत्व लेते हैं। यह बहुत अच्छा है अगर आपकी सीमा अंत में तत्वों की संख्या के बराबर होती है (जैसे कार्ड के डेक को फेरबदल करने के लिए)

यह बहुत अच्छी तरह से काम नहीं करता है अगर आप चाहते हैं (कहते हैं) 1.10,000 रेंज में 10 यादृच्छिक तत्व हैं – आप अनावश्यक रूप से बहुत काम कर सकते हैं उस समय, आपके द्वारा अभी तक तैयार किए गए मानों का एक सेट रखने के लिए शायद बेहतर है और अगले अंक पहले से मौजूद न होने तक लूप में संख्याएं बनाते रहें:

 if (max < numbersNeeded) { throw new IllegalArgumentException("Can't ask for more numbers than are available"); } Random rng = new Random(); // Ideally just create one instance globally // Note: use LinkedHashSet to maintain insertion order Set<Integer> generated = new LinkedHashSet<Integer>(); while (generated.size() < numbersNeeded) { Integer next = rng.nextInt(max) + 1; // As we're adding to a set, this will automatically do a containment check generated.add(next); } 

हालांकि सेट पसंद के साथ सावधान रहें – मैंने बहुत जानबूझकर LinkedHashSet उपयोग किया है क्योंकि यह प्रविष्टि क्रम रखता है, जिसे हम यहां परवाह करते हैं।

फिर भी हर बार रेंज को कम करके और मौजूदा मूल्यों के लिए क्षतिपूर्ति करके, एक और विकल्प हमेशा प्रगति करना है। तो उदाहरण के लिए, मान लीजिए कि आप सीमा 0..9 में 3 मान चाहते हैं। पहले चलने पर आप श्रेणी 0..9 में किसी भी संख्या को उत्पन्न करते हैं – मान लें कि आप एक 4 उत्पन्न करते हैं।

दूसरे आवृत्ति पर आप फिर सीमा 0.8 में एक संख्या उत्पन्न करेंगे। यदि उत्पन्न संख्या 4 से कम है, तो आप इसे उतना ही रखना चाहते हैं … अन्यथा आप इसे एक जोड़ देते हैं। यह आपको 0.9 के बिना नतीजा 0 का परिणाम देता है। मान लीजिए कि हमें 7 तरह से मिलता है।

तीसरे स्थान पर आप 0 ..7 रेंज में नंबर बनाते थे यदि उत्पन्न संख्या 4 से कम है, तो आप इसे उतना ही रखना चाहते हैं जितना। यदि यह 4 या 5 है, तो आप एक जोड़ देंगे यदि यह 6 या 7 है, तो आप दो जोड़ देंगे। इस तरह से परिणाम रेंज 0 है। 0 बिना 4 या 6

यहाँ है कि मैं यह कैसे करूँगा

 import java.util.ArrayList; import java.util.Random; public class Test { public static void main(String[] args) { int size = 20; ArrayList<Integer> list = new ArrayList<Integer>(size); for(int i = 1; i <= size; i++) { list.add(i); } Random rand = new Random(); while(list.size() > 0) { int index = rand.nextInt(list.size()); System.out.println("Selected: "+list.remove(index)); } } } 

जैसा कि सम्मानित श्री स्कीट ने बताया है:
यदि n को यादृच्छिक रूप से चुनी गई संख्याओं की संख्या आप चुनना चाहते हैं और एन चयन के लिए उपलब्ध संख्याओं का कुल नमूना स्थान है:

  1. यदि n << N , तो आपको बस उस नंबर को संचय करना चाहिए जो आपने उठाया है और यह देखने के लिए एक सूची जांचें कि क्या उसमें चयनित संख्या है या नहीं।
  2. यदि n ~ = N , तो आप शायद मेरी पद्धति का उपयोग करें, एक सूची को पूरे नमूना स्थान को शामिल करने और फिर उसमें से संख्याओं को हटाने के लिए जैसे ही आप उन्हें चुनते हैं।
 //random numbers are 0,1,2,3 ArrayList<Integer> numbers = new ArrayList<Integer>(); Random randomGenerator = new Random(); while (numbers.size() < 4) { int random = randomGenerator .nextInt(4); if (!numbers.contains(random)) { numbers.add(random); } } 

इस छद्म-कोड द्वारा बताई गई यादृच्छिक संख्या को दोहराए जाने का सबसे प्रभावी, बुनियादी तरीका समझाया गया है नेस्टेड छोरों या हल्के लुकअप की आवश्यकता नहीं है:

 // get 5 unique random numbers, possible values 0 - 19 // (assume desired number of selections < number of choices) const int POOL_SIZE = 20; const int VAL_COUNT = 5; declare Array mapping[POOL_SIZE]; declare Array results[VAL_COUNT]; declare i int; declare r int; declare max_rand int; // create mapping array for (i=0; i<POOL_SIZE; i++) { mapping[i] = i; } max_rand = POOL_SIZE-1; // start loop searching for maximum value (19) for (i=0; i<VAL_COUNT; i++) { r = Random(0, max_rand); // get random number results[i] = mapping[r]; // grab number from map array mapping[r] = max_rand; // place item past range at selected location max_rand = max_rand - 1; // reduce random scope by 1 } 

मान लीजिए पहले पुनरावृत्ति शुरू करने के लिए यादृच्छिक संख्या 3 (0 से – 1 9)। इससे परिणाम [0] = मैपिंग [3] होगा, अर्थात, मान 3. हम तो मानचित्रण [3] से 1 9 तक आवंटित करेंगे।

अगले पुनरावृत्ति में, यादृच्छिक संख्या 5 (0 – 18 से) थी। इससे परिणाम [1] = मैपिंग [5] होगा, अर्थात, 5 मान। फिर हम मानचित्रण [5] से 18 तक आवंटित करेंगे।

अब लगता है कि अगले पुनरावृत्ति 3 फिर से चुना (0 से – 17)। नतीजे [2] को मानचित्रण [3] का मूल्य सौंपा जाएगा, लेकिन अब यह मान 3 नहीं है, लेकिन 1 9 है।

यह एक ही सुरक्षा सभी नंबरों के लिए बनी रहती है, भले ही आपको एक पंक्ति में 5 बार एक ही नंबर मिला। उदाहरण के लिए, यदि यादृच्छिक संख्या जनरेटर ने आपको पंक्ति में पांच बार दिया है, तो परिणाम होंगे: [0, 1 9, 18, 17, 16]।

आपको एक ही नंबर दो बार कभी नहीं मिलेगा

एक अनुक्रम के सभी सूचकांक उत्पन्न करना आम तौर पर एक बुरा विचार है, क्योंकि इसमें बहुत समय लग सकता है, खासकर यदि संख्याओं का अनुपात MAX को चुना जाना कम है (जटिलता O(MAX) वर्चस्व हो जाती है) यह संख्या खराब हो जाती है यदि संख्याओं का अनुपात MAX एक के लिए चुना जाता है, साथ ही सभी के अनुक्रम से चुने गए सूचकांक निकालकर भी महंगा हो जाता है (हम O(MAX^2/2) )। लेकिन छोटी संख्या के लिए, यह आम तौर पर अच्छी तरह से काम करता है और विशेष रूप से त्रुटि प्रवण नहीं है।

संग्रह का उपयोग करके उत्पन्न इंडेक्सों को छानने का भी बुरा विचार है, क्योंकि कुछ समय अनुक्रमों को क्रम में डालने में खर्च होता है, और प्रगति की गारंटी नहीं होती है क्योंकि एक ही यादृच्छिक संख्या कई बार खींची जा सकती है (लेकिन बड़ी मात्रा में यह MAX है संभावना नहीं)। यह जटिलता के करीब हो सकता है
O(kn log^2(n)/2) , डुप्लिकेटों को अनदेखा करते हुए और मानते हुए संग्रह का उपयोग कुशल लुकअप के लिए एक पेड़ का उपयोग करता है (लेकिन पेड नोड को आवंटित करने और संभवत: रिबैलेंंस के लिए महत्वपूर्ण स्थिर लागत के साथ)

एक अन्य विकल्प शुरुआत से अनोखे यादृच्छिक मूल्य उत्पन्न करना है, गारंटी की प्रगति की जा रही है। इसका मतलब है कि पहले दौर में, [0, MAX] में यादृच्छिक सूचकांक उत्पन्न होता है:

 items i0 i1 i2 i3 i4 i5 i6 (total 7 items) idx 0 ^^ (index 2) 

दूसरे दौर में, केवल [0, MAX - 1] उत्पन्न होता है (जैसा कि एक आइटम पहले से ही चुना गया था):

 items i0 i1 i3 i4 i5 i6 (total 6 items) idx 1 ^^ (index 2 out of these 6, but 3 out of the original 7) 

सूचकांकों के मूल्यों को समायोजित करने की आवश्यकता है: यदि दूसरा सूचकांक अनुक्रम के दूसरे छमाही (प्रथम सूचकांक के बाद) में पड़ता है, तो इसे अंतर के लिए खाते में वृद्धि की जानी चाहिए। हम इसे एक लूप के रूप में लागू कर सकते हैं, जिससे हमें अद्वितीय वस्तुओं की मनमानी संख्या चुनने की अनुमति मिलती है।

लघु अनुक्रमों के लिए, यह काफी तेज O(n^2/2) 2/2 O(n^2/2) एल्गोरिदम है:

 void RandomUniqueSequence(std::vector<int> &rand_num, const size_t n_select_num, const size_t n_item_num) { assert(n_select_num <= n_item_num); rand_num.clear(); // !! // b1: 3187.000 msec (the fastest) // b2: 3734.000 msec for(size_t i = 0; i < n_select_num; ++ i) { int n = n_Rand(n_item_num - i - 1); // get a random number size_t n_where = i; for(size_t j = 0; j < i; ++ j) { if(n + j < rand_num[j]) { n_where = j; break; } } // see where it should be inserted rand_num.insert(rand_num.begin() + n_where, 1, n + n_where); // insert it in the list, maintain a sorted sequence } // tier 1 - use comparison with offset instead of increment } 

जहां n_select_num आपका 5 और n_number_num आपका MAXn_Rand(x) [0, x] (समावेशी) में यादृच्छिक पूर्णांक देता है। सम्मिलन बिंदु को खोजने के लिए द्विआधारी खोज का उपयोग करके बहुत सी मदों का चयन करते हुए इसे थोड़ा तेज किया जा सकता है (उदा। 5 लेकिन 500 नहीं) ऐसा करने के लिए, हमें यह सुनिश्चित करने की आवश्यकता है कि हम आवश्यकताओं को पूरा करें।

हम द्विआधारी खोज को तुलना n + j < rand_num[j] साथ करेंगे जो कि समान है
n < rand_num[j] - j हमें यह दिखाने की जरूरत है कि rand_num[j] - j अभी क्रमबद्ध अनुक्रम rand_num[j] लिए क्रमबद्ध क्रम है। यह सौभाग्य से आसानी से दिखाया गया है, क्योंकि मूल rand_num दो तत्वों के बीच सबसे कम दूरी एक है (उत्पन्न संख्या अद्वितीय है, इसलिए हमेशा कम से कम 1 का अंतर होता है)। उसी समय, यदि हम सभी तत्वों से सूचकांक j को घटाते हैं
rand_num[j] , सूचकांक में अंतर बिल्कुल 1 है। तो "सबसे खराब" मामले में, हमें लगातार अनुक्रम मिलता है – लेकिन कभी कम नहीं होता। द्विआधारी खोज का उपयोग O(n log(n)) , O(n log(n)) एल्गोरिथ्म का उपयोग करने के लिए किया जा सकता है:

 struct TNeedle { // in the comparison operator we need to make clear which argument is the needle and which is already in the list; we do that using the type system. int n; TNeedle(int _n) :n(_n) {} }; class CCompareWithOffset { // custom comparison "n < rand_num[j] - j" protected: std::vector<int>::iterator m_p_begin_it; public: CCompareWithOffset(std::vector<int>::iterator p_begin_it) :m_p_begin_it(p_begin_it) {} bool operator ()(const int &r_value, TNeedle n) const { size_t n_index = &r_value - &*m_p_begin_it; // calculate index in the array return r_value < nn + n_index; // or r_value - n_index < nn } bool operator ()(TNeedle n, const int &r_value) const { size_t n_index = &r_value - &*m_p_begin_it; // calculate index in the array return nn + n_index < r_value; // or nn < r_value - n_index } }; 

और अंत में:

 void RandomUniqueSequence(std::vector<int> &rand_num, const size_t n_select_num, const size_t n_item_num) { assert(n_select_num <= n_item_num); rand_num.clear(); // !! // b1: 3578.000 msec // b2: 1703.000 msec (the fastest) for(size_t i = 0; i < n_select_num; ++ i) { int n = n_Rand(n_item_num - i - 1); // get a random number std::vector<int>::iterator p_where_it = std::upper_bound(rand_num.begin(), rand_num.end(), TNeedle(n), CCompareWithOffset(rand_num.begin())); // see where it should be inserted rand_num.insert(p_where_it, 1, n + p_where_it - rand_num.begin()); // insert it in the list, maintain a sorted sequence } // tier 4 - use binary search } 

मैंने इसे तीन मानदंडों पर परीक्षण किया है सबसे पहले, 7 नंबरों में से 3 नंबरों का चयन किया गया और चयनित वस्तुओं के हिस्टोग्राम को 10,000 से अधिक रनों में जमा किया गया था:

 4265 4229 4351 4267 4267 4364 4257 

यह दर्शाता है कि 7 आइटमों में से प्रत्येक को लगभग उसी समय की संख्या चुना गया था, और एल्गोरिदम के कारण कोई स्पष्ट पूर्वाग्रह नहीं है। सभी दृश्यों को शुद्धता (सामग्री की विशिष्टता) के लिए भी जांच की गई थी।

दूसरा बेंचमार्क 5000 वस्तुओं में से 7 नंबर चुनने में शामिल था। एल्गोरिदम के कई संस्करणों का समय 10,000,000 से अधिक रनों में जमा हुआ था। परिणाम b1 के रूप में कोड में टिप्पणियों में चिह्नित हैं। एल्गोरिदम का सरल संस्करण थोड़ा तेज है

तीसरे बेंचमार्क में 5000 वस्तुओं में से 700 नंबर का चयन करना शामिल था। एल्गोरिथम के कई संस्करणों का समय फिर से जमा हुआ था, इस बार 10,000 से अधिक रन। परिणाम b2 के रूप में कोड में टिप्पणियों में चिह्नित हैं। एल्गोरिदम का द्विआधारी खोज संस्करण अब सरल से दो गुना अधिक तेज है।

दूसरी विधि सीसीए की तुलना में अधिक चुनने के लिए शुरू होता है मेरी मशीन पर आइटम (ध्यान दें कि या तो एल्गोरिथ्म की जटिलता मदों की संख्या, MAX पर निर्भर नहीं करता है)

यह उल्लेख करना महत्वपूर्ण है कि उपरोक्त एल्गोरिदम क्रमशः क्रम में यादृच्छिक संख्या उत्पन्न करते हैं। लेकिन यह एक और सरणी जोड़ना आसान होगा, जिसमें संख्याओं को क्रम में सहेजा जाएगा, जिसमें वे उत्पन्न हुए थे और बदले में लौटते हैं (नगण्य अतिरिक्त लागत O(n) )। उत्पादन को घसीटना आवश्यक नहीं है: यह बहुत धीमा होगा

ध्यान दें कि स्रोत सी ++ में हैं, मेरे पास अपनी मशीन पर जावा नहीं है, लेकिन अवधारणा स्पष्ट होनी चाहिए।

संपादित करें :

मनोरंजन के लिए, मैंने सभी दृष्टिकोणों के साथ एक सूची तैयार करने वाले दृष्टिकोण को लागू किया है
0 .. MAX , उन्हें बेतरतीब ढंग से चुनता है और विशिष्टता की गारंटी के लिए उन्हें सूची से निकाल देता है। चूंकि मैंने बहुत अधिक MAX (5000) का चयन किया है, इसलिए प्रदर्शन खराब है:

 // b1: 519515.000 msec // b2: 20312.000 msec std::vector<int> all_numbers(n_item_num); std::iota(all_numbers.begin(), all_numbers.end(), 0); // generate all the numbers for(size_t i = 0; i < n_number_num; ++ i) { assert(all_numbers.size() == n_item_num - i); int n = n_Rand(n_item_num - i - 1); // get a random number rand_num.push_back(all_numbers[n]); // put it in the output list all_numbers.erase(all_numbers.begin() + n); // erase it from the input } // generate random numbers 

मैंने एक set (एक सी ++ संग्रह) के साथ दृष्टिकोण को भी लागू किया है, जो वास्तव में बेंचमार्क b2 पर दूसरी बार आता है, द्विआधारी खोज के साथ दृष्टिकोण के मुकाबले केवल 50% धीमी है यह समझ में आता है, क्योंकि set में द्विआधारी पेड़ का उपयोग होता है, जहां प्रविष्टि की लागत द्विआधारी खोज के समान होती है फर्क सिर्फ इतना है कि डुप्लिकेट आइटम मिलने की संभावना है, जो प्रगति को धीमा कर देती है।

 // b1: 20250.000 msec // b2: 2296.000 msec std::set<int> numbers; while(numbers.size() < n_number_num) numbers.insert(n_Rand(n_item_num - 1)); // might have duplicates here // generate unique random numbers rand_num.resize(numbers.size()); std::copy(numbers.begin(), numbers.end(), rand_num.begin()); // copy the numbers from a set to a vector 

पूर्ण स्रोत कोड यहां है ।

एक और दृष्टिकोण जो आपको निर्दिष्ट करने के लिए कि कितने नंबर आप size साथ चाहते हैं और लौटा संख्या के min और max मूल्य

 public static int getRandomInt(int min, int max) { Random random = new Random(); return random.nextInt((max - min) + 1) + min; } public static ArrayList<Integer> getRandomNonRepeatingIntegers(int size, int min, int max) { ArrayList<Integer> numbers = new ArrayList<Integer>(); while (numbers.size() < size) { int random = getRandomInt(min, max); if (!numbers.contains(random)) { numbers.add(random); } } return numbers; } 

इसे 0 और 25 के बीच 7 नंबरों को वापस करने के लिए उपयोग करें

  ArrayList<Integer> list = getRandomNonRepeatingIntegers(7, 0, 25); for (int i = 0; i < list.size(); i++) { System.out.println("" + list.get(i)); } 

आप सेट इंटरफ़ेस ( एपीआई ) को लागू करने वाले एक क्लास का उपयोग कर सकते हैं, और फिर प्रत्येक नंबर जो आप जेनरेट करते हैं, इसे सम्मिलित करने के लिए Set.add () का उपयोग करें।

यदि वापसी का मान झूठा है, तो आप जानते हैं कि पहले से ही संख्या पहले ही जनरेट हो चुकी है।

यह सब करने के बजाय यह एक LinkedHashSet ऑब्जेक्ट और यादृच्छिक संख्या को Math.random() फ़ंक्शन द्वारा बनाते हैं …. अगर कोई डुप्लिकेट प्रविष्टि होती है तो LinkedHashSet ऑब्जेक्ट उस नंबर को अपनी सूची में नहीं जोड़ता … इस संग्रह कक्षा में से कोई डुप्लिकेट मानों की अनुमति नहीं है .. अंत में आपको यादृच्छिक संख्याओं की सूची नहीं मिलती है, जिसमें कोई डुप्लिकेट नहीं होता …. …. D

एलएफएसआर के साथ "यादृच्छिक" आदेश संख्या करने का एक और तरीका है, पर एक नज़र डालें:

http://en.wikipedia.org/wiki/Linear_feedback_shift_register

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

लेकिन ये वास्तव में यादृच्छिक संख्या नहीं हैं क्योंकि यादृच्छिक पीढ़ी नियतात्मक है

लेकिन अपने मामले के आधार पर आप इस तकनीक का इस्तेमाल कर सकते हैं ताकि शेलिंग का उपयोग करते समय यादृच्छिक संख्या पीढ़ी पर प्रसंस्करण की मात्रा कम हो।

यहां जावा में एक एलएफएसआर एल्गोरिथ्म है, (मैंने इसे कहीं न कहीं लिया है):

 public final class LFSR { private static final int M = 15; // hard-coded for 15-bits private static final int[] TAPS = {14, 15}; private final boolean[] bits = new boolean[M + 1]; public LFSR() { this((int)System.currentTimeMillis()); } public LFSR(int seed) { for(int i = 0; i < M; i++) { bits[i] = (((1 << i) & seed) >>> i) == 1; } } /* generate a random int uniformly on the interval [-2^31 + 1, 2^31 - 1] */ public short nextShort() { //printBits(); // calculate the integer value from the registers short next = 0; for(int i = 0; i < M; i++) { next |= (bits[i] ? 1 : 0) << i; } // allow for zero without allowing for -2^31 if (next < 0) next++; // calculate the last register from all the preceding bits[M] = false; for(int i = 0; i < TAPS.length; i++) { bits[M] ^= bits[M - TAPS[i]]; } // shift all the registers for(int i = 0; i < M; i++) { bits[i] = bits[i + 1]; } return next; } /** returns random double uniformly over [0, 1) */ public double nextDouble() { return ((nextShort() / (Integer.MAX_VALUE + 1.0)) + 1.0) / 2.0; } /** returns random boolean */ public boolean nextBoolean() { return nextShort() >= 0; } public void printBits() { System.out.print(bits[M] ? 1 : 0); System.out.print(" -> "); for(int i = M - 1; i >= 0; i--) { System.out.print(bits[i] ? 1 : 0); } System.out.println(); } public static void main(String[] args) { LFSR rng = new LFSR(); Vector<Short> vec = new Vector<Short>(); for(int i = 0; i <= 32766; i++) { short next = rng.nextShort(); // just testing/asserting to make // sure the number doesn't repeat on a given list if (vec.contains(next)) throw new RuntimeException("Index repeat: " + i); vec.add(next); System.out.println(next); } } } 

आपकी समस्या n तत्वों के संग्रह से यादृच्छिक पर k तत्वों को चुनने के लिए कम लगता है संग्रह। शफल उत्तर इस प्रकार सही है, लेकिन जैसा कि अयोग्य बताया गया है: इसकी हे (एन)

विकिपीडिया: फिशर-येट्स फेरफल में ओ (के) संस्करण है जब सरणी पहले से मौजूद है। आपके मामले में, तत्वों की कोई सरणी नहीं है और तत्वों की सरणी बनाने में बहुत महंगा हो सकता है, कहें तो अधिकतम 20 की बजाय 10000000

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

आप एक ही ऑपरेशन को ओ (के) समय में हैशप के साथ कर सकते हैं, हालांकि मैं अपनी तरह की दर्द स्वीकार करता हूं। ध्यान दें कि यह केवल सार्थक है अगर k n से कम है (यानी कश्मीर ~ एलजी (एन) या ऐसा), अन्यथा आप सीधे फेरबदल का उपयोग करना चाहिए

आप अपने हैशप का उपयोग फेरबदल एल्गोरिथ्म में बैकिंग सरणी के एक कुशल प्रतिनिधित्व के रूप में करेंगे। सरणी के किसी भी तत्व को उसके सूचकांक के बराबर है, मानचित्र में प्रकट होने की आवश्यकता नहीं है। यह आपको निरंतर समय में आकार n के एक सरणी का प्रतिनिधित्व करने की अनुमति देता है, इसमें प्रारंभ करने में कोई समय नहीं है

  1. कश्मीर यादृच्छिक संख्याएं चुनें: पहली श्रेणी 0 से n-1 में है, दूसरे 0 से n-2, तीसरे 0 से n-3 और इतने पर, nk से।

  2. स्वैप का एक सेट के रूप में अपने यादृच्छिक संख्या का इलाज करें। पहले यादृच्छिक सूचकांक अंतिम स्थिति के लिए स्वैप। दूसरा रैंडम इंडेक्स दूसरे स्थान पर अंतिम स्थिति में बदल जाता है। हालांकि, बैकिंग सरणी के खिलाफ काम करने के बजाय, अपने हैशप के खिलाफ काम करें। आपका हैशप प्रत्येक वस्तु को स्टोर करेगा जो कि स्थिति से बाहर है


int getValue(i) { if (map.contains(i)) return map[i]; return i; } void setValue(i, val) { if (i == val) map.remove(i); else map[i] = val; } int[] chooseK(int n, int k) { for (int i = 0; i < k; i++) { int randomIndex = nextRandom(0, n - i); //(n - i is exclusive) int desiredIndex = ni-1; int valAtRandom = getValue(randomIndex); int valAtDesired = getValue(desiredIndex); setValue(desiredIndex, valAtRandom); setValue(randomIndex, valAtDesired); } int[] output = new int[k]; for (int i = 0; i < k; i++) { output[i] = (getValue(ni-1)); } return output; }

कार्ड बैच का एल्गोरिथ्म है: आप नंबरों का क्रमबद्ध ऑर्डर ("कार्ड बैच") बनाते हैं और प्रत्येक पुनरावर्तन में आप इसे एक यादृच्छिक स्थिति से एक नंबर का चयन करते हैं (निश्चित संख्या को "कार्ड बैच" से हटाकर)।

यहाँ एक यादृच्छिक सरणी के तेजी से निर्माण के लिए एक कुशल समाधान है। यादृच्छिकता के बाद आप सरणी के n थ एलिमेंट e को चुन सकते हैं, n और रिटर्न e । इस समाधान में ओ (1) को आरम्भिक रूप से एक यादृच्छिक संख्या और हे (एन) प्राप्त करने के लिए है, लेकिन जैसा कि एक नियंत्रण के लिए पर्याप्त मात्रा में स्मृति की आवश्यकता होती है,

संग्रह के मुकाबले पूर्णांक के लिए एक अधिक कुशल और कम बोझिल समाधान है। शफल

समस्या एक ही सेट में केवल गैर-चुने गए आइटमों से क्रमिक रूप से वस्तुओं को चुनने और दूसरे स्थान पर क्रमबद्ध करने के समान है। यह बिल्कुल बेतरतीब ढंग से निपटने वाले कार्ड या टोपी या बिन से राफेल टिकट जीतना है।

यह एल्गोरिथ्म किसी सरणी को लोड करने और लोड के अंत में एक यादृच्छिक क्रम प्राप्त करने के लिए काम करता है। यह सूची संग्रह (या किसी अन्य अनुक्रमित संग्रह) में जोड़ने के लिए और संग्रह के अंत में एक यादृच्छिक अनुक्रम को प्राप्त करने के लिए भी काम करता है।

यह एक ही सरणी के साथ किया जा सकता है, एक बार बनाया गया है, या एक संख्याबद्ध आदेश संग्रह, जैसे एक सूची, जगह में। सरणी के लिए, आरंभिक एरे आकार को सभी इच्छित मानों को शामिल करने के लिए सटीक आकार होना चाहिए। यदि आपको नहीं पता कि अग्रिम में कितने मूल्य हो सकते हैं, संख्यात्मक क्रमबद्ध संग्रह का उपयोग करके, जैसे कि एक ArrayList या सूची, जहां आकार अपरिवर्तनीय नहीं है, यह भी काम करेगा यह पूर्णांक के लिए किसी भी आकार के सरणी के लिए सार्वभौमिक रूप से काम करेगा। MAX_VALUE जो कि 2,000,000,000 से अधिक है सूची वस्तुओं की एक ही सूचकांक की सीमा होगी इससे पहले कि आप उस आकार की एक सरणी के लिए मिल अपनी मशीन स्मृति से बाहर चला सकता है। सरणी को लोड करने के बाद ऑब्जेक्ट प्रकारों को टाइप करने और इसे कुछ संग्रह में कनवर्ट करने के लिए यह अधिक कुशल हो सकता है। यह विशेष रूप से सच है अगर लक्ष्य संग्रह संख्यात्मक रूप से अनुक्रमित नहीं है।

यह एल्गोरिथ्म, जो वास्तव में लिखा गया है, बहुत अधिक वितरण बना देगा जहां कोई डुप्लिकेट नहीं है। एक महत्वपूर्ण पहलू यह है कि अगले मद के सम्मिलन के लिए मौजूदा आकार को सम्मिलित करने के लिए संभवतः 1 होना आवश्यक है। 1. इसलिए, दूसरे आइटम के लिए, इसे स्थान 0 या स्थान 1 में संग्रहीत करना संभव हो सकता है 20 वीं मद के लिए, इसे किसी भी स्थान में 1 से 1 से 1 में संग्रहीत करना संभव हो सकता है। स्थान जितना संभव हो उतना संभव है कि वह स्थान 0 पर बने रहने के लिए जैसा कि यह किसी भी अन्य स्थान पर समाप्त हो रहा है। यह अगले नए आइटम के लिए अगले नए स्थान सहित, कहीं भी जाने के लिए संभव है।

अनुक्रम की यादृच्छिकता यादृच्छिक संख्या जनरेटर की यादृच्छिकता के रूप में यादृच्छिक होगी।

यह एल्गोरिथ्म का संदर्भ सरणी में यादृच्छिक स्थानों में संदर्भ प्रकारों को लोड करने के लिए भी किया जा सकता है। चूंकि यह एक सरणी के साथ काम करता है, इसलिए यह संग्रह के साथ भी काम कर सकता है। इसका मतलब है कि आपको संग्रह बनाने की ज़रूरत नहीं है और फिर इसे फेरबदल कर या ऑब्जेक्ट को डालने के लिए जो भी ऑर्डर किया गया है उसका आदेश दिया है। संग्रह में केवल संग्रह में कहीं भी एक आइटम सम्मिलित करने की क्षमता है या उसे जोड़ना

 // RandomSequence.java import java.util.Random; public class RandomSequence { public static void main(String[] args) { // create an array of the size and type for which // you want a random sequence int[] randomSequence = new int[20]; Random randomNumbers = new Random(); for (int i = 0; i < randomSequence.length; i++ ) { if (i == 0) { // seed first entry in array with item 0 randomSequence[i] = 0; } else { // for all other items... // choose a random pointer to the segment of the // array already containing items int pointer = randomNumbers.nextInt(i + 1); randomSequence[i] = randomSequence[pointer]; randomSequence[pointer] = i; // note that if pointer & i are equal // the new value will just go into location i and possibly stay there // this is VERY IMPORTANT to ensure the sequence is really random // and not biased } // end if...else } // end for for (int number: randomSequence) { System.out.printf("%2d ", number); } // end for } // end main } // end class RandomSequence 

मेरा प्रारंभिक कोड, केवल बुनियादी सिद्धांतों का उपयोग करते हुए
यह कक्षा आपको सरणी के आकार से 1 से लेकर लेकर लेकर दो अंकों की संख्या से भरा सरणी देता है।
केवल बाहर की मदद एक यादृच्छिक संख्या उत्पन्न करने के लिए है।
सशर्त, index == count while लूप में index == count है, यह मुश्किल भाग है, और यह विधि क्या काम करती है।
मूलतः, यह पूछ रहा है: यादृच्छिक संख्या सरणी के तत्व के बराबर नहीं है, लेकिन क्या यह सरणी तत्व एक संख्या के लिए अगले पंक्ति में है?

 public class Numbers { private int MAX; // the amount of numbers private int count = 0; // counter for the array's elements private int[] nums; // the array for the numbers public Numbers(int x) { MAX = x; // MAX equal to constructor's parameter nums = new int[MAX]; // creates array object while (count < MAX) // call to drawNum() until the array is full drawNum(); } public void drawNum() { int num = (int)(Math.random()*MAX) + 1; // random number, from 1 to MAX int index = 0; // counter for while loop boolean loop = true; // conditional for while loop while (loop) { if (num == nums[index]) // if random number is equal to the array's element, end loop loop = false; if (num != nums[index] && index == count) // index == count! { nums[count] = num; // random number's added to the array, count++; // ++ to the array's counter loop = false; // end loop } index++; // ++ to the while loop counter } } } 

यह वास्तव में सभी पर निर्भर करता है कि आपको यादृच्छिक पीढ़ी के लिए क्या चाहिए, लेकिन यह मेरा लेना है।

पहले, यादृच्छिक संख्या उत्पन्न करने के लिए एक स्टैंडअलोन विधि बनाएं। सीमा के लिए अनुमति देना सुनिश्चित करें

 public static int newRandom(int limit){ return generatedRandom.nextInt(limit); } 

इसके बाद, आप मूल्यों की तुलना करते हुए एक बहुत ही सरल निर्णय संरचना बनाना चाहते हैं। यह दो तरीकों से एक में किया जा सकता है यदि आपके पास सत्यापित करने के लिए संख्याओं की बहुत सीमित संख्या है, तो एक साधारण IF स्टेटमेंट पर्याप्त होगा:

 public static int testDuplicates(int int1, int int2, int int3, int int4, int int5){ boolean loopFlag = true; while(loopFlag == true){ if(int1 == int2 || int1 == int3 || int1 == int4 || int1 == int5 || int1 == 0){ int1 = newRandom(75); loopFlag = true; } else{ loopFlag = false; }} return int1; } 

उपरोक्त int5 int5 के साथ int5 के साथ तुलना करता है, साथ ही साथ यह सुनिश्चित करने के लिए कि रैंडमों में कोई शून्य नहीं है।

जगह में इन दो तरीकों के साथ, हम निम्न कार्य कर सकते हैं:

  num1 = newRandom(limit1); num2 = newRandom(limit1); num3 = newRandom(limit1); num4 = newRandom(limit1); num5 = newRandom(limit1); 

के बाद:

  num1 = testDuplicates(num1, num2, num3, num4, num5); num2 = testDuplicates(num2, num1, num3, num4, num5); num3 = testDuplicates(num3, num1, num2, num4, num5); num4 = testDuplicates(num4, num1, num2, num3, num5); num5 = testDuplicates(num5, num1, num2, num3, num5); 

अगर आपके पास सत्यापित करने के लिए एक लंबी सूची है, तो कोड की स्पष्टता में और प्रसंस्करण संसाधनों में, एक और जटिल विधि बेहतर परिणाम देगा।

उम्मीद है की यह मदद करेगा। इस साइट ने मुझे बहुत मदद की है, मुझे कम से कम प्रयास करने के लिए बाध्य महसूस किया गया है और साथ ही साथ में मदद करने के लिए।