Get a random number focused on center

2019-01-29 14:56发布

Is it possible to get a random number between 1-100 and keep the results mainly within the 40-60 range? I mean, it will go out of that range rarely, but I want it to be mainly within that range... Is it possible with JavaScript/jQuery?

Right now I'm just using the basic Math.random() * 100 + 1.

20条回答
对你真心纯属浪费
2楼-- · 2019-01-29 15:26

It looks stupid but you can use rand twice:

var choice = Math.random() * 3;
var result;

if (choice < 2){
    result = Math.random() * 20 + 40; //you have 2/3 chance to go there
}
else {
    result = Math.random() * 100 + 1;
}
查看更多
乱世女痞
3楼-- · 2019-01-29 15:28

I might do something like setup a "chance" for the number to be allowed to go "out of bounds". In this example, a 20% chance the number will be 1-100, otherwise, 40-60:

$(function () {
    $('button').click(function () {
        var outOfBoundsChance = .2;
        var num = 0;
        if (Math.random() <= outOfBoundsChance) {
            num = getRandomInt(1, 100);
        } else {
            num = getRandomInt(40, 60);
        }
        $('#out').text(num);
    });
    
    function getRandomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<button>Generate</button>
<div id="out"></div>

fiddle: http://jsfiddle.net/kbv39s9w/

查看更多
Fickle 薄情
4楼-- · 2019-01-29 15:28

If you can use the gaussian function, use it. This function returns normal number with average 0 and sigma 1.

95% of this number are within average +/- 2*sigma. Your average = 50, and sigma = 5 so

randomNumber = 50 + 5*gaussian()
查看更多
戒情不戒烟
5楼-- · 2019-01-29 15:28

The best way to do that is generating a random number that is distributed equally in a certain set of numbers, and then apply a projection function to the set between 0 and a 100 where the projection is more likely to hit the numbers you want.

Typically the mathematical way of achieving this is plotting a probability function of the numbers you want. We could use the bell curve, but let's for the sake of easier calculation just work with a flipped parabola.

Let's make a parabola such that its roots are at 0 and 100 without skewing it. We get the following equation:

f(x) = -(x-0)(x-100) = -x * (x-100) = -x^2 + 100x

Now, all the area under the curve between 0 and 100 is representative of our first set where we want the numbers generated. There, the generation is completely random. So, all we need to do is find the bounds of our first set.

The lower bound is, of course, 0. The upper bound is the integral of our function at 100, which is

F(x) = -x^3/3 + 50x^2
F(100) = 500,000/3 = 166,666.66666 (let's just use 166,666, because rounding up would make the target out of bounds)

So we know that we need to generate a number somewhere between 0 and 166,666. Then, we simply need to take that number and project it to our second set, which is between 0 and 100.

We know that the random number we generated is some integral of our parabola with an input x between 0 and 100. That means that we simply have to assume that the random number is the result of F(x), and solve for x.

In this case, F(x) is a cubic equation, and in the form F(x) = ax^3 + bx^2 + cx + d = 0, the following statements are true:

a = -1/3
b = 50
c = 0
d = -1 * (your random number)

Solving this for x yields you the actual random number your are looking for, which is guaranteed to be in the [0, 100] range and a much higher likelihood to be close to the center than the edges.

查看更多
等我变得足够好
6楼-- · 2019-01-29 15:30
var randNum;
// generate random number from 1-5
var freq = Math.floor(Math.random() * (6 - 1) + 1);
// focus on 40-60 if the number is odd (1,3, or 5)
// this should happen %60 of the time
if (freq % 2){
    randNum = Math.floor(Math.random() * (60 - 40) + 40);
}
else {
    randNum = Math.floor(Math.random() * (100 - 1) + 1);
}
查看更多
你好瞎i
7楼-- · 2019-01-29 15:31

The best solution targeting this very problem is the one proposed by BlueRaja - Danny Pflughoeft but I think a somewhat faster and more general solution is also worth mentioning.


When I have to generate random numbers (strings, coordinate pairs, etc.) satisfying the two requirements of

  1. The result set is quite small. (not larger than 16K numbers)
  2. The result set is discreet. (like integer numbers only)

I usually start by creating an array of numbers (strings, coordinate pairs, etc.) fulfilling the requirement (In your case: an array of numbers containing the more probable ones multiple times.), then choose a random item of that array. This way, you only have to call the expensive random function once per item.

查看更多
登录 后发表回答