在 C++ 中使用均匀实数分布生成的随机数并不是真正均匀分布的
Random numbers generated using uniform real distribution in C++ are not really uniformly distributed
我写了一个小代码来确保我可以从非常广泛的范围内获得随机数,例如。 [0, 10^36) 因为我稍后会用到这些大范围。
我的代码如下:
#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;
}
下面是输出示例:
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
如您所见,随机数都非常接近给定区间的上端点。我试了很多次运行这个程序,也把10个数增加到100个,但是随机数总是接近区间的上端点(指数35,有时34)。
因为我已经使用了 std::uniform_real_distribution
,所以我希望有时也有 [0, 1000] 范围内的数字。我不认为这是一个统一的分布。这对我来说很重要,随机数不仅接近上端点,因为我稍后将在 if 语句中使用随机数:
if (random_number == 0)
//do some operations
并且上端点将实际用作发生某些事情的速率。但是好像随机数有时没有机会为零。
我不知道为什么会这样,非常感谢任何想法或帮助。
(日食 4.4.1, Windows 7)
As you can see, the random numbers are all really close to the upper
endpoint of the given interval.
不,他们不是。例如这一个:
2.23367e+035
注意在范围[0, 1e36]
中,子范围[1e35, 1e36]
是子范围[0, 1e35]
的9倍,所以均匀分布,你可以期望看到这些数字的频率是原来的 9 倍。您偶尔会看到指数为 34 的数字,但任何更低的指数都非常罕见。
Benjamin Lindley 的回答很好。我想补充一点,您可能正在寻找一种不同类型的分布而不是统一分布。你可以这样写:
#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
如果你看一下这种情况的数学,一个数字更有可能具有指数 10^35
,因为每个范围内的可能数字:
- 在
[1*10^35,1*10^36)
范围内有 9*10^34
个不同的数字
- 在
[1*10^34,1*10^35)
范围内有 9*10^33
个不同的数字
[1,1000]
范围内有 1000
个不同的数字
因此您可以看到,一个数字具有指数 10^35
的可能性是 10^34
的 10
倍,并且它的可能性是 9*10^32
倍指数 10^35
而不是在 [1,1000]
.
范围内的数字
我写了一个小代码来确保我可以从非常广泛的范围内获得随机数,例如。 [0, 10^36) 因为我稍后会用到这些大范围。
我的代码如下:
#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;
}
下面是输出示例:
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
如您所见,随机数都非常接近给定区间的上端点。我试了很多次运行这个程序,也把10个数增加到100个,但是随机数总是接近区间的上端点(指数35,有时34)。
因为我已经使用了 std::uniform_real_distribution
,所以我希望有时也有 [0, 1000] 范围内的数字。我不认为这是一个统一的分布。这对我来说很重要,随机数不仅接近上端点,因为我稍后将在 if 语句中使用随机数:
if (random_number == 0)
//do some operations
并且上端点将实际用作发生某些事情的速率。但是好像随机数有时没有机会为零。
我不知道为什么会这样,非常感谢任何想法或帮助。
(日食 4.4.1, Windows 7)
As you can see, the random numbers are all really close to the upper endpoint of the given interval.
不,他们不是。例如这一个:
2.23367e+035
注意在范围[0, 1e36]
中,子范围[1e35, 1e36]
是子范围[0, 1e35]
的9倍,所以均匀分布,你可以期望看到这些数字的频率是原来的 9 倍。您偶尔会看到指数为 34 的数字,但任何更低的指数都非常罕见。
Benjamin Lindley 的回答很好。我想补充一点,您可能正在寻找一种不同类型的分布而不是统一分布。你可以这样写:
#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
如果你看一下这种情况的数学,一个数字更有可能具有指数 10^35
,因为每个范围内的可能数字:
- 在
[1*10^35,1*10^36)
范围内有 - 在
[1*10^34,1*10^35)
范围内有 [1,1000]
范围内有
9*10^34
个不同的数字
9*10^33
个不同的数字
1000
个不同的数字
因此您可以看到,一个数字具有指数 10^35
的可能性是 10^34
的 10
倍,并且它的可能性是 9*10^32
倍指数 10^35
而不是在 [1,1000]
.