En programmation Java, la génération de valeurs BigInteger aléatoires dans une plage prescrite nécessite une attention particulière pour garantir une distribution uniforme et une efficacité de calcul . On pourrait initialement recourir à la multiplication du résultat de nextDouble par la limite supérieure, mais cette approche devient problématique lorsqu'il s'agit de valeurs au-delà des limites de la double précision (253).
Pour résoudre ce problème problème, la classe BigInteger fournit un constructeur approprié :
public BigInteger(int numBits, Random rnd)
Ce constructeur génère un BigInteger aléatoire compris entre 0 et (2numBits - 1), garantissant une distribution uniforme. Cependant, le défi demeure d'obtenir des valeurs dans la plage souhaitée (0 à n), où n n'est pas nécessairement une puissance de 2.
Solution :
Une solution efficace La solution consiste à utiliser une boucle :
<code class="java">BigInteger randomNumber; do { randomNumber = new BigInteger(upperLimit.bitLength(), randomSource); } while (randomNumber.compareTo(upperLimit) >= 0);</code>
En moyenne, cette boucle s'exécutera moins de deux fois, garantissant une distribution uniforme.
Optimisation pour les RNG coûteux :
Si le RNG choisi est gourmand en calcul, le nombre d'itérations peut être limité :
<code class="java">int nlen = upperLimit.bitLength(); BigInteger nm1 = upperLimit.subtract(BigInteger.ONE); BigInteger randomNumber, temp; do { temp = new BigInteger(nlen + 100, randomSource); randomNumber = temp.mod(upperLimit); } while (s.subtract(randomNumber).add(nm1).bitLength() >= nlen + 100);</code>
Cette version réduit considérablement la probabilité que la boucle soit parcourue plus d'une fois (moins de 1 sur 2100). Cependant, l'opération mod() est coûteuse en calcul, donc cette optimisation ne peut être bénéfique que si l'instance RNG est particulièrement lente.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!