2009-10-31 6 views
47

Ceci est vraiment bizarre, et je ne vois pas pourquoi cela se produit. Dans le cycle 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 à 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 passe? En outre, je ne peux pas obtenir des résultats différents dans chaque instance de classe A. Voici le code:Random.Next retourne toujours les mêmes valeurs

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(); 
} 
} 

Répondre

94

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

Lorsque vous créez un objet Random, il est ensemencé avec une valeur provenant de l'horloge système. Si vous créez des instances Random trop proches dans le temps, elles seront toutes ensemencé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".

+1

J'ai oublié aussi, je l'habitude d'avoir de nouveau la même question dans la journée à faire du Bingo pour les cartons un club, et à l'époque, j'ai utilisé le pire truc jamais connu de l'homme: Pause du fil pour 2 Mme inexpérimentée et folle ... Assez fou, j'ai une classe qui crée des noms aléatoires avec une déclaration aléatoire statique sur le dessus de tout. –

5

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 bien fournir une valeur de départ à l'instance Random() dans le constructeur A.

8

Vous créez une nouvelle instance de Random très proche (votre boucle est très serrée), de sorte 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 savez problably ce bit suivant, mais je vais l'inclure ici pour être complet:

Le MSDN a les détails à ce sujet, mais au fond, votre problème est la méthode que vous utilisez Random.Next génère:

Entier signé de 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 renvoyé.

à cause de cela vos appels retourneront -1 ou 0.

7

Utilisez un seul, statique générateur de nombres aléatoires 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 de vous donner des chiffres dans la gamme -1,1 plutôt que -1,0

+0

je pense qu'avec cette gamme il peut aussi retourner 1 et ils veulent seulement 0 et -1? – Lucas

+0

@Svante a édité la question pour rendre l'intervalle ouvert pour correspondre à l'échantillon de code.La question initiale spécifiait un intervalle fermé, sans utiliser de langage précis. Je pense que le code était incorrect et je vais restaurer la question pour spécifier un intervalle fermé. – tvanfosson

+0

@tvanfosson Pouvez-vous me dire pourquoi cela fonctionne? Je ne comprends pas comment faire de cette statique vous donne un caractère aléatoire. Je sais que ça marche, mais pas pourquoi. Ils sont toujours très proches dans le temps. Merci. – johnny

Questions connexes