web-dev-qa-db-fra.com

Random.Next renvoie toujours les mêmes valeurs

C'est vraiment bizarre, et je ne vois pas pourquoi cela se produit. Dans le cycle foreach, j'itère à travers une collection de classe A, et pour chaque classe, j'appelle la méthode Count(), où r1 et r2 les nombres sont générés à partir de la plage [-1,1]. Le problème est que Random.Next renvoie les mêmes nombres "aléatoires" pour chaque instance. Lorsque les résultats de la première instance sont 0 et -1, les mêmes seront renvoyés par les instances suivantes. S'il vous plaît, pourriez-vous me dire pourquoi cela se produit? De plus, je ne peux pas obtenir de résultats différents dans chaque instance de classe A. Voici le code:

class a
{
 Random rnd = new Random();
 private void Count()
 {
  int r1 = rnd.Next(-1, 1);
  int r2 = rnd.Next(-1, 1);
 }
}
class b
{
 List<a> listofA=new list<a>();
 foreach (a ACLASS in listofA)
 {
  ACLASS.Count();
 }
}
58
Thomas

Le problème est que vous créez des instances de la classe Random trop proches dans le temps.

Lorsque vous créez un objet Random, il est amorcé avec une valeur de l'horloge système. Si vous créez des instances Random trop proches dans le temps, elles seront toutes amorcées avec la même séquence aléatoire.

Créez un seul objet Random et transmettez sa référence au constructeur lorsque vous créez des instances de la classe "a", au lieu de créer un objet Random pour chaque instance "a".

118
Guffa

Vous créez une nouvelle instance de Random très proches les unes des autres (votre boucle est très serrée) afin que chaque instance utilise effectivement la même valeur de départ.

Une meilleure approche serait de créer une instance et de la transmettre à votre méthode Count.

Vous connaissez probablement ce morceau suivant, mais je vais l'inclure ici pour être complet:

La MSDN contient les détails à ce sujet, mais en gros votre problème est la méthode Random.Next que vous utilisez génère:

Un entier signé 32 bits supérieur ou égal à minValue et inférieur à maxValue; c'est-à-dire que la plage de valeurs de retour inclut minValue mais pas maxValue. Si minValue est égal à maxValue, minValue est renvoyé.

pour cette raison, vos appels renverront -1 ou 0.

9
ChrisF

Utilisez un seul générateur de nombres aléatoires statique pour toutes les instances de la classe.

class a
{
  private static Random rnd;
  static a() {
      rnd = new Random();
  }
  private void Count()
  {
    int r1 = rnd.Next(-1, 2);
    int r2 = rnd.Next(-1, 2);
  }
}

Notez le changement pour vous donner des nombres dans la plage -1,1 plutôt que -1,0

9
tvanfosson

Vous incluez une instance aléatoire pour chaque instance A. Il semble qu'ils obtiennent tous la même valeur de départ par défaut. Vous voulez probablement créer un aléatoire statique pour toutes les instances A et l'utiliser à plusieurs reprises, ou fournir une valeur de départ à l'instance Random () dans le constructeur A.

5
Jherico