web-dev-qa-db-fra.com

Comment va Java.Util.Random?

Deux questions:

Vais-je obtenir différentes séquences de chiffres pour chaque graine que je me suis mise?

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

Au fait, qui, le cas échéant, d'autres PRNG devrais-je utiliser?

Solution: Depuis, je vais utiliser le PRNG Pour faire une partie, je n'ai pas besoin de la sécurité cryptographique. Je vais avec la Twister Mersenne, les deux pour c'est vitesse et période énorme.

47
Dove

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

Si ces choses ne comptent pas pour vous, alors aléatoire a la caractéristique rachetée d'être fournie dans le cadre de la JDK. C'est assez bon pour des choses comme des jeux occasionnels (mais pas ceux où l'argent est impliqué). Il n'y a pas de graines faibles en tant que telles.

Une autre alternative qui est le Xorshift Generator , qui peut être implémentée dans Java comme suit:

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

Pour certaines opérations très bon marché, cela a une période de 2 ^ 64-1 (zéro n'est pas autorisé) et est suffisamment simple pour être inlincé lorsque vous générez des valeurs à plusieurs reprises. Diverses valeurs de changement de vitesse sont possibles: voir le papier de George Marsaglia sur les générateurs Xorshift pour plus de détails. Vous pouvez envisager des bits dans les numéros générés comme étant aussi aléatoires. Une faiblesse principale est que, de temps en temps, il entrera dans une "rut" où peu de bits sont définis dans le nombre, puis il faut quelques générations pour sortir de cette ornière.

D'autres possibilités sont:

  • combinez différents générateurs (par exemple, d'alimenter la sortie d'un générateur Xorshift dans un LCG, puis ajoutez le résultat à la sortie d'un générateur Xorshift avec différents paramètres): cela permet généralement de "lisser les faiblesses des différentes méthodes d'être" lissé "et peut Donnez une période plus longue si les périodes combinées sont soigneusement choisies
  • ajouter un "décalage" (pour donner une période plus longue): essentiellement, où un générateur transformerait normalement le dernier nombre généré, stocker un "tampon d'histoire" et transformera, disons, le (N-1023) TH.

Je dirais éviter les générateurs qui utilisent une quantité stupide de mémoire pour vous donner une période plus longue que nécessaire (certains ont une période supérieure au nombre d'atomes de l'univers, vous n'avez vraiment pas besoin de cela). Et notez que "une longue période" ne signifie pas nécessairement que "Générateur de haute qualité" (bien que 2 ^ 48 reste un peu bas!).

50
Neil Coffey

Comme le dit ZVRBA, Javadoc explique la mise en œuvre normale. La page Wikipedia sur les générateurs de nombres pseudo-aléatoires a une juste quantité d'informations et mentionne le Mersenne Twister , qui n'est pas jugée cryptographiquement sécurisée, mais est très rapide et a diverses - implémentations en Java . (Le dernier lien a deux implémentations - il y a d'autres disponibles, je crois.)

Si vous avez besoin de génération sécurisée cryptographiquement, lisez la page Wikipedia - il existe différentes options disponibles.

10
Jon Skeet

Alors que les rngs vont, la mise en œuvre de Sun est certainement pas à la pointe de la réserve , mais suffisamment bien à la plupart des fins. Si vous avez besoin de nombres aléatoires à des fins de cryptographie, il y a java.security.securerandandom , si vous voulez juste quelque chose de plus rapide et mieux que Java.Util.random, il est facile de trouver Java Mises en œuvre de la twister Mersenne sur le net.

6
Michael Borgwardt

Ceci est décrit dans la Documentation . Les générateurs congrandentiels linéaires sont théoriquement bien compris et beaucoup de matériel sur eux sont disponibles dans la littérature et sur Internet. Le générateur confortable linéaire avec les mêmes paramètres émet toujours la même séquence périodique, et la seule chose que la graine décide d'où commence la séquence. Donc, la réponse à votre première question est "Oui, si vous génèverez suffisamment de nombres aléatoires".

4
zvrba

Voir la réponse dans mon article de blog:

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

Aléatoire a une période maximale pour son état (une longue, I.E. 2 ^ 64). Cela peut être directement généralisé à 2 ^ k - Investissez autant de bits d'état que vous le souhaitez, et vous obtenez la période maximale. 2Mersenne Twister a en fait un = short Période, comparativement (voir les commentaires dans ledit blog post).

--Oups. Aléatoire se limite à 48bits, au lieu d'utiliser les 64 bits complètes d'une longue, donc en conséquence, sa période est 2 ^ 48 après tout, pas 2 ^ 64.

0
Dimitris Andreou