# Javaによる MersenneTwister 実装 (2002年版) ###### tags: `java` [Mersenne Twister Home Page](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/mt.html) Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,All rights reserved. ~~~java package gamelib.util; import java.util.Random; ////////////////////////////////////////////////////////////////////////// /** * MersenneTwister による乱数を生成する。 * * <H3>[MersenneTwisterについて]</H3> * <P> * Cで実装された乱数生成アルゴリズム。 * </P> * <P> * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,All rights reserved. * </P> */ public class MersenneTwister extends Random { static private final int N = 624; static private final int M = 397; static private final int MATRIX_A = 0x9908b0df; /* constant vector a */ static private final int UPPER_MASK = 0x80000000; /* most significant w-r bits */ static private final int LOWER_MASK = 0x7fffffff; /* least significant r bits */ static private final int[] MAGIC = { 0x00, MATRIX_A }; static private final int MAGIC_SEED = 19650218; static private final int DEFAULT_SEED = 5489; private int[] mt = new int[ N ]; private int mti; private int[] seedBuf; // size = 2. ( 32, 32 bits integer store for [little-endian] ) ////////////////////////////////////////////////////////////////////////// /** * MersenneTwister インスタンスを生成する。 */ public MersenneTwister() { /* a default initial seed is used */ this( DEFAULT_SEED ); } ////////////////////////////////////////////////////////////////////////// /** * 指定した値を種として MersenneTwister インスタンスを生成する。 */ public MersenneTwister( long seed ) { setSeed( seed ); } ////////////////////////////////////////////////////////////////////////// /** * シードを設定する。 */ public void setSeed( long seed ) { if( seedBuf == null ) { seedBuf = new int[ 2 ]; } seedBuf[ 0 ] = (int)seed; seedBuf[ 1 ] = (int)seed >>> 32; setSeed( seedBuf ); } ////////////////////////////////////////////////////////////////////////// /** * シードを設定する。 */ private void setSeed( int seed ) { if( mt == null ) { mt = new int[ N ]; } mt[ 0 ] = seed; for( mti = 1; mti < N; mti++ ) { mt[ mti ] = ( 1812433253 * ( mt[ mti - 1 ] ^ ( mt[ mti - 1 ] >>> 30 ) ) + mti ); } } ////////////////////////////////////////////////////////////////////////// /** * シードを設定する。 */ public void setSeed( int[] seedBuffer ) { int length = seedBuffer.length; if( length == 0 ) { throw new IllegalArgumentException( "seedBuffer is empty" ); } int i = 1; int j = 0; int k = ( N > length ? N : length ); setSeed( MAGIC_SEED ); for( ; k > 0; k-- ) { mt[ i ] = ( mt[ i ] ^ ( ( mt[ i - 1 ] ^ ( mt[ i - 1 ] >>> 30 ) ) * 1664525 ) ) + seedBuffer[ j ] + j; i++; j++; if( i >= N ) { mt[ 0 ] = mt[ N - 1 ]; i = 1; } if( j >= length ) j = 0; } for( k = N - 1; k > 0; k-- ) { mt[ i ] = ( mt[ i ] ^ ( ( mt[ i - 1 ] ^ ( mt[ i - 1 ] >>> 30 ) ) * 1566083941 ) ) - i; i++; if( i >= N ) { mt[ 0 ] = mt[ N - 1 ]; i = 1; } } mt[ 0 ] = UPPER_MASK; // MSB is 1; assuring non-zero initial array } ////////////////////////////////////////////////////////////////////////// /** * 次の擬似乱数を生成する。 * @see Random#next(int) */ synchronized protected int next( int bits ) { int y; if( mti >= N ) { /* generate N words at one time */ int kk; if( mti == N + 1 ) { /* if not initialized */ setSeed( DEFAULT_SEED ); /* a default initial seed is used */ } for( kk = 0; kk < N - M; kk++ ) { y = ( mt[ kk ] & UPPER_MASK ) | ( mt[ kk + 1 ] & LOWER_MASK ); mt[ kk ] = mt[ kk + M ] ^ (int)( y >>> 1 ) ^ MAGIC[ (int)( y & 0x1L ) ]; } for( ; kk < N - 1; kk++ ) { y = ( mt[ kk ] & UPPER_MASK ) | ( mt[ kk + 1 ] & LOWER_MASK ); mt[ kk ] = mt[ kk + ( M - N ) ] ^ (int)( y >>> 1 ) ^ MAGIC[ (int)( y & 0x1L ) ]; } y = ( mt[ N - 1 ] & UPPER_MASK ) | ( mt[ 0 ] & LOWER_MASK ); mt[ N - 1 ] = mt[ M - 1 ] ^ (int)( y >>> 1 ) ^ MAGIC[ (int)( y & 0x1L ) ]; mti = 0; } y = mt[ mti++ ]; /* Tempering */ y ^= ( y >>> 11 ); y ^= ( y << 7 ) & 0x9d2c5680L; y ^= ( y << 15 ) & 0xefc60000L; y ^= ( y >>> 18 ); return y >>> ( 32 - bits ); } } ~~~
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up