0

我找不到像 (0,1) 这样的开区间从均匀分布生成随机数的方法。

(double)rand()/RAND_MAX;

这将包括 0 和 1 吗?如果是,在开区间生成随机数的正确方法是什么?

4

4 回答 4

1

看看std::uniform_real_distribution<cstdlib>您可以使用比std::rand()内置的更专业的伪随机数生成器。这是一个打印出 [0,1) 范围内的 10 个随机数的代码示例:

#include <iostream>
#include <random>

int main()
{  
    std::default_random_engine generator;
    std::uniform_real_distribution<double> distribution(0.0,1.0);

    for (int i=0; i<10; ++i)
        std::cout << distribution(generator) << endl;

    return 0; 
}

完全为零的可能性很小。如果不得到 0 对您很重要,您可以检查它并生成另一个数字。

当然,您可以使用指定的随机数引擎std::mt19937(即“非常”随机)或最快的std::knuth_b.

于 2013-11-12T18:54:16.960 回答
0

我已经很久没有写过 C++ 了,但是试试下面的代码:

double M = 0.00001, N = 0.99999;
double rNumber = M + rand() / (RAND_MAX / (N - M + 1) + 1);
于 2013-11-12T16:08:04.130 回答
0

我已经很多年没有用 C++ 编程了,但是当我这样做时,rand 的实现是特定于编译器的。实现方式各不相同,它们是否涵盖 [0,RAND_MAX]、[0,RAND_MAX)、(0,RAND_MAX] 或 (0,RAND_MAX)。这可能已经改变,我相信如果有的话,有人会加入。

假设实现是在闭区间 [0,RAND_MAX] 上,那么(double)(rand()+1)/(RAND_MAX+2);应该产生一个开区间 U(0,1),除非RAND_MAX正在推高字长,在这种情况下强制转换为长。如果您的生成器覆盖范围不同,请调整附加常数。

更好的解决方案是放弃rand并使用 Boost 库中的 Mersenne Twister 之类的东西。MT 有不同的调用,可以明确地让您控制结果的开/关范围。

于 2013-11-12T16:12:06.713 回答
0

给定具有闭区间 [a, b] 的 RNG 的均匀分布,最简单的方法是简单地丢弃不需要的值并再次掷骰子。这在数值上是稳定的,实际上是保持均匀性最快的方法。

 double myRnD()
 {
    double a = 0.0;
    while (a == 0.0 || a == 1.0) a = (double)rand() * (1.0 / (double)RAND_MAX);
    return a;
 }

(免责声明:RAND_MAX 必须是 2 的幂且 < 2^52)

于 2013-11-12T16:30:18.620 回答