Génération de valeurs uniques et aléatoires C #

Je cherche depuis un moment et j’ai du mal à trouver cela. J’essaie de générer plusieurs nombres aléatoires et uniques: C #. J’utilise System.Random et une valeur de départ datetime.now.ticks:

public Random a = new Random(DateTime.Now.Ticks.GetHashCode()); private void NewNumber() { MyNumber = a.Next(0, 10); } 

J’appelle régulièrement NewNumber (), mais le problème est que je reçois souvent des numéros répétés. Certaines personnes ont suggéré que parce que je déclarais le hasard chaque fois que je le faisais, cela ne produirait pas un nombre aléatoire, alors je mets la déclaration en dehors de ma fonction. Des suggestions ou de meilleurs moyens que d’utiliser System.Random? Je vous remercie

    J’appelle régulièrement NewNumber (), mais le problème est que je reçois souvent des numéros répétés.

    Random.Next ne Random.Next pas que le nombre soit unique. De plus, votre plage va de 0 à 10 et vous obtiendrez probablement des doublons. Peut-être que vous pouvez configurer une liste de int et insérer des nombres aléatoires dans la liste après avoir vérifié si elle ne contient pas le doublon. Quelque chose comme:

     public Random a = new Random(); // replace from new Random(DateTime.Now.Ticks.GetHashCode()); // Since similar code is done in default constructor internally public List randomList = new List(); int MyNumber = 0; private void NewNumber() { MyNumber = a.Next(0, 10); if (!randomList.Contains(MyNumber)) randomList.Add(MyNumber); } 

    Vous pouvez essayer de mélanger un tableau d’ints possibles si votre plage est comprise entre 0 et 9. Cela évite également tout conflit lors de la génération de nombres.

     var nums = Enumerable.Range(0, 10).ToArray(); var rnd = new Random(); // Shuffle the array for (int i = 0;i < nums.Length;++i) { int randomIndex = rnd.Next(nums.Length); int temp = nums[randomIndex]; nums[randomIndex] = nums[i]; nums[i] = temp; } // Now your array is randomized and you can simply print them in order for (int i = 0;i < nums.Length;++i) Console.WriteLine(nums[i]); 

    Je publie une implémentation correcte d’un algorithme de mélange, car l’autre qui est posté ici ne produit pas de mélange uniforme.

    Comme l’autre réponse indique, pour que de petits nombres de valeurs soient randomisés, vous pouvez simplement remplir un tableau avec ces valeurs, mélanger le tableau, puis utiliser le nombre de valeurs souhaité.

    Ce qui suit est une implémentation du Fisher-Yates Shuffle (alias le Shuthle Shuffle). (Lisez la section “erreurs d’implémentation” de ce lien (recherchez “en sélectionnant toujours j dans toute la plage d’indices de tableaux valides à chaque itération”) pour consulter un aperçu de ce qui ne va pas avec l’autre implémentation publiée ici.)

     using System; using System.Collections.Generic; namespace ConsoleApplication2 { static class Program { static void Main(ssortingng[] args) { Shuffler shuffler = new Shuffler(); List list = new List{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; shuffler.Shuffle(list); foreach (int value in list) { Console.WriteLine(value); } } } /// Used to shuffle collections. public class Shuffler { /// Creates the shuffler with a  as the random number generator. public Shuffler() { _rng = new Random(); } /// Shuffles the specified array. /// The type of the array elements. /// The array to shuffle. public void Shuffle(IList array) { for (int n = array.Count; n > 1; ) { int k = _rng.Next(n); --n; T temp = array[n]; array[n] = array[k]; array[k] = temp; } } private System.Random _rng; } } 

    Attention, je ne le recommande pas :). Voici un “oneliner” aussi:

     //This code generates numbers between 1 - 100 and then takes 10 of them. var result = Enumerable.Range(1,101).OrderBy(g => Guid.NewGuid()).Take(10).ToArray(); 

    En fonction de ce que vous voulez vraiment, vous pouvez faire quelque chose comme ceci:

     using System; using System.Collections.Generic; using System.Linq; namespace SO14473321 { class Program { static void Main() { UniqueRandom u = new UniqueRandom(Enumerable.Range(1,10)); for (int i = 0; i < 10; i++) { Console.Write("{0} ",u.Next()); } } } class UniqueRandom { private readonly List _currentList; private readonly Random _random = new Random(); public UniqueRandom(IEnumerable seed) { _currentList = new List(seed); } public int Next() { if (_currentList.Count == 0) { throw new ApplicationException("No more numbers"); } int i = _random.Next(_currentList.Count); int result = _currentList[i]; _currentList.RemoveAt(i); return result; } } } 

    Et voici ma version de la recherche de N nombres uniques aléatoires à l’aide de HashSet . Cela semble assez simple, puisque HashSet ne peut contenir que des éléments différents. C’est intéressant – serait-ce plus rapide que d’utiliser List ou Shuffler?

     using System; using System.Collections.Generic; namespace ConsoleApplication1 { class RnDHash { static void Main() { HashSet rndIndexes = new HashSet(); Random rng = new Random(); int maxNumber; Console.Write("Please input Max number: "); maxNumber = int.Parse(Console.ReadLine()); int iter = 0; while (rndIndexes.Count != maxNumber) { int index = rng.Next(maxNumber); rndIndexes.Add(index); iter++; } Console.WriteLine("Random numbers were found in {0} iterations: ", iter); foreach (int num in rndIndexes) { Console.WriteLine(num); } Console.ReadKey(); } } } 

    Cochez cette méthode prête à l’emploi: indiquez une plage et un nombre de nombres à obtenir.

     public static int[] getUniqueRandomArray(int min, int max, int count) { int[] result = new int[count]; List numbersInOrder = new List(); for (var x = min; x < max; x++) { numbersInOrder.Add(x); } for (var x = 0; x < count; x++) { var randomIndex = Random.Range(0, numbersInOrder.Count); result[x] = numbersInOrder[randomIndex]; numbersInOrder.RemoveAt(randomIndex); } return result; } 

    Vous pouvez également utiliser un dataTable stockant chaque valeur aléatoire, puis effectuer simplement la méthode aléatoire avec! = Valeurs dans le dataColumn

    Vous pouvez utiliser les fonctions aléatoires de base de C #

     Random ran = new Random(); int randomno = ran.Next(0,100); 

    vous pouvez maintenant utiliser la valeur randomno dans tout ce que vous voulez, mais gardez à l’esprit que cela générera un nombre aléatoire compris entre 0 et 100 uniquement et que vous pourrez l’étendre à n’importe quel chiffre.

    Essaye ça:

     private void NewNumber() { Random a = new Random(Guid.newGuid().GetHashCode()); MyNumber = a.Next(0, 10); } 

    Quelques explications:

    Guid : base on here : représente un identificateur global unique (GUID)

    Guid.newGuid() produit un identifiant unique comme "936DA01F-9ABD-4d9d-80C7-02AF85C822A8"

    et ce sera unique dans toute la base de l’univers ici

    Le code de hachage produit ici un entier unique à partir de notre identifiant unique

    donc Guid.newGuid().GetHashCode() nous donne un nombre unique et la classe random produira de vrais nombres aléatoires