简体   繁体   English

带有递归的随机数JavaScript

[英]JavaScript for Random Numbers with Recursion

I'm trying to create a javascript function that accepts 2 parameters min and max and generates a random number between the two integers. 我正在尝试创建一个JavaScript函数,该函数接受2个参数minmax并在两个整数之间生成一个随机数。 That part is easy. 这部分很容易。

Where things get rough is that I need to create a conditional that says 事情变得艰难的地方是我需要创建一个条件

function generateNum (min, max) {
  var randNumber = Math.ceil(Math.random()*(max - min)+min);

  if (randNumber === max) {
    // store the result (probably in an array) and generate a new 
    // number with the same behavior as randNumber (e.g. it is also
    // stores it's total in the array and recursively "re-generates 
    // a new number until max is not hit)
  }
}

The idea is to recursive-ise this so that a running total of the number of max hits is stored, combined, and then returned. 这个想法是递归实现的,这样就可以存储,组合然后返回最大点击数的运行总数。

For example: The script receives min / max parameters of 5/10 generateNum(5,10){} . 例如:该脚本接收的最小/最大参数为5/10 generateNum(5,10){} If the value generated by randNumber were 5, 6, 7, 8, or 9 then there would be no recursion and the function would return that value. 如果randNumber生成的值为randNumber或9,则将没有递归,并且该函数将返回该值。 If the value generated by randNumber is 10 , then the value 10 is stored in an array and the function now "re-tries" recursively (meaning that as many times as 10 is generated, then that value is stored as an additional object in the array and the function re-tries). 如果randNumber生成的randNumber 10 ,则将值10存储在数组中,并且该函数现在以递归方式“重randNumber ”(意味着生成的次数多达10次,则该值将作为附加对象存储在数组,然后函数重试)。 When the process stops (which could be infinite but has a parabolically decreasing probability of repeating with each recursion). 当过程停止时(可能是无限的,但是每次递归重复的概率都在下降)。 The final number (5, 6, 7, 8, 9) would be added to the total of generated max values and the result would be returned. 最后的数字(5、6、7、8、9)将被添加到所生成的max的总数中,并返回结果。

Quite an unusual mathematic scenario, let me know how I can clarify if that doesn't make sense. 相当不同寻常的数学场景,请让我知道如何澄清这是否没有道理。

That part is easy. 这部分很容易。

Not as easy as you think... The algorithm that you have is broken; 不像您想的那么容易。。。您所拥有的算法已损坏; it will almost never give you the minimum value. 它几乎永远不会给您最小值。 Use the Math.floor method instead, and add one to the range: 请改用Math.floor方法,然后在范围内添加一个:

var randNumber = Math.floor(Math.random() * (max - min + 1)) + min;

To do this recursively is simple, just call the method from itself: 递归执行此操作很简单,只需从自身调用该方法:

function generateNum (min, max) {
  var randNumber = Math.floor(Math.random()*(max - min + 1)) + min;
  if (randNumber == max) {
    randNumber += generateNum(min, max);
  }
  return randNumber;
}

You can also solve this without recursion: 您也可以解决此问题而无需递归:

function generateNum (min, max) {
  var randNumber = 0;
  do {
    var num = Math.floor(Math.random()*(max - min + 1)) + min;
    randNumber += num;
  } while (num == max);
  return randNumber;
}

There is no need to use an array in either case, as you don't need the seprate values in the end, you only need the sum of the values. 在任何一种情况下都不需要使用数组,因为最后不需要单独的值,因此只需要这些值的总和即可。

I assume that you don't really need a recursive solution since you tagged this for-loop . 我假设您实际上不需要递归解决方案,因为您已标记了此for-loop This will return the number of times the max number was picked: 这将返回选择最大数量的次数:

function generateNum (min, max) {
    var diff = max - min;
    if(diff <= 0)
        return;

    for(var i = 0; diff == Math.floor(Math.random()*(diff + 1)); i++);

    return i;
}

Example outputs: 输出示例:

generateNum(1,2)  // 3
generateNum(1,2)  // 1
generateNum(1,2)  // 0
generateNum(5,10) // 0
generateNum(5,10) // 1

Recursive method: 递归方法:

function generateNum (min, max) {
  var res = Math.floor(Math.random() * (max - min + 1)) + min;

  return (res === max) ? [res].concat(generateNum(min, max)) : res;
}

Two things: 两件事情:

1) the probability to roll 10 stays (theoretically the same on each roll (re-try)), the low probability is of hitting n times 10 in a row 1)掷出10张的概率保持不变(理论上每次掷出相同(重试)),低概率是连续击中n乘10

2) I don't see why recursion is needed, what about a while loop? 2)我不明白为什么需要递归,而while循环又如何呢?

 var randNumber;
 var arr = [];
 while ((randNumber = Math.ceil(Math.random()*(max - min)+min)) === max) {
   arr.push(
 }

I'd consider an idea that you don't need to use not only recursion and arrays but not even a for loop. 我认为,您不仅不需要使用递归和数组,甚至不需要使用for循环。 I think you need a simple expression like this one (separated into three for clarity): 我认为您需要一个像这样的简单表达(为了清楚起见,请分成三个部分):

function generateNum (min, max)
{
    var randTail = Math.floor(Math.random()*(max - min)+min);
    var randRepeatMax = Math.floor(Math.log(Math.random()) / Math.log(1/(max-min+1)));
    return randRepeatMax*max + randTail;
}

Assuming one random number is as good as another, this should give you the same distribution of values as the straightforward loop. 假设一个随机数与另一个随机数一样好,这将为您提供与直接循环相同的值分布。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM