生成范围内的随机数

时间:2009-12-07 15:48:03

标签: math random

我以前做过这个,但现在我又在努力解决这个问题,我想我不理解这个问题背后的数学。

我想在1两侧的小范围内设置一个随机数。示例包括.981.02.941.1等。我找到的所有示例都描述了在0和{{1}之间获取随机数但是,我怎样才能使用它来达到我想要的范围?

编程语言并不重要,尽管我使用的是Pure Data。有人可以解释所涉及的数学吗?

15 个答案:

答案 0 :(得分:15)

均匀

如果你想要一个(伪)均匀分布(均匀间隔)在0.9和1.1之间,那么以下内容将起作用:

  range = 0.2
  return 1-range/2+rand(100)*range/100

相应地调整范围。

伪法线

如果你想要正态分布(钟形曲线),你需要特殊的代码,这将是语言/库特定的。您可以使用此代码得到近似值:

sd = 0.1
mean = 1
count = 10
sum = 0
for(int i=1; i<count; i++) 
  sum=sum+(rand(100)-50)
}
normal = sum / count
normal = normal*sd + mean

答案 1 :(得分:9)

一般来说,要获得一个范围内的随机数,您就不能获得0100之间的数字,而是获得0和{{之间的数字1}}。然而,这是无关紧要的,因为您可以通过将#除以1来获得0 - 1数字 - 所以我不会忘记这一点。

在考虑此伪代码时,您需要将1000之间的数字视为百分比。换句话说,如果我在1a之间有一个任意范围,那么两个端点之间的路径的百分比就是我随机选择的点。 (因此b的随机结果表示0.5252%之间距离的a

考虑到这一点,请以这种方式考虑问题:

  1. 设置范围的起点和终点。

    b

    var min = 0.9;

  2. 获取var max = 1.1;0之间的随机数

    1

  3. 在起点和终点范围点之间取差异var random = Math.random(); - b

    a

  4. 将您的随机数乘以差值

    var range = max - min;

  5. 以最小值添加。

    var adjustment = range * random;

  6. 并且,您可以按顺序理解每个步骤的值:

    var result = min + adjustment;

    请注意,结果保证在您的范围内。最小随机值为var min = 0.9; var max = 1.1; var random = Math.random(); // random == 0.52796 (for example) var range = max - min; // range == 0.2 var adjustment = range * random; // adjustment == 0.105592 var result = min + adjustment; // result == 1.005592 ,最大随机值为0。在这两种情况下,会发生以下情况:

    1

答案 2 :(得分:6)

return 0.9 + rand(100) / 500.0

或者我错过了什么?

答案 3 :(得分:3)

如果rand()返回0到100之间的随机数,您只需要:

(rand() / 100) * 2

获取0到2之间的随机数。

另一方面,如果您希望范围从0.9到1.1,请使用以下内容:

0.9 + ((rand() / 100) * 0.2)

答案 4 :(得分:3)

您可以通过changing variable在范围[0,1)中构建您喜欢的任何分布。特别是,如果你想要一些具有累积分布函数F的随机分布,你只需将[0,1]中的均匀随机替换为所需CDF的反函数。

一个特殊的(也许是最流行的)情况是正态分布N(0,1)。在这里,您可以使用Box-Muller transform。使用stdev进行缩放并添加均值可以获得具有所需参数的正态分布。

你可以将统一的random相加并得到一些正态分布的近似值,这个案例由上面的Nick Fortescue考虑。

如果你的源randoms是整数,你应该首先在实域中构造一个具有一些已知分布的随机数。例如,[0,1]中的均匀分布可以构造这种方式。你得到第一个整数,范围从0到99,乘以0.01,得到第二个整数,乘以0.0001并加到第一个,依此类推。这样你得到一个数字0.XXYYZZ ...双精度大约是16位十进制数字,所以你需要8个整数randoms来构造双重统一。

答案 5 :(得分:3)

Box-Müller救援。

var z2_cached;
function normal_random(mean, variance) {

    if ( z2_cached ) {
            var z2 = z2_cached;
            z2_cached = 0
            return z2 * Math.sqrt(variance) + mean;
    }

    var x1 = Math.random();
    var x2 = Math.random();

    var z1 = Math.sqrt(-2 * Math.log(x1) ) * Math.cos( 2*Math.PI * x2);
    var z2 = Math.sqrt(-2 * Math.log(x1) ) * Math.sin( 2*Math.PI * x2);

    z2_cached = z2;
    return z1 * Math.sqrt(variance) + mean;
}

使用均值1和方差值,例如0.01

for ( var i=0; i < 20; i++ ) console.log( normal_random(1, 0.01) );
0.937240893365304
1.072511121460833
0.9950053748909895
1.0034139439164074
1.2319710866884104
0.9834737343090275
1.0363970887198277
0.8706648577217094
1.0882382154101415
1.0425139197341595
0.9438723605883214
0.935894021237943
1.0846400276817076
1.0428213927823682
1.020602499547105
0.9547701472093025
1.2598174560413493
1.0086997644531541
0.8711594789918106
0.9669499056660755

功能给出约。正态分布在给定方差的均值周围。

答案 6 :(得分:2)

low + (random() / 100) * range

例如:

0.90 + (random() / 100) * 0.2

答案 7 :(得分:2)

有多近?您可以使用平均值为1且标准偏差小的Gaussian (a.k.a. Normal) distribution

如果你想要接近1的数字比远离1的数字更频繁,那么高斯是合适的。

某些语言(such as Java)将支持标准库中的高斯语。

答案 8 :(得分:1)

除以100并加1.(我假设您正在寻找从0到2的范围?)

答案 9 :(得分:1)

您需要-1到1的范围作为rand()表达式的输出。

( rand(2) - 1 )

然后根据需要将-1缩放到1范围。比如,对于任何一方的.1变体:

(( rand(2) - 1 ) / 10 )

然后只需添加一个。

(( rand(2) - 1 ) / 10 ) + 1

答案 10 :(得分:1)

Rand()已经为你提供了一个介于0和100之间的随机数。你可以得到的最大不同随机数为100因此假设你想要最多三个十进制数0.950-1.050是你的范围看着。

然后可以通过

实现分发
0.95 + ((rand() / 100) 

答案 11 :(得分:1)

你在寻找随机的没有。从1到2,如1.1,1.5,1.632等,如果是,那么这里是一个简单的python代码:

import random
print (random.random%2)+1

答案 12 :(得分:0)

var randomNumber = Math.random();
while(randomNumber<0.9 && randomNumber>0.1){
    randomNumber = Math.random();
}

if(randomNumber>=0.9){
    alert(randomNumber);
}
else if(randomNumber<=0.1){
    alert(1+randomNumber);
}

答案 13 :(得分:0)

我不明白这个(抱歉):

  

我试图在1:.98,1.02,.94,1.1等两侧设置一个随机数。

因此,我将为问题提供一般解决方案。


转换随机数生成器

如果在给定范围[0,1)*中有一个随机数生成器,并且分布均匀,您可以使用以下方法将其转换为任何分布:

1 - 将分布描述为输出范围中定义的函数,总面积为1.因此,此函数为f(x)=得到值x的概率。

2 - 整合**功能。

3 - 将其等同于“randomic” *

4 - 求解x的等式。所以ti给出了随机函数x的值。

*:任何输入分布的推广都在下面。

**:集成函数的常数项为0(也就是说,你只需丢弃它)。

**:这是一个变量,表示在[0,1]范围内生成均匀分布的随机数的结果。 [我不确定这是否是正确的英文名称]

示例

假设您想要一个分布为f(x)=x^2 from 0 to 100的值。那么这个函数没有标准化,因为范围内函数下面的总面积是1000000/3而不是1.所以你标准化它在垂直轴上缩放曲线(保持相对比例),即除以总面积:{ {1}}。

现在,我们有一个总面积为1的函数。下一步是整合它(你可能已经完成了它以获得该区域)并将它等同于随机。

综合功能是:f(x)=3*x^2 / 1000000 from 0 to 100。并将其等同于随机:F(x)=x^3/1000000+c(请记住我们丢弃常数项。)

现在,我们需要求解x的等式,得到的表达式为r=x^3/1000000。现在,您可以使用此公式生成具有所需分布的数字。

<强>概括

如果您有一个带有自定义分布的随机数生成器并想要另一个不同的任意分布,您首先需要源分布函数,然后使用它来表示目标arbirary随机数生成器。要获取分布函数,请执行最多3步。对于目标执行所有步骤,然后将randomic替换为从源分发中获得的表达式。

通过一个例子可以更好地理解......

示例

你有一个在[0,100]范围内均匀分布的随机数生成器,你想要...同样的分布x=100*r^(1/3)以简化[因为对于那个我们已经完成了给我们的所有步骤{{ 1}}]。

由于源分布是统一的,因此函数是常数:f(x)=3*x^2 / 1000000 from 0 to 100。但是我们需要对范围进行标准化,从而为我们留下:x=100*r^(1/3)

现在,我们整合它:f(z)=1。并将其等同于随机:f(z)=1/100,但这次我们没有为x解决它,而是用它来替换目标中的r:

F(z)=z/100

现在,您可以使用r=z/100来计算分布x=100*r^(1/3) where r = z/100 => x=100*(z/100)^(1/3) => x=z^(1/3) 的随机数,并以分布x=z^(1/3) [统一]中的随机数开头。

注意:如果您的分布正常,请使用铃声功能。相同的方法适用于任何其他分发。注意一些分布创建可能的渐近线,你可能需要尝试不同的方法来解决方程式。

离散分布

有时你需要表达一个离散的分布,例如,你希望得到0的概率为95%,1的概率为5%。那你怎么做的?

好吧,你用矩形分布将它除以范围连接到[0,1]并使用randomic来评估:

f(x)=3*x^2 / 1000000 from 0 to 100

或者您可以采用复杂的路径,即编写这样的分布函数(使每个选项的长度范围恰好为1):

f(z)=1/100 from 0 to 100

由于每个范围的长度为1,分配的值总和为1,因此我们知道总面积为1.现在,下一步是整合它:

         0 if r is in [0, 0.95)
f(r) = {
         1 if r is in [0.95, 1)

将其等同于随机:

         0.95 if x is in [0, 1)
f(x) = {
         0.5 if x is in [1, 2)

并解决方程......

好的,要解决这种方程式,首先应用函数计算输出范围:

         0.95*x if x is in [0, 1)
F(x) = {
         (0.5*(x-1))+0.95 = 0.5*x + 0.45 if x is in [1, 2)

现在,这些是解决方案的范围:

         0.95*x if x is in [0, 1)
r = {
         0.5*x + 0.45 if x is in [1, 2)

现在,解决内部功能:

[0, 1) becomes [0, 0.95)
[1, 2) becomes [0.95, {(0.5*(x-1))+0.95 where x = 2} = 1)

但是,由于输出是离散的,我们在执行整数部分之后得到相同的结果:

         ? if r is in [0, 0.95)
x = {
         ? if r is in [0.95, 1)

注意:使用随机意味着伪随机。


编辑:找到它on wikipedia(我知道我没有发明它)。

答案 14 :(得分:0)

对于0.9到1.1之间的数字

  

seed = 1

     

范围= 0,1

如果你的随机是0..100

  

f_rand = random / 100

生成的数字

  

gen_number =(seed + f_rand * range * 2)-range

你会得到的 1,04; 1,08; 1,01; 0,96; ...

种子3,范围2 =&gt; 1,95; 4.08; 2,70; 3,06; ...