1

一段时间以来,我一直在用 C++ 中的这些随机数扯掉我的头发。

在 Python 中,我有很棒的:

random.uniform(0, 1)

每次我调用它时都会产生一个新的随机数。

C++必须有这样的东西。我在 Google 上搜索了很长时间,发现了erand48(),我计划将其实现到我的光线追踪器中(我正在将它从 Python 翻译成 C++)。

我尝试了一个简单的测试用例,但我希望创建一个random_uniform()总是吐出一个新随机数的函数(使用time()AFAICT 是行不通的,因为它运行得非常快)

unsigned short Xi[3] = {0, 1, 27};
std::cout << erand48(Xi);

输出是(并且每次我调用程序时都会如此):

0.174529

我尝试使用以前的输出作为新的Xi,像这样(Xi定义了 s 初始值):

float random_uniform() {
  long generated = erand48(Xi);
  int temp = generated * 1000000;

  unsigned short Xi[3] = {temp - 16, temp - 7, temp - 18};

  return generated;
}

但这似乎不会产生足够随机的数字(而且它只会吐出来0。我,不知道为什么......)。

有什么方法可以让我每次都吐出一个新的随机数?

4

4 回答 4

3

不熟悉 python,我将假设 random.uniform(0, 1) 从 0 和 1 之间的均匀分布中吐出一个随机数?

如果是这样,请尝试以下操作:

srand(time(NULL));
float myRand = ((float) rand( )) / RAND_MAX;

请注意,您的里程可能会有所不同 - rand() 不能保证是非常高质量的随机数源。根据实现和使用方式,您可能会得到视觉效果。我在光线追踪器中使用了 Mersenne Twister 随机数生成器。

编辑:为了更清楚一点,那就是:

...
void init_program ( )
{
    ...
    srand(time(NULL));
    ...
}
...
float random_uniform ( )
{
    return ((float) rand( )) / RAND_MAX;
}
...

如果你同时调用两者srandrand你​​很可能每次都得到相同的“随机”数字,因为除非同时发生变化,否则time你会用完全相同的种子播种生成器,因此得到完全相同的相同的第一个随机数。

于 2011-05-06T02:35:41.310 回答
2

您是否有理由不只是使用rand()C++ 标准库的一部分?您所指的功能是单一 UNIX 规范的一部分,但可能不可移植......

您一遍又一遍地获得相同值的原因是因为您没有播种随机数生成器,因此它的行为具有确定性。使用srand()orsrand48()如果您对 UNIX 特定的功能没问题并且需要 48 位精度。 只在程序开始时调用一次,然后通过time(NULL). 不用担心使用time(),因为你只调用这个函数一次,你不必担心总是得到相同的时间值。

您可能还想参考此页面,了解如何从中获取返回值rand()并将其有效缩放到您想要的范围:

使用 C 或 C++ rand() 函数


编辑:返回并erand48再次阅读文档。您会注意到它返回 [0, 1) 范围内的双精度数。你把它放在一个很长的地方,这可能就是你总是看到零的原因(该值被截断为整数)。我还认为它可能会unsigned long使用序列中的当前数字为您更新数组的值——您提供存储,它使用它来“跟踪”序列。

尝试:

unsigned short xsubi[3] = { 0, 1, 27 };
for (int i = 0; i < 10; ++i)
{
   double value = erand48(xsubi);
   printf("%f\n", value);
}
于 2011-05-06T02:39:27.860 回答
1

是的-它被称为std::rand(),以标准形式出现并以<cstdlib>.

http://msdn.microsoft.com/en-us/library/398ax69y(v=VS.100).aspx

于 2011-05-06T02:34:01.967 回答
1

可能想研究Boost.Random

于 2011-05-06T02:47:54.613 回答