我需要一个无偏的均匀随机数生成器(双重),用于c或c ++的关闭区间,比如说[0,1]。
许多随机数生成器,例如GSL gsl_rng_uniform(r)
,仅在开放时间间隔内工作,如[0,1],但这不符合我的情况。
的Al。
答案 0 :(得分:6)
除非你有整数值,否则闭区间的概念有问题 - 因为击中区间“结束”的概率是无穷小的。如果您有一个整数随机数生成器,其最大值为RAND_MAX
,那么您将通过计算得到一个关闭的间隔
rand() / double(RAND_MAX)
因为它将完全从0到1(包括)
如果这不能给你足够的分辨率,你可以考虑“连接”多个随机数。假设double实际上有一个53位的尾数(加上一个“始终为1”的位),你可以这样做(这段代码假设RAND_MAX = 0xFFFFFFFF以便于阅读;你可以改进它......):
#include <stdio.h>
#include <stdlib.h>
double goodRand() {
unsigned long long r;
unsigned long long int r1, r2;
r1 = rand();
r2 = rand();
r = (r1 << 22) + (r2 & 0x003FFFFF);
return (double) r/ (double)(0x001FFFFFFFFFFFFF);
}
int main(void) {
int i;
double rMax = 0;
for (i =0; i < 10000; i++) {
double temp;
temp = goodRand();
rMax = (temp>rMax)?temp:rMax;
}
printf("max value is %lf\n", rMax);
}
现在,您可以对最大值为1.0(含)的随机数进行非常精细的采样。您可以使代码更紧凑,但这是一般的想法......
答案 1 :(得分:1)
C++11 Random怎么样,例如std :: mt19937 + std :: uniform_int_distribution?
std::mt19937 generator;
std::uniform_int_distribution<int> distribution(0,1);
int number = distribution(generator);
答案 2 :(得分:1)
std::uniform_real_distribution<double> dist{0.0, std::nextafter(1.0, 2.0)};
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng(seed);
double v = dist(eng); // a random double in the range 0.0 to 1.0 inclusive
虽然应该注意浮点分布通常在舍入和最低有效位方面并不完美。