47 votes

Quelle est la qualité de java.util.Random?

Deux questions:

Vais-je avoir différentes séquences de nombres pour chaque graine que je mets?

Y a-t-il des graines "mortes"? (Ceux qui produisent des zéros ou répètent très rapidement.)

Au fait, quels autres PRNG devrais-je utiliser?

Solution: Depuis, je vais utiliser PRNG pour créer un jeu. Je n'ai pas besoin qu'il soit cryptographiquement sécurisé. Je vais avec le Twister Mersenne, à la fois pour sa rapidité et sa période énorme.

51voto

Neil Coffey Points 13408

Dans une certaine mesure, des générateurs de nombres aléatoires sont des chevaux pour les cours. Le Hasard de classe implémente une LCG raisonnablement paramètres choisis. Mais il présente encore les caractéristiques suivantes:

Si ces choses ne comptent pas pour vous, alors Aléatoire a la caractéristique qui le dédouane de l'être fournis dans le cadre de la JDK. Il est assez bon pour des choses comme des jeux casual (mais pas celles où l'argent est impliqué). Il n'y a pas de faiblesse graines de tant que tel.

Une autre alternative qui est la XORShift générateur, ce qui peut être mis en œuvre en Java comme suit:

public long randomLong() {
  x ^= (x << 21);
  x ^= (x >>> 35);
  x ^= (x << 4);
  return x;
}

Pour certains, très bon marché, les opérations, ce qui a une période de 2^64-1 (zéro n'est pas permis), et est assez simple pour être insérée lorsque vous générez des valeurs à plusieurs reprises. Divers changement de valeurs sont possibles: voir George Marsaglia du papier sur XORShift Générateurs pour plus de détails. Vous pouvez envisager de bits dans le nombre généré comme étant tout aussi aléatoire. Une principale faiblesse est que de temps en temps il va entrer dans une "ornière" où pas beaucoup de bits sont définis dans le nombre, et ensuite, il y a quelques générations pour sortir de cette ornière.

D'autres possibilités sont:

  • combiner différents types de générateurs (par exemple nourriture la sortie d'un XORShift générateur dans une GRILLE, puis ajouter le résultat à la sortie d'un XORShift générateur avec des paramètres différents): ceci permet généralement les faiblesses des différentes méthodes pour être "lissée", et peut donner une plus longue période si les périodes de l'combiné générateurs sont choisis avec soin
  • ajouter un "lag" (pour une plus longue période): essentiellement, où un générateur normalement transformer le dernier numéro généré, stocker un historique de "tampon" et de transformer, par exemple, le (n-1023)th.

Je dirais d'éviter les générateurs qui utilisent un stupide quantité de mémoire pour vous donner une période plus longue que vous avez vraiment besoin (certains ont une période plus grande que le nombre d'atomes dans l'univers, vous n'avez généralement pas besoin de ça). Et de noter que "longue période" ne veut pas forcément dire "haute qualité générateur" (bien que 2^48 est encore un peu faible!).

10voto

Jon Skeet Points 692016

Comme zvrba dit, que JavaDoc explique la normale de la mise en œuvre. La page de Wikipédia sur les pseudo-générateurs de nombres aléatoires a une bonne quantité de l'information et mentionne le nombre de Mersenne twister, ce qui n'est pas réputé cryptographique sécurisé, mais il est très rapide et a diverses implémentations en Java. (Le dernier lien a deux implémentations, il y a les autres, je crois.)

Si vous avez besoin d'cryptographique sécurisé génération, lire la page de Wikipedia - il existe diverses options disponibles.

6voto

Michael Borgwardt Points 181658

Comme Rng aller, du Soleil, de la mise en œuvre est certainement pas de pointe, mais il est assez bon pour la plupart des besoins. Si vous avez besoin de nombres aléatoires pour la cryptographie à des fins, il y a java.de sécurité.SecureRandom, si vous voulez juste quelque chose de plus rapide et mieux que java.util.aléatoire, il est facile de trouver des implémentations Java de le Mersenne Twister sur le net.

4voto

zvrba Points 14028

Ceci est décrit dans la documentation. Linéaire des générateurs à congruence sont théoriquement bien compris et beaucoup de matériel est disponible dans la littérature et sur internet. Générateur linéaire à congruence avec les mêmes paramètres toujours les sorties de la même périodique de la séquence, et la seule chose que les semences décide est le début de la séquence. Donc la réponse à votre première question est "oui, si vous générez suffisamment de nombres aléatoires."

0voto

Dimitris Andreou Points 5398

Voir la réponse dans mon post de blog:

http://code-o-matic.blogspot.com/2010/12/how-long-is-period-of-random-numbers.html

Aléatoire a une période maximale de son état (un long, c'est à dire 2^64 de la période). Cela peut être directement généralisée à 2^k - investir autant d'état les bits que vous voulez, et vous obtenez la période maximale. 2Mersenne Twister a fait une très courte période, comparativement (voir les commentaires dans le dit blog post).

--Oups. Aléatoire se limite à 48bits, au lieu d'utiliser le 64 bits de long, de sorte que, en conséquence, sa période est de 2^48, après tout, pas 2^64.

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