Est-il possible d'obtenir un nombre aléatoire entre 1-100 et de garder les résultats principalement dans la plage 40-60? Je veux dire, il sortira rarement de cette plage, mais je veux qu'il soit principalement dans cette plage ... Est-ce possible avec JavaScript / jQuery?
En ce moment, j'utilise simplement la base Math.random() * 100 + 1
.
javascript
algorithm
random
numbers
Darryl Huffman
la source
la source
Réponses:
Le moyen le plus simple serait de générer deux nombres aléatoires de 0 à 50 et de les additionner.
Cela donne une distribution biaisée vers 50, de la même manière en roulant deux biais de dés vers 7.
En fait, en utilisant un plus grand nombre de "dés" (comme le suggère @Falco) , vous pouvez faire une approximation plus proche d'une courbe en cloche:
JSFiddle: http://jsfiddle.net/797qhcza/1/
la source
Vous avez ici de bonnes réponses qui donnent des solutions spécifiques; permettez-moi de vous décrire la solution générale. Le problème est:
La solution générale à ce problème consiste à déterminer la fonction quantile de la distribution souhaitée, puis à appliquer la fonction quantile à la sortie de votre source uniforme.
La fonction quantile est l' inverse de l' intégrale de votre fonction de distribution souhaitée . La fonction de distribution est la fonction où l'aire sous une partie de la courbe est égale à la probabilité que l'élément choisi au hasard soit dans cette partie.
Je donne un exemple de la façon de le faire ici:
http://ericlippert.com/2012/02/21/generating-random-non-uniform-data/
Le code qu'il contient est en C #, mais les principes s'appliquent à n'importe quel langage; il devrait être simple d'adapter la solution à JavaScript.
la source
Prendre des tableaux de nombres, etc. n'est pas efficace. Vous devez prendre un mappage qui prend un nombre aléatoire compris entre 0 et 100 et correspond à la distribution dont vous avez besoin. Donc, dans votre cas, vous pourriez prendre pour obtenir une distribution avec le plus de valeurs au milieu de votre plage.
f(x)=-(1/25)x2+4x
la source
x
entre 0 et 100 (tirée de cette question ):y = (Math.sin(2 * Math.PI * (x/100 - 1/4)) + 1) / 2
Je pourrais faire quelque chose comme configurer une "chance" pour que le nombre soit autorisé à "sortir des limites". Dans cet exemple, 20% de chances que le nombre soit 1-100, sinon 40-60:
violon: http://jsfiddle.net/kbv39s9w/
la source
J'avais besoin de résoudre ce problème il y a quelques années et ma solution était plus facile que toutes les autres réponses.
J'ai généré 3 aléas entre les bornes et les ai moyennes. Cela tire le résultat vers le centre mais laisse tout à fait possible d'atteindre les extrémités.
la source
BellFactor
de 3.Cela a l' air stupide mais vous pouvez utiliser rand deux fois:
la source
Bien sûr, c'est possible. Faites un 1-100 aléatoire. Si le nombre est <30, générer un nombre compris entre 1 et 100 sinon générer entre 40 et 60.
la source
Il existe de nombreuses façons de générer de tels nombres aléatoires. Une façon de le faire est de calculer la somme de plusieurs nombres uniformément aléatoires. Le nombre de nombres aléatoires que vous additionnez et leur plage détermineront à quoi ressemblera la distribution finale.
Plus vous additionnez de chiffres, plus il sera biaisé vers le centre. L'utilisation de la somme d'un nombre aléatoire était déjà proposée dans votre question, mais comme vous le constatez, elle n'est pas biaisée vers le centre de la plage. D'autres réponses ont proposé d'utiliser la somme de 2 nombres aléatoires ou la somme de 3 nombres aléatoires .
Vous pouvez obtenir encore plus de biais vers le centre de la plage en prenant la somme de nombres plus aléatoires. À l'extrême, vous pourriez prendre la somme de 99 nombres aléatoires qui étaient chacun 0 ou 1. Ce serait une distribution binomiale. (Les distributions binomiales peuvent dans un certain sens être considérées comme la version discrète des distributions normales). Cela peut toujours en théorie couvrir toute la gamme, mais il a tellement de biais vers le centre que vous ne devriez jamais vous attendre à le voir atteindre les points d'extrémité.
Cette approche signifie que vous pouvez modifier le niveau de biais souhaité.
la source
Qu'en est-il de l'utilisation de quelque chose comme ceci:
La façon dont je l'ai codé vous permet de définir quelques variables:
boucles = nombre d' essais de résultats
= nombre de fois où la fonction essaiera d'obtenir un nombre compris entre 40 et 60 avant d'arrêter de parcourir la boucle while
Bonus supplémentaire: il utilise do while !!! L'émerveillement à son meilleur
la source
Vous pouvez écrire une fonction qui mappe des valeurs aléatoires entre
[0, 1)
à et en[1, 100]
fonction du poids. Considérez cet exemple:Ici, la valeur
0.95
correspond à une valeur entre[61, 100]
.En fait, nous avons
.05 / .1 = 0.5
, ce qui, une fois mappé à[61, 100]
, donne81
.Voici la fonction:
la source
Voici une solution pondérée à 3/4 40-60 et 1/4 en dehors de cette plage.
la source
Ok, j'ai donc décidé d'ajouter une autre réponse parce que je me sentais comme ma dernière réponse, ainsi que la plupart des réponses ici, utilisent une sorte de méthode semi-statistique pour obtenir un retour de résultat de type courbe en cloche. Le code que je fournis ci-dessous fonctionne de la même manière que lorsque vous lancez un dé. Par conséquent, il est plus difficile d'obtenir 1 ou 99, mais plus facile d'en obtenir 50.
la source
Je recommanderais d'utiliser la distribution bêta pour générer un nombre compris entre 0 et 1, puis l'agrandir. Il est assez flexible et peut créer de nombreuses formes de distribution différentes.
Voici un échantillonneur rapide et sale:
la source
la source
La meilleure solution ciblant ce problème est celle proposée par BlueRaja - Danny Pflughoeft mais je pense qu'une solution un peu plus rapide et plus générale mérite également d'être mentionnée.
Quand je dois générer des nombres aléatoires (chaînes, paires de coordonnées, etc.) satisfaisant aux deux exigences de
Je commence généralement par créer un tableau de nombres (chaînes, paires de coordonnées, etc.) répondant à l'exigence (dans votre cas: un tableau de nombres contenant les plus probables plusieurs fois.), Puis choisissez un élément aléatoire de ce tableau. De cette façon, vous n'avez qu'à appeler la fonction aléatoire coûteuse une fois par article.
la source
Distribution
Solution
Solution générique
la source
Vous pouvez utiliser un nombre aléatoire d'aide pour générer des nombres aléatoires en 40-60 ou 1-100:
la source
Si vous pouvez utiliser la
gaussian
fonction, utilisez-la. Cette fonction renvoie un nombre normal avecaverage 0
etsigma 1
.95% de ce nombre sont à l'intérieur
average +/- 2*sigma
. Votreaverage = 50
, etsigma = 5
ainsila source
La meilleure façon de le faire est de générer un nombre aléatoire qui est réparti également dans un certain ensemble de nombres, puis d'appliquer une fonction de projection à l'ensemble compris entre 0 et 100, où la projection est plus susceptible d'atteindre les nombres souhaités.
En règle générale, la manière mathématique d'y parvenir consiste à tracer une fonction de probabilité des nombres que vous souhaitez. Nous pourrions utiliser la courbe en cloche, mais pour un calcul plus facile, travaillons simplement avec une parabole retournée.
Faisons une parabole telle que ses racines soient à 0 et 100 sans l'incliner. Nous obtenons l'équation suivante:
Maintenant, toute l'aire sous la courbe entre 0 et 100 est représentative de notre premier ensemble où nous voulons que les nombres soient générés. Là, la génération est complètement aléatoire. Donc, tout ce que nous devons faire est de trouver les limites de notre premier ensemble.
La borne inférieure est, bien sûr, 0. La borne supérieure est l'intégrale de notre fonction à 100, qui est
Nous savons donc que nous devons générer un nombre compris entre 0 et 166 666. Ensuite, nous devons simplement prendre ce nombre et le projeter dans notre deuxième ensemble, qui est compris entre 0 et 100.
Nous savons que le nombre aléatoire que nous avons généré est une intégrale de notre parabole avec une entrée x entre 0 et 100. Cela signifie que nous devons simplement supposer que le nombre aléatoire est le résultat de F (x) et résoudre pour x.
Dans ce cas, F (x) est une équation cubique et sous la forme
F(x) = ax^3 + bx^2 + cx + d = 0
, les affirmations suivantes sont vraies:La résolution de ceci pour x vous donne le nombre aléatoire réel que vous recherchez, ce qui est garanti d'être dans la plage [0, 100] et une probabilité beaucoup plus élevée d'être proche du centre que des bords.
la source
Cette réponse est vraiment bonne . Mais je voudrais publier des instructions d'implémentation (je ne suis pas en JavaScript, donc j'espère que vous comprendrez) pour différentes situations.
Supposons que vous ayez des plages et des poids pour chaque plage:
Les informations statiques initiales peuvent être mises en cache:
Boundary[n] = Boundary[n - 1] + weigh[n - 1]
etBoundary[0] = 0
. L'échantillon aBoundary = {0, 1, 3, 103, 108}
Génération de nombres:
N
partir de la plage [0, somme de tous les poids).for (i = 0; i < size(Boundary) && N > Boundary[i + 1]; ++i)
i
plage et générez un nombre aléatoire dans cette plage.Remarque supplémentaire pour les optimisations de performances. Les plages ne doivent être ordonnées ni dans l'ordre croissant ou décroissant, donc pour une plage de recherche de plage plus rapide qui a le poids le plus élevé doit aller en premier et une avec le poids le plus bas doit aller en dernier.
la source