在C ++中使用统一实分布生成的随机数并不是真正均匀分布的

时间:2015-05-31 18:32:57

标签: c++ random

我写了一个小代码,以确保我可以从一个非常广泛的范围获得随机数,例如。 [0,10 ^ 36]因为我稍后会使用这些宽范围。

我的代码如下:

private void openLocation() {
    lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    Criteria c = new Criteria();
    pro = lm.getBestProvider(c,false);
    Location l = lm.getLastKnownLocation(pro);

    if (l != null) {
        Toast.makeText(WebActivity.this, "Longitude : "+String.valueOf(l.getLongitude())+", Latitude : "+String.valueOf(l.getLatitude()), Toast.LENGTH_LONG).show();
    } else {
        Toast.makeText(WebActivity.this,"loc object is null",Toast.LENGTH_LONG).show();
    }

    mgac = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
}

以下是输出的示例:

#include <iostream>
#include <cmath>
#include <random>
#include <chrono>

int main()
{   unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    double expo = pow(10,36);
    std::uniform_real_distribution<double> dist(0,expo);
    std::mt19937_64 rng(seed);
    for (int i=0; i<10; i++)
        std::cout << dist(rng) << std::endl;
    return 0;
}   

如您所见,随机数都非常接近给定区间的上端点。我尝试多次运行程序,也将10个数字增加到100,但随机数总是接近区间的上端点(指数为35,有时为34)。

因为我使用了6.75507e+035 4.01129e+035 6.85525e+035 8.85896e+035 3.1455e+035 3.04962e+035 5.48817e+035 3.54502e+035 2.24337e+035 2.23367e+035 ,所以我希望也有,有时也会有[0,1000]范围内的数字。我发现这不是一个统一的分布。这对我来说很重要,随机数不仅接近上端点,因为我稍后会在if语句中使用随机数:

std::uniform_real_distribution

并且上端点实际上将用作速率,其中发生某些事情。但似乎随机数有时候没有机会为零。

我不知道为什么会发生这种情况,并且非常感谢任何想法或帮助。

(Eclipse 4.4.1,Windows 7)

3 个答案:

答案 0 :(得分:14)

  

正如你所看到的,随机数都非常接近上层   给定间隔的终点。

不,他们不是。这个,例如:

2.23367e+035

请注意,在[0, 1e36]范围内,子范围[1e35, 1e36]是子范围[0, 1e35]的9倍,所以通过均匀分布,您可以期待看到这些数字经常是9倍。你会看到指数为34的数字,但是任何较低的指数都会非常罕见。

答案 1 :(得分:4)

本杰明林德利的回答很好。我想补充一点,你可能正在寻找一种不同的分布而不是统一的分布。你可以这样写:

#include <iostream>
#include <cmath>
#include <random>
#include <chrono>

int main()
{
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
    std::uniform_real_distribution<double> dist(0, 36);
    std::mt19937_64 rng(seed);
    for (int i = 0; i < 20; i++)
    {
        std::cout << pow(10, dist(rng)) << std::endl;
    }
    return 0;
}

该程序给出了以下输出:

7.26972e+027
5.97e+010
3.50003e+034
3.42446e+021
2.93422e+035
111.724
2.73858e+019
55641.4
4.18253e+019
7.47441e+007
9.2706
7.45588e+009
3.26219e+007
5.6794e+027
4.67289e+026
4.24672e+014
3.97334e+010
14.7511
2.65037e+022
85279.3

答案 2 :(得分:1)

如果你看一下情况的数学,那么一个数字更有可能是指数10^35,因为每个范围都有可能的数字:

  • 9*10^34
  • 范围内有[1*10^35,1*10^36)个不同的数字
  • 9*10^33
  • 范围内有[1*10^34,1*10^35)个不同的数字
  • 1000
  • 范围内有[1,1000]个不同的数字

因此,您可以看到,数字指数10的可能性比10^3510^34倍,且数字的可能性增加9*10^32倍使指数10^35不在[1,1000]范围内。