Crappy Random Number Generator

谁都会走 提交于 2019-12-31 22:41:09

问题


This may sound like an odd question, but where can I find a random number generator that works in C or C++ that is not very good?

Context: I'm creating some tree graph plotting software and testing it by using multi-digit random numbers (so each digit becomes a node in the tree). The random number generator I've been using - which is the one that comes with the GNU C++ compiler - gives me a nice spread of values. That's good, but I want to see how the table looks when the numbers clump together and are less homogenous.

Can anyone suggest a random number generator that has been proven to be not-so-random?

(Oh, any anyone who links to xkcd and/or suggests I just return 4 will get sarcasm in response).


回答1:


I've always thought of randu as the godfather of bad random number generators.




回答2:


Implement a fairly short Linear Feedback Shift Register by using bit manipulation in C.

Most of the published material on LFSRs will concentrate on maximal sequences, but it sounds like you could sabotage one of these to produce a shorter sequence, with a little experimentation.




回答3:


The Boost library offers functions to generate random values spread over various non-uniform distributions, including the normal distribution which might generate interesting shaped trees.




回答4:


The C standard suggests:

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;
}

As a simple linear congruential generator (LCG), it isn't bad (there are many worse sets of constants you could use), but it is certainly not a good pseudo-random number generator compared to other members of the universe of cryptographic and near-cryptographic pseudo-random number generators. It might be bad enough for you, or you could consult Knuth volume 2 to look for other bad sets of numbers. (My (old) copy of Sedgewick has a rather short chapter 35 on random numbers with some illustrations of bad constants.)




回答5:


A way in which you can introduce clustering while continuing to use gcc is to randomly take two of the returned random numbers as the lower & upper brackets for a random number of iterations. Do this a few times and you should get random clustering.




回答6:


A C++ solution:

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;
};

It produces random length runs of at most maxClumpSize instances of the same random number value. (I didn't say that very clearly...hopefully you get the idea).




回答7:


Chapter 7 of the Numerical Recipes in C book addresses a variety of random number generators. Section 7.7 covers Quasi- (that is, Sub-) Random Sequences.




回答8:


Use a random number generator (Wikipedia PRNG page), with constraints.

Some other possibilities: UChicago, UMich, FSU




回答9:


use srand, but add a seed to it which doesnt change much. in fact, all pseudo-random-number-generator behave this way.

basically, just seed it with 1, then 2 then 3 .. pretty soon you will see that the "random" numbers are not so random.




回答10:


Actually, the rand() function is really quite bad. I use GameRand which is REALLY simple, and produces decent results, but it may still not be crappy enough for you.




回答11:


Often for crappy randomish-looking numbers, and I usually need deterministic ones, I compute sines and cosines of simple expressions with large-ish values and phase modulation. Typically I'm generating colors in two dimensions for graphics purposes ("procedural textures" and all that) so I'll give an example like that in generic pseudocode:

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))

Guaranteed to fail most serious tests of randomness. The results are crappy in a way that is useful for art.

It is fun to sit and play with formulas like these in an interactive plotting environment like Matlab or Python with numpy and matplotlib.



来源:https://stackoverflow.com/questions/1535654/crappy-random-number-generator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!