蹩脚的随机数发生器

时间:2009-10-08 04:38:42

标签: algorithm language-agnostic random

这可能听起来像一个奇怪的问题,但在哪里可以找到一个在C或C ++中工作的随机数生成器不是很好?

上下文:我正在创建一些树形图绘制软件并使用多位随机数对其进行测试(因此每个数字都成为树中的一个节点)。我一直在使用的随机数生成器 - 这是GNU C ++编译器附带的随机数生成器 - 给了我很好的价值分布。这很好,但是我希望看到当数字聚集在一起并且不那么同质时表格看起来如何。

任何人都可以建议一个被证明不是随机的随机数发生器吗?

(哦,任何链接到xkcd和/或建议我只返回4的人都会得到回应的讽刺)。

11 个答案:

答案 0 :(得分:8)

我一直认为randu是不良随机数生成器的教父。

答案 1 :(得分:3)

通过在C中使用位操作来实现相当短的Linear Feedback Shift Register

LFSR上发表的大多数材料都集中在最大序列上,但听起来你可以通过一些实验来破坏其中一个以产生更短的序列。

答案 2 :(得分:3)

Boost library提供了生成遍布各种非均匀分布的随机值的函数,包括可能生成有趣形状树的正态分布。

答案 3 :(得分:2)

C标准建议:

static unsigned long int next = 1;

int rand(void) // RAND_MAX assumed to be 32767
{
    next = next * 1103515245 + 12345;
    return (unsigned int)(next/65536) % 32768;
}

void srand(unsigned int seed)
{
    next = seed;
}

作为一个简单的线性同余生成器(LCG),它还不错(你可以使用许多更糟糕的常量集),但与宇宙的其他成员相比,它肯定不是一个好的伪随机数生成器加密和近加密伪随机数发生器。对你来说可能已经够糟糕了,或者你可以咨询Knuth第2卷来寻找其他不好的数字。 (我的(旧)副本塞奇威克在随机数字上有一个相当短的第35章,其中有一些不良常数的插图。)

答案 4 :(得分:1)

C ++解决方案:

class ClumpedRandom
{
  public:
    ClumpedRandom(int maxClumpSize) 
     : mMaxClump(maxClumpSize)
     , mCurrentClumpSize(0)
     , mCurrentCount(0)
    {
       if (!sInitialized) {
         sInitialized = true;
         srand(time(NULL));
       } 
    }

    int operator()()
    {
      if (++mCurrentCount >= mCurrentClumpSize) {
        // Need a new clump:
        mCurrentClumpSize = rand() % mMaxClump;
        mCurrentCount = 0;
        mCurrentValue = rand();
      }

      return mCurrentValue;   
    }


  private:
    static bool sInitialized;
    int mMaxClump;
    int mCurrentClumpSize;
    int mCurrentCount;
    int mCurrentValue;
};

它生成最多相同随机数值的maxClumpSize实例的随机长度运行。 (我没有说得很清楚......希望你能得到这个想法)。

答案 5 :(得分:1)

在继续使用gcc的同时可以引入聚类的方法是随机将两个返回的随机数作为低位&随机迭代次数的上括号。这样做几次,你应该得到随机聚类。

答案 6 :(得分:1)

使用带有约束的随机数生成器(Wikipedia PRNG page)。

其他一些可能性:UChicagoUMichFSU

答案 7 :(得分:1)

Chapter 7 of the Numerical Recipes in C本书涉及各种随机数生成器。第7.7节涵盖准(即子)随机序列。

答案 8 :(得分:0)

使用srand,但是添加一个没有变化的种子。实际上,所有伪随机数生成器都是这样的。

基本上,只用1,然后是2然后3来播种..很快你就会看到“随机”数字不是那么随机。

答案 9 :(得分:0)

实际上,rand()函数非常糟糕。我使用的GameRand非常简单,产生了不错的结果,但它可能仍然不够蹩脚。

答案 10 :(得分:0)

通常对于蹩脚的随机数字,我通常需要确定性数字,我计算具有大值和相位调制的简单表达式的正弦和余弦。通常我会为了图形目的而在二维中生成颜色(“程序纹理”和所有这些),所以我将在通用伪代码中给出一个例子:

for i=1,N
  for j=1,N
    value[i*n+j] = sin(51*i*i+cos(80*j)) + sin(300*j+3*sin(111*i-j))

保证最严重的随机性测试失败。结果很糟糕,对艺术有用。

在Matlab或Python等交互式绘图环境中使用numpy和matplotlib来坐下来玩这样的公式很有趣。