How can I best generate a static array of random number on demand?

后端 未结 8 844
北海茫月
北海茫月 2021-01-14 06:56

An application I\'m working on requires a matrix of random numbers. The matrix can grow in any direction at any time, and isn\'t always full. (I\'ll probably end up re-imple

8条回答
  •  旧时难觅i
    2021-01-14 07:28

    PRNGs can be built out of hash functions.
    This is what e.g. MS Research did with parallelizing random number generation with MD5 or others with TEA on a GPU.
    (In fact, PRNGs can be thought of as a hash function from (seed, state) => nextnumber.)
    Generating massive amounts of random numbers on a GPU brings up similar problems.
    (E.g., to make it parallel, there should not be a single shared state.)

    Although it is more common in the crypto world, using a crypto hash, I have taken the liberty to use MurmurHash 2.0 for sake of speed and simplicity. It has very good statistical properties as a hash function. A related, but not identical test shows that it gives good results as a PRNG. (unless I have fsc#kd up something in the C# code, that is.:) Feel free to use any other suitable hash function; crypto ones (MD5, TEA, SHA) as well - though crypto hashes tend to be much slower.

    public class LazyRandomMatrix
    {
        private uint seed;
    
        public LazyRandomMatrix(int seed)
        {
            this.seed = (uint)seed;
        }
    
        public int this[int x, int y]
        {
            get
            {
                return MurmurHash2((uint)x, (uint)y, seed);
            }
        }
    
        static int MurmurHash2(uint key1, uint key2, uint seed)
        {
            // 'm' and 'r' are mixing constants generated offline.
            // They're not really 'magic', they just happen to work well.
    
            const uint m = 0x5bd1e995;
            const int r = 24;
    
            // Initialize the hash to a 'random' value
    
            uint h = seed ^ 8;
    
            // Mix 4 bytes at a time into the hash
    
            key1 *= m;
            key1 ^= key1 >> r;
            key1 *= m;
    
            h *= m;
            h ^= key1;
    
            key2 *= m;
            key2 ^= key2 >> r;
            key2 *= m;
    
            h *= m;
            h ^= key2;
    
            // Do a few final mixes of the hash to ensure the last few
            // bytes are well-incorporated.
    
            h ^= h >> 13;
            h *= m;
            h ^= h >> 15;
    
            return (int)h;
        }
    
    }
    

提交回复
热议问题