À partir de cette citation de Skeet:
Ce n'est pas une façon de mélanger que j'aime, principalement parce que c'est O (n log n) sans raison valable quand il est facile d'implémenter un mélange O (n). Le code de la question «fonctionne» en donnant essentiellement un numéro aléatoire ( espérons-le unique! ) À chaque élément, puis en ordonnant les éléments en fonction de ce nombre.
Je vais continuer à expliquer un peu la raison de l' unique, espérons-le!
Maintenant, à partir de Enumerable.OrderBy :
Cette méthode effectue un tri stable; c'est-à-dire que si les clés de deux éléments sont égales, l'ordre des éléments est conservé
C'est très important! Que se passe-t-il si deux éléments "reçoivent" le même nombre aléatoire? Il arrive qu'ils restent dans le même ordre qu'ils sont dans le tableau. Maintenant, quelle est la possibilité que cela se produise? Il est difficile de calculer exactement, mais il y a le problème d'anniversaire qui est exactement ce problème.
Maintenant, est-ce réel? Est-ce vrai?
Comme toujours, en cas de doute, écrivez quelques lignes de programme: http://pastebin.com/5CDnUxPG
Ce petit bloc de code mélange un tableau de 3 éléments un certain nombre de fois en utilisant l'algorithme de Fisher-Yates fait à l'envers, l'algorithme de Fisher-Yates fait en avant (dans la page wiki il y a deux algorithmes de pseudo-code ... Ils produisent l'équivalent résultats, mais l'un est fait du premier au dernier élément, tandis que l'autre est fait du dernier au premier élément), le mauvais algorithme naïf de http://blog.codinghorror.com/the-danger-of-naivete/ et en utilisant le .OrderBy(x => r.Next())
et le .OrderBy(x => r.Next(someValue))
.
Maintenant, Random.Next est
Entier signé 32 bits supérieur ou égal à 0 et inférieur à MaxValue.
donc c'est équivalent à
OrderBy(x => r.Next(int.MaxValue))
Pour tester si ce problème existe, nous pourrions agrandir le tableau (quelque chose de très lent) ou simplement réduire la valeur maximale du générateur de nombres aléatoires (ce int.MaxValue
n'est pas un nombre "spécial" ... C'est simplement un très grand nombre). En fin de compte, si l'algorithme n'est pas biaisé par la stabilité du OrderBy
, alors toute plage de valeurs devrait donner le même résultat.
Le programme teste ensuite certaines valeurs, comprises entre 1 et 4096. En regardant le résultat, il est assez clair que pour des valeurs faibles (<128), l'algorithme est très biaisé (4-8%). Avec 3 valeurs dont vous avez besoin au moins r.Next(1024)
. Si vous agrandissez le tableau (4 ou 5), cela r.Next(1024)
ne suffit même pas. Je ne suis pas un expert en shuffling et en maths, mais je pense que pour chaque bit supplémentaire de longueur du tableau, vous avez besoin de 2 bits supplémentaires de valeur maximale (car le paradoxe d'anniversaire est connecté au sqrt (numvalues)), donc que si la valeur maximale est 2 ^ 31, je dirai que vous devriez pouvoir trier des tableaux jusqu'à 2 ^ 12/2 ^ 13 bits (4096-8192 éléments)