Générer un nombre aléatoire avec max, min et moyenne (moyenne) en Java
Question
Je dois générer des nombres aléatoires avec les propriétés suivantes.
Min doit être 200
Max devrait être 20000
est de 500 moyenne (moyenne).
Facultatif: 75e centile pour être 5000
Sans aucun doute il n'est pas une distribution uniforme, ni gaussienne. Je dois donner une dissymétrie gauche.
La solution
Java aléatoire ne fonctionnera probablement pas parce que cela ne vous donne des distributions normales (gaussiennes).
Qu'est-ce que vous cherchez probablement est une distribution f (voir ci-dessous). Vous pouvez probablement utiliser la bibliothèque distlib et choisissez f répartition . Vous pouvez utiliser les aléatoire méthode pour obtenir votre numéro aléatoire.
Autres conseils
Dites X
est votre variable cible, permet de normaliser la plage en faisant Y=(X-200)/(20000-200)
. Alors maintenant, vous voulez une variable aléatoire qui prend Y
valeurs [0,1]
avec (500-200)/(20000-200)=1/66
moyenne.
Vous avez beaucoup d'options, le plus naturelle me semble un Beta Distribution , Y ~ Beta(a,b)
avec a/(a+b) = 1/66
- vous avez un degré de liberté supplémentaire, que vous pouvez choisir pour correspondre à la dernière exigence de quartile
Après cela, vous revenez simplement X Y*(20000-200)+200
Pour générer une variable aléatoire Beta, vous pouvez utiliser Apache Commons ou voir .
Cela peut ne pas être la réponse que vous cherchez, mais le cas spécifique avec 3 distributions uniformes:
(Ignorer les chiffres sur la gauche, mais il est à l'échelle!)
public int generate() {
if(random(0, 65) == 0) {
// 50-100 percentile
if(random(1, 13) > 3) {
// 50-75 percentile
return random(500, 5000);
} else {
// 75-100 percentile
return random(5000, 20000);
}
} else {
// 0-50 percentile
return random(200, 500);
}
}
Comment je suis arrivé les chiffres
En premier lieu, l'aire sous la courbe est égale entre 200-500 et 5-20000. Cela signifie que le rapport de la hauteur est prise 300 * leftHeight == 19500 * rightHeight
leftHeight == 65 * rightHeight
Cela nous donne une chance de choisir 1/66 droite, et un 65/66 chance de choisir gauche.
I a ensuite fait le même calcul pour le 75ème percentile, sauf que le rapport était 500-5000 chance == 5000-20000 chance * 10 / 3
. Encore une fois, cela signifie que nous ont une chance d'être dans 10/13 50-75 percentile, et une chance 3/13 être en 75-100.
Kudos à @Stas -. J'utilise sa fonction 'aléatoire inclusive'
Et oui, je me rends compte mes chiffres sont faux que cette méthode fonctionne avec des nombres discrets, et mes calculs étaient continus. Il serait bon que quelqu'un pourrait corriger mes affaires à la frontière.
On peut avoir une fonction f de travail sur [0; 1], tels que
Integral(f(x)dx) on [0;1] = 500
f(0) = 200
f(0.75) = 5000
f(1) = 20000
Je suppose que fonction de la forme
f(x) = a*exp(x) + b*x + c
pourrait être une solution, il vous suffit de résoudre le système connexe.
Ensuite, vous faites f(uniform_random(0,1))
et vous y êtes!
Le PERT (ou bêta- la distribution PERT ) est conçu pour un minimum et maximum et le mode estimé. Il est une version « lissée-out » de la distribution triangulaire, et la génération d'un nombre aléatoire de cette distribution peut être mis en œuvre comme suit:
startpt + (endpt - startpt) *
BetaDist(1.0 + (midpt - startpt) * shape / (endpt - startpt),
1.0 + (endpt - midpt) * shape / (endpt - startpt))
où -
-
startpt
est le minimum, -
midpt
est le mode (pas nécessairement la moyenne ou moyenne), -
endpt
est le maximum, -
shape
est un nombre 0 ou plus, mais le plus souvent 4 et -
BetaDist(X, Y)
renvoie un nombre aléatoire de la distribution bêta avec des paramètresX
etY
.
Étant donné une moyenne connue (mean
), midpt
peut être calculé par:
3 * mean / 2 - (startpt + endpt) / 4