72 votes

Random.Next retourne toujours les mêmes valeurs

C'est vraiment bizarre, et je ne peux pas comprendre pourquoi cela se produit. Dans la boucle foreach, je parcours une collection de classe A, et pour chaque classe, j'appelle la méthode Count(), où les nombres r1 et r2 sont générés dans 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 pour la première instance sont 0 et -1, les mêmes seront renvoyés pour les instances suivantes. Pourriez-vous me dire pourquoi cela se produit ? De plus, je n'arrive pas à obtenir des résultats différents pour 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 listofA=new list();
 foreach (a ACLASS in listofA)
 {
  ACLASS.Count();
 }
}

138voto

Guffa Points 308133

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

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

Créez un seul objet Random et passez 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 de "a".

4 votes

J'ai oublié aussi, j'avais le même problème il y a quelques années en créant des cartons de Bingo pour un club, et à l'époque, j'utilisais le pire truc jamais connu de l'homme : Mettre en pause le fil pendant 2 ms. Inexpérimenté et fou... Assez fou, j'ai une classe qui crée des noms aléatoires avec une déclaration statique Random en haut de tout.

15voto

tvanfosson Points 268301

Utilisez un générateur de nombres aléatoires unique et 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);
  }
}

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

0 votes

Je pense qu'avec cette gamme, cela peut aussi renvoyer 1 et ils veulent seulement 0 et -1?

0 votes

@Svante a modifié la question pour rendre l'intervalle ouvert afin de correspondre à l'exemple de code. La question initiale spécifiait un intervalle fermé, bien qu'elle n'utilisait pas de langage précis. Je pense que le code était incorrect et je vais restaurer la question pour spécifier un intervalle fermé.

0 votes

@tvanfosson Pouvez-vous me dire pourquoi cela fonctionne? Je ne comprends pas comment rendre cela statique vous donne de l'aléatoire. Je sais que cela fonctionne, mais pas pourquoi. Ils sont toujours très proches dans le temps. Merci.

9voto

ChrisF Points 74295

Vous créez de nouvelles instances de Random très proches les unes des autres (votre boucle est très serrée) donc chaque instance utilise effectivement la même valeur de graine.

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

Vous connaissez probablement déjà ce qui suit, mais je vais le inclure ici pour plus de précision :

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

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

en raison de cela, vos appels renverront -1 ou 0.

5voto

Jherico Points 12554

Vous incluez une instance aléatoire pour chaque instance A. Il semble qu'elles obtiennent toutes la même valeur de graine par défaut. Vous voulez probablement créer une instance aléatoire statique pour toutes les instances A et l'utiliser de manière répétée, ou fournir une valeur de graine à l'instance Random() dans le constructeur de A.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X