2016-06-17 9 views
17

यदि आप मान उत्पन्न करने के लिए Random.Range() का उपयोग कर रहे हैं, तो श्रेणी के भीतर कुछ मानों को बाहर करने का कोई तरीका है (उदाहरण के लिए: 1 और 20 के बीच कोई संख्या चुनें, लेकिन 6 से 8 तक नहीं)?Random.Range() से मान बहिष्कृत करें?

+1

आप यह जांचने के लिए अपनी खुद की विधि लिख सकते हैं कि उत्पन्न संख्या बहिष्कृत श्रेणियों में आती है और इस मामले में इसे फिर से उत्पन्न करें। –

+1

मैंने इस प्रश्न को इस साइट पर कई यादृच्छिक संख्या विशेषज्ञों को पेश करने के लिए यादृच्छिक टैग जोड़ा है, और मेरा उत्तर कुछ विश्वसनीयता देने के लिए। – Bathsheba

उत्तर

12

यह करने के लिए सबसे अच्छा तरीका है अपने पसंदीदा जनरेटर का उपयोग करने के 1 और 17 के बीच एक पूर्णांक n उत्पन्न करने के लिए तो

if (n > 5){ 
    n += 3; 
} 

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

+1

यदि आप नमूना देते हैं और त्याग देते हैं तो भिन्नता बहुत अधिक क्यों होगी, इसकी व्याख्या (या स्पष्टीकरण से लिंक) कर सकते हैं? (क्योंकि यह मेरे लिए आश्चर्यजनक प्रतीत होता है!) – davidbak

5

हाँ, LINQ में आप सरल उपयोग where बयान

var list = Enumerable.Range(1, 20).Where(a => a < 6 || a > 8).ToArray(); 

अन्य तरीका witout LINQ

 public IEnumerable RangeBetween() 
     { 
      foreach (var i in Enumerable.Range(1, 20)) 
      { 
       if (i < 6 || i > 8) 
       { 
        yield return i; 
       } 
      } 
     } 

संपादित करें: अब मुझे सख्त सी # प्रश्न नहीं है। यह Unity और Random को प्रभावित करता है। लेकिन पूरा जवाब के लिए मैं sugest के लिए संख्या उत्पन्न आप Enumerable.Range और अगले इस प्रयोग के साथ उपरोक्त कोड का उपयोग करें:

list[Random.Next(list.Length)]; 
+0

यह गेम इंजन के लिए है। यदि आप linq से बच सकते हैं, तो इससे बचें। यह स्मृति आवंटित करता है और कुछ फ़ंक्शन आईओएस में काम नहीं करते हैं। – Programmer

+0

@ प्रोग्रामर लैम्ब्डा अभिव्यक्ति से भी बचें? –

+0

मैं यह नहीं कहूंगा।मेरा मतलब है कि अगर वह उस कोड को ज्यादातर समय बुलाता है, तो उसे इससे बचना चाहिए। – Programmer

10

तो आप वास्तव में चाहते हैं 17 (20 - 3) विभिन्न मूल्यों

[1..5] U [9..20] 

और आप कर सकते हैं कुछ इस तरह लागू:

// Simplest, not thread-safe 
    private static Random random = new Random(); 

    ... 

    int r = (r = random.Next(1, 17)) > 5 
    ? r + 3 
    : r; 

सामान्य (और जटिल) मामले में मैं सभी संभव मूल्यों की एक सरणी पैदा करने की सलाह देते हैं और फिर 0,123,516 लेइसे से आइटम:

int[] values = Enumerable 
    .Range(1, 100) // [1..100], but 
    .Where(item => item % 2 == 1) // Odd values only 
    .Where(item => !(item >= 5 && item <= 15)) // with [5..15] range excluded 
    //TODO: Add as many conditions via .Where(item => ...) as you want 
    .ToArray(); 

    ... 

    int r = values[random.Next(values.Length)]; 
+0

प्लस वन, यह सांख्यिकीय रूप से सही है; मुझे भरोसा है कि असाइनमेंट के बाईं ओर परिभाषित एक चर के लिए सशर्त परीक्षण पर असाइनमेंट सी # में अच्छी तरह परिभाषित है! – Bathsheba

+0

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

0

अगर आर 6-8 समावेशी रेंज में है यह एक अलग यादृच्छिक संख्या का चुनाव करेगा।

int r = 0; 
do 
{ 
    r = Random.Next(20); 
} while (r >= 6 && r <= 8) 
+0

मुझे लगता है कि इस विधि का उपयोग करने का एक मौका है (वास्तव में छोटा, लेकिन फिर भी) कि प्रोग्राम एक अनंत लूप में प्रवेश करता है ... यदि आपको हमेशा 6 और 8 के बीच कोई संख्या मिलती है। – Ignacio

+0

मुझे इस पर टिप्पणी करना पसंद है। यह आपके गेम को फ्रीज करने का एक शानदार तरीका है। @Ignacio आप सही हैं। ऐसा मेरे साथ पहले भी हो चुका है। यूनिटी में यादृच्छिक संख्या उत्पन्न करते समय लूप नहीं। – Programmer

+0

@ प्रोग्रामर, न केवल एकता में, यह किसी भी प्रोग्राम को – Ignacio

-1

मैं इस विषय पर अपने 2 सेंट में फेंकने जा रहा हूं। यहां एक पूर्ण श्रेणी है जो एक विधि दिखाती है जो आपकी पसंद की संख्या को छोड़कर यादृच्छिक संख्या उत्पन्न करती है और इसका उपयोग कैसे करें।

using UnityEngine; 
using System.Collections.Generic; 
using System.Linq; 

public class test2 : MonoBehaviour { 

    System.Random rand; 
    int[] excludelist; 
    void Start() 
    { 
     rand = new System.Random(); 
     excludelist = new int[] { 5,9,3}; 
     for(int i = 0; i<20;i++) 
     { 
      Debug.Log(MakeMeNumber(excludelist)); 
     } 

    } 
    private int MakeMeNumber(params int[] excludeList) 
    { 
     var excluding = new HashSet<int>(excludeList); 
     var range = Enumerable.Range(1, 20).Where(i => !excluding.Contains(i)); 


     int index = rand.Next(0, 20 - excluding.Count); 
     return range.ElementAt(index); 
    } 
} 
1

एक और तरीका वैध वापसी मूल्यों की एक सरणी बनाने के लिए है और फिर बेतरतीब ढंग से एक का चयन करें:

void Main() 
{ 
    var rng = new Random(); 
    var validValues = Enumerable.Range(1, 20).Except(new int[] {6, 7, 8}).ToArray(); 

    for (int i = 0; i < 25; i++) 
    { 
     Console.Write(validValues[rng.Next(0, validValues.Length)]); 
     Console.Write(" "); 
    } 
} 

संपादित करें: ओह! बस ध्यान दिया कि यह यूनिटी 3 डी के लिए था इसलिए यह उदाहरण उचित नहीं हो सकता है। यह मानक Random वर्ग का उपयोग कर काम करता है, हालांकि।

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