2012-03-06 7 views
-8

Je sais qu'il y a beaucoup de questions sur le net, mais j'aimerais savoir pourquoi ma méthode échoue Qu'est-ce que je fais de mal?Numéro unique au hasard?

public class Generator 
{ 

    private static readonly Random random = new Random(); 

    private static readonly object SyncLock = new object(); 

    public static int GetRandomNumber(int min, int max) 
    { 
     lock (SyncLock) 
     { 
      return random.Next(min, max); 
     } 
    } 

} 


[TestFixture] 
public class Class1 
{ 
    [Test] 
    public void SimpleTest() 
    { 

     var numbers=new List<int>(); 
     for (int i = 1; i < 10000; i++) 
     { 
      var random = Generator.GetRandomNumber(1,10000); 
      numbers.Add(random); 
     } 

     CollectionAssert.AllItemsAreUnique(numbers); 

    } 
} 

EDIT La méthode de test échoue !! Désolé de ne pas mentionner

Merci pour votre temps et suggestions

+4

Échec de quelle manière? –

+0

Qu'est-ce qui ne fonctionne pas? Est-ce une erreur de compilation? Est-ce que la fonction retourne toujours le même numéro? – Msonic

+2

@Boo j'ai eu peur quand votre commentaire a surgi ...: O – xandercoded

Répondre

0
public static void FisherYatesShuffle<T>(T[] array) 
{ 
    Random r = new Random(); 
    for (int i = array.Length - 1; i > 0; i--) 
    { 
     int j = r.Next(0, i + 1); 
     T temp = array[j]; 
     array[j] = array[i]; 
     array[i] = temp; 
    } 
} 

int[] array = new int[10000]; 

for (int i = 0; i < array.Length; i++) array[i] = i; 
FisherYatesShuffle(array); 
+0

@LB cela fonctionne. Puis-je vous demander pourquoi le générique? – user9969

+0

@ user231465 juste être en mesure de mélanger n'importe quel type de tableau, pas seulement des tableaux entiers –

14

Comment pouvez-vous attendre peut-être une séquence de 10.000 nombres aléatoires à partir d'un ensemble de 10.000 valeurs possibles pour être tous uniques, sauf si vous êtes très chanceux? Ce que vous attendez est faux.

Lancez une pièce deux fois. Attendez-vous vraiment que TH et HT soient les seules séquences possibles?

Qu'est-ce qui vous fait penser que les nombres aléatoires devraient fonctionner différemment?

Cette sortie d'un générateur de nombres aléatoires est possible:

1, 1, 1, 1, 1, 1, ..., 1 

est donc ceci:

1, 2, 3, 4, 5, 6, ..., 10000 

En fait, ces deux séquences sont tout aussi susceptibles!

+0

La ligne '1..10000' contient 10k nombres uniques. Pourquoi est-ce impossible? – zerkms

+9

J'ai dit "sauf si vous êtes extrêmement chanceux." – jason

+1

@zerkms - D'accord. Pas impossible. Mais vous pouvez être assez confiant que si vous exécutiez ce programme une fois par seconde pendant la durée de vie de l'univers, vous n'obtiendriez jamais un ensemble sans doublons. Ceci est une variante du problème d'anniversaire: http://en.wikipedia.org/wiki/Birthday_problem – perfectionist

2

au hasard! = Unique

Le point ici est que votre code devrait modéliser votre problème et le vôtre ne vraiment pas. Aléatoire n'est pas égal à unique. Si vous voulez unique, vous devez obtenir votre ensemble de valeurs et les mélanger.

Si vous voulez vraiment des nombres aléatoires, vous ne pouvez pas vous attendre à ce qu'ils soient uniques. Si votre (P) RNG offre une distribution égale, alors plus de beaucoup d'essais vous devriez voir des comptes similaires de chaque valeur (voir le Law of Large Numbers). Des cas peuvent apparaître qui semblent "faux" mais vous ne pouvez pas négliger le fait que vous avez frappé ce cas par hasard.

+0

-1 N nombres uniques peuvent être générés dans O (n). OrderBy fonctionnerait dans O (n * log (n)) http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle –

+1

'Guid's sont garantis pour être unique, mais il n'y a aucune garantie qu'ils produisent valeurs suffisantes pour mélanger une séquence. Si c'est un shuffle que vous voulez, utilisez un algorithme de mélange. – jason

+2

Il est ironique que votre réponse viole le principe énoncé dans votre première phrase. Jason a raison. ** Les Guids sont une source d'unicité, et non une source de hasard **. Il n'y a aucune garantie que vous n'obteniez pas dix mille guids * déjà triés dans l'ordre *; en fait, il existe certaines versions de l'algorithme de génération de guides qui font exactement cela. –

2

Vous semblez être sous l'impression erronée que la classe Random génère une séquence de unique, bien que des nombres apparemment aléatoires. Ce n'est simplement pas le cas; caractère aléatoire implique que le prochain numéro pourrait être tout des choix possibles, pas n'importe quel sauf un que j'ai vu avant. Cela étant, il n'est pas du tout surprenant que votre test échoue: la probabilité que 10000 entiers générés aléatoirement (entre 1 et 10000 pas moins) soient uniques est minuscule.

+0

qu'en est-il de 1000? – user9969

0

Je pense que vous avez oublié de mentionner que votre méthode test échoue.

Il échoue parce que votre générateur aléatoire ne produit pas de nombres uniques. Je ne sais pas comment cela se passerait en l'état actuel.

+0

oui le test a échoué et je voulais qu'il passe pour prouver que je peux générer des nombres aléatoires Uniquement – user9969

+0

Ensuite, vous devez mettre à jour votre code pour produire ce résultat. À l'heure actuelle, l'échec du test est un résultat correct. –

+0

ok.Je voudrais mettre à jour le code pour produire le résultat mais je n'arrive pas à trouver comment? – user9969