高效且随机分布很好的随机数发生器MersenneTwister

分类:代码, 博客 标签:

普通的随机数发生器产生的伪随机数经常存在周期比较短,或者效率不高,或者随机分布特征不佳等缺点,这里给出的是一个高效的而且随机分布特征很不错的MersenneTwister随机数发生器,下面是源代码。

class MersenneTwister { 
	var state
	var next
	var left	
	
	function MersenneTwister() {
		state = new Array(624+1);   
		next = 0;                   
		left = -1;                  
	}
	
	function seedMT(seed) {
		var x = ((seed & 0xFFFFFFFF) | 1);
        var i;                            
        
        seed = x;

        left = 0;
        i = 0;    
        state[i++] = x;       
        var j = 624;
        
        while (j>0) {                 
            x *= 69069;
            x &= 0xFFFFFFFF;
            state[i++] = x;
			j--
        }        
        
        return seed;
	}
	
	function reloadMT() {
		var p0 = 0;
        var p2 = 2;
        var pM = 397;
        var s0;
        var s1;
        var j;
    
        if (left < -1) {        
            // not seeded, use standard seed value.
            seedMT(4357);                          
        }
    
        left = 624-1;
        next = 1;
            
        s0 = state[0];
        s1 = state[1];
        var j = 624-397+1;
        
        while (j>0) {
            state[p0++] = state[pM++] ^ ((((s0 & 0x80000000) | (s1 & 0x7FFFFFFF)) >> 1) & 0x7FFFFFFF) ^ ((s1 & 0x00000001) ? 0x9908B0DF : 0);
            s0 = s1;
            s1 = state[p2++];
			j--
        }
         
        pM = 0;
        var j = 397;
        while (j>0) {
            state[p0++] = state[pM++] ^ ((((s0 & 0x80000000) | (s1 & 0x7FFFFFFF)) >> 1) & 0x7FFFFFFF) ^ ((s1 & 0x00000001) ? 0x9908B0DF : 0);
            s0 = s1;
            s1 = state[p2++];
			j--
        }
    
        s1 = state[0];
        state[p0] = state[pM] ^ ((((s0 & 0x80000000) | (s1 & 0x7FFFFFFF)) >> 1) & 0x7FFFFFFF) ^ ((s1 & 0x00000001) ? 0x9908B0DF : 0);

        s1 ^= (s1 >> 11) & 0x001FFFFF;
        s1 ^= (s1 <<  7) & 0x9D2C5680;
        s1 ^= (s1 << 15) & 0xEFC60000;
        return (s1 ^ ((s1 >> 18) & 0x00003FFF));
	}
	
	function randomMT() {
		var y;
    
        if (--left < 0) {
            return reloadMT();
        }
    
        y  = state[next++];
        y ^= (y >> 11) & 0x001FFFFF;
        y ^= (y <<  7) & 0x9D2C5680;
        y ^= (y << 15) & 0xEFC60000;
        return (y ^ ((y >> 18) & 0x00003FFF));
	}
	
	function rangedMT(low, high) {
		// var custom_range = high - low + 1;
		var r = randomMT();                              
		if (r < 0)
			r += 4294967296.0;	// make it an unsigned number!
		return Math.floor(((r * (high - low + 1)) / 4294967296.0 + low));
	}
	
}


分类:代码, 博客 标签:

发表评论

You must be logged in to post a comment.