【问题标题】:Can rand() really be this bad? [closed]rand() 真的可以这么糟糕吗? [关闭]
【发布时间】:2012-05-21 20:46:58
【问题描述】:

以上是使用 rand() 生成的示例图像,以获取随机坐标并将常数添加到这些坐标处的像素值。这是几千次迭代后的样子。我在 Mac OS X Lion 中使用 stdlib.h 中的 rand(),将 time(NULL) 作为种子。

您可以清楚地看到垂直线,就好像 x 坐标奇数的线比 x 坐标偶数的线具有更高的值。

我将如何实现一种更好的算法,或者我在哪里可以找到一个没有很多依赖项的算法? (我更喜欢只有头文件)。

这是代码(抱歉花了我这么长时间):

void generate(int iterations = 1) {
 for (unsigned int x = 0;x < (area * 4);++x) {
  map[rand() % area] += 1;
 }
 number a = min();
 number b = max();
 for (int i = 0;i < area;++i) {
  map[i] -= a;
  map[i] /= b;
 }
}

地图包含双浮点数,后来转换为 RGB 值。

【问题讨论】:

  • 您是否 100% 确定我们不能排除您使用 rand() 时出现的错误?
  • 请发布代码,显示您如何使用rand()
  • 是的,rand() 非常可怕。在大多数实现中,它只是一个简单的 LCG,可能不适合除了掷骰子之外的任何事情(即使这样,大多数程序员也会做一些愚蠢的事情,例如 rand() % 6 + 1)。
  • 代码或它没有发生。
  • 使用map[rand() / (((unsigned) RAND_MAX + 1) / area)] += 1;,而不是map[rand() % area] += 1;。这是一个改进,因为来自rand() 的高位比低位具有更好的分布,假设它是 LGC。

标签: c++ macos random


【解决方案1】:

C++11 在random 中提供了非常有用的随机数功能。请参阅herehere 了解更多详情。

【讨论】:

    【解决方案2】:

    你试过arc4random()吗?它提供了比rand() 更强大、更统一的随机值。

    您也可以尝试SecRandomCopyBytes(),它是 Security.framework 的一部分。这基本上只是从 /dev/random 读取。

    【讨论】:

      【解决方案3】:

      我认为最重要的是看看你如何使用rand() 来提取坐标。真正令人惊讶的是,您只能在 x 坐标中看到模式,而在 y 坐标中看不到。如果rand() 确实存在缺陷,则两者都应该出现。

      也就是说,我可以尝试猜测这些模式的来源:众所周知,rand() 在高位比在低位产生更多的随机性。因此,永远不要使用模数来提取较小的范围,因为这样只会得到随机性较小的低位部分。

      根据这些知识,我猜你是在提取低位来产生 x 值,而高位来提取 y 值。与沿 x 轴相比,这将为您提供沿 y 轴的随机模式。

      如果这就是您现在正在做的事情,那么您的代码中肯定还有一些伪影,这会导致 y 轴上的随机性大于 x 轴上的随机性。所以如果没有看到你的代码,很难判断这个实现是否有缺陷。

      【讨论】:

        【解决方案4】:

        在 mac 上,您可以只使用 random 而不是 rand。 random 的手册页注释如下:

        BUG

        大约是 rand(3) 速度的 2/3。

        历史上的实现曾经有一个非常弱的种子;随机序列随种子变化不大。当前的实现采用更好的伪随机数生成器进行初始状态计算。

        需要加密质量随机性的应用程序应使用 arc4random(3)。

        【讨论】:

          最近更新 更多