Problèmes de génération de nombres aléatoires dans les boucles
Cet article aborde un problème courant rencontré lors de l'utilisation de Random.Next()
dans des boucles : des itérations consécutives produisant des nombres aléatoires identiques. Le problème se manifeste souvent lorsque plusieurs Random
objets sont instanciés en succession rapide.
Scénario de problème :
Considérez l'extrait de code suivant :
<code class="language-csharp">class A { Random rnd = new Random(); public void Count() { int r1 = rnd.Next(-1, 1); int r2 = rnd.Next(-1, 1); // ... further code using r1 and r2 ... } } class B { List<A> listOfA = new List<A>(); public B() { // ... populate listOfA ... foreach (A instance in listOfA) { instance.Count(); } } }</code>
Si listOfA
contient plusieurs instances de la classe A
, chaque objet A
crée sa propre instance Random
. En raison de l'instanciation à grande vitesse, ces Random
objets peuvent recevoir la même valeur de départ (souvent dérivée de l'horloge système), conduisant à des séquences de nombres aléatoires identiques.
Cause fondamentale :
Le problème vient de la dépendance du constructeur Random
par défaut à l'égard de l'horloge système pour l'amorçage. Si plusieurs Random
objets sont créés dans un laps de temps très court, ils reçoivent des valeurs de départ pratiquement identiques, ce qui entraîne une génération de nombres pseudo-aléatoires identiques.
Solution : instance aléatoire unique
La solution est simple : créez une seule Random
instance et réutilisez-la dans toutes les instances de la classe A
. Cela garantit qu'une séquence unique et non répétitive de nombres aléatoires est générée.
Voici le code corrigé :
<code class="language-csharp">class A { private Random rnd; public A(Random rnd) { this.rnd = rnd; } public void Count() { int r1 = rnd.Next(-1, 1); int r2 = rnd.Next(-1, 1); // ... further code using r1 and r2 ... } } class B { Random rnd = new Random(); List<A> listOfA = new List<A>(); public B() { // ... populate listOfA, passing rnd to the constructor ... foreach (A instance in listOfA) { instance.Count(); } } }</code>
En injectant la seule instance Random
(rnd
) dans le constructeur de classe A
, nous garantissons que tous les appels à rnd.Next()
tirent de la même séquence correctement amorcée. Cela élimine efficacement la génération de nombres aléatoires en double.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!