简体   繁体   English

影响Math.random()

[英]Influence Math.random()

I'm looking for a way to influence Math.random(). 我正在寻找一种影响Math.random()的方法。

I have this function to generate a number from min to max: 我有这个函数来生成从最小到最大的数字:

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

Is there a way to make it more likely to get a low and high number than a number in the middle? 有没有办法让它更容易得到一个低和高的数字而不是中间的数字?

For example; 例如; rand(0, 10) would return more of 0,1,9,10 than the rest. rand(0,10)将返回0,1,9,10比其余的更多。

Is there a way to make it more likely to get a low and high number than a number in the middle? 有没有办法让它更容易得到一个低和高的数字而不是中间的数字?

Yes. 是。 You want to change the distribution of the numbers generated. 您想要更改生成的数字的分布。

http://en.wikipedia.org/wiki/Random_number_generation#Generation_from_a_probability_distribution http://en.wikipedia.org/wiki/Random_number_generation#Generation_from_a_probability_distribution

One simple solution would be to generate an array with say, 100 elements. 一个简单的解决方案是生成一个包含100个元素的数组。

In those 100 elements represent the numbers you are interested in more frequently. 在这100个元素中,更频繁地表示您感兴趣的数字。

As a simple example, say you wanted number 1 and 10 to show up more frequently, you could overrepresent it in the array. 举个简单的例子,假设您想要更频繁地显示数字1和数字10,您可以在数组中过多地表示它。 ie. 即。 have number one in the array 20 times, number 10 in the array 20 times, and the rest of the numbers in there distributed evenly. 数组中的第一个20次,数组中的数字10次20次,其余数字均匀分布。 Then use a random number between 0-100 as the array index. 然后使用0-100之间的随机数作为数组索引。 This will increase your probability of getting a 1 or a 10 versus the other numbers. 这将增加你获得1或10的概率与其他数字相比。

You need a distribution map. 你需要一个分布图。 Mapping from random output [0,1] to your desired distribution outcome. 从随机输出[0,1]映射到您期望的分布结果。 like [0,.3] will yield 0, [.3,.5] will yield 1, and so on. 如[0,.3]将产生0,[。3,.5]将产生1,依此类推。

Sure. 当然。 It's not entirely clear whether you want a smooth rolloff so (for example) 2 and 8 are returned more often than 5 or 6, but the general idea works either way. 目前还不完全清楚你是否想要一个平滑的滚降,所以(例如)2和8的返回频率通常超过5或6,但一般的想法无论哪种方式都有效。

The typical way to do this is to generate a larger range of numbers than you'll output. 这样做的典型方法是生成比输出更大的数字范围。 For example, lets start with 5 as the base line occurring with frequency N. Let's assume that you want 4 or 7 to occur at frequency 2N, 3 or 8 at frequency 3N, 2 or 9 and frequency 4N and 0 or 10 at frequency 5N. 例如,让我们从5开始,作为以频率N出现的基线。假设您希望4或7频率为2N,3或8,频率为3N,2或9,频率为4N,0或10频率为5N 。

Adding those up, we need values from 1 to 29 (or 0 to 28, or whatever) from the generator. 添加它们,我们需要来自生成器的1到29(或0到28,或其他)的值。 Any of the first 5 gives an output of 0. Any of the next 4 gives and output of 1. Any of the next 3 gives an output of 2, and so on. 前5个中的任何一个给出0的输出。接下来的4中的任何一个给出和输出1.接下来的3中的任何一个给出2的输出,依此类推。

Of course, this doesn't change the values returned by the original generator -- it just lets us write a generator of our own that produces numbers following the distribution we've chosen. 当然,这不会改变原始生成器返回的值 - 它只是让我们编写一个我们自己的生成器,它根据我们选择的分布生成数字。

Not really. 并不是的。 There is a sequence of numbers that are generated based off the seed. 存在基于种子生成的一系列数字。 Your random numbers come from the sequence. 你的随机数来自序列。 When you call random, you are grabbing the next element of the sequence. 当你随机调用时,你正在抓住序列的下一个元素。

Can you influence the output of Math.random in javascript (which runs client side)? 你可以在javascript(运行客户端)中影响Math.random的输出吗?

No. At least not in any feasible/practical manner. 不,至少不是以任何可行/实际的方式。

But what you could do is to create your own random number generator that produces number in the distribution that you need. 但是你可以做的是创建自己的随机数生成器,在你需要的发行版中产生数字。

There are probably an infinite number of ways of doing it, and you might want to think about the exact shape/curvature of the probability function. 可能有无数种方法,你可能想要考虑概率函数的确切形状/曲率。

It can be probably be done in one line, but here is a multi-line approach that uses your existing function definition (named rand , here): 它可能可以在一行中完成,但这是一个使用现有函数定义的多行方法(在这里命名为rand ):

var dd = rand(1,5) + rand(0,5);
var result;
if (dd > 5)
    result = dd - 5;
else result = 6 - dd;

One basic result is that if U is a random variable with uniform distribution and F is the cumulative distribution you want to sample from, then Y = G(X) where G is the inverse of F has F as its cumulative distribution. 一个基本结果是,如果U是具有均匀分布的随机变量,而F是要从中采样的累积分布,则Y = G(X)其中G是F的倒数,其中F为其累积分布。 This might not necessarily be the most efficient way of doing and generating random numbers from all sort of distributions is a research subfield in and of itself. 这可能不一定是最有效的方法,并且从所有类型的分布中生成随机数本身就是一个研究子域。 But for a simple transformation it might just do the trick. 但是对于一个简单的转换,它可能就是这样做的。 Like in your case, F(x) could be 4*(x-.5)^3+.5, it seems to satisfy all constraints and is easy to invert and use as a transformation of the basic random number generator. 与你的情况类似,F(x)可以是4 *(x-.5)^ 3 + .5,它似乎满足所有约束并且易于反转并用作基本随机数发生器的变换。

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

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