⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mersennetwister.java

📁 一个用于排队系统仿真的开源软件,有非常形象的图象仿真过程!
💻 JAVA
字号:
/*
 * MersenneTwister.java
 *
 *
 * Created on 13 novembre 2002, 17.57
 */

package jmt.engine.random.engine;

/** This is a Java version of the Mersenne Twister.
 * Coded by Takuji Nishimura and Makoto Matsu.
 * <br>
 *<br>Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
 *  All rights reserved.
 * <br><br>
 * Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  <br>
 *    1. Redistributions of source code must retain the above Copyright
 *       notice, this list of conditions and the following disclaimer.
 *  <br>
 *   2. Redistributions in binary form must reproduce the above Copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *  <br>
 *   3. The names of its contributors may not be used to endorse or promote
 *      products derived from this software without specific prior written
 *      permission.
 *   <br><br>
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *  <br>
 *  <br>
 * Any feedback is very welcome.<br>
 * http://www.math.keio.ac.jp/matumoto/emt.html<br>
 * email: matumoto@math.keio.ac.jp<br>
 * <br>
 *
 * @author  (translated  in java by) Federico Granata
 */
public class MersenneTwister extends RandomEngine {

	private int mti;
	private int[] mt = new int[N]; /* set initial seeds: N = 624 words */

	/* Period parameters */
	private static final int N = 624;
	private static final int M = 397;

	private static final int MATRIX_A = 0x9908b0df;
	/* constant vector a */
	private static final int UPPER_MASK = 0x80000000;
	/* most significant w-r bits */
	private static final int LOWER_MASK = 0x7fffffff;
	/* least significant r bits */

	/* for tempering */
	private static final int TEMPERING_MASK_B = 0x9d2c5680;
	private static final int TEMPERING_MASK_C = 0xefc60000;

	private static final int mag0 = 0x0;
	private static final int mag1 = MATRIX_A;
	//private static final int[] mag01=new int[] {0x0, MATRIX_A};
	/* mag01[x] = x * MATRIX_A  for x=0,1 */

	public static final int DEFAULT_SEED = 4357;

	/** Creates a new instance of Prova */
	public MersenneTwister() {
		init_genrand((long) (Math.random() * Long.MAX_VALUE));
	}

    /**
     * Constructor
     * @param seed seed used to generate the sequence
     */
	public MersenneTwister(long seed) {
		init_genrand(seed);
	}


    public void setNewSeed(long seed) {
        init_genrand(seed);
    }


	/** initializes mt[N] with a seed */
	void init_genrand(long s) {
		long internal = s & 0xffffffffL;
		mt[0] = (int) internal;
		for (mti = 1; mti < N; mti++) {
			internal = (0x6C078965L * (internal ^ (internal >> 30)) + mti);
			/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
			/* In the previous versions, MSBs of the seed affect   */
			/* only MSBs of the array mt[].                        */
			/* 2002/01/09 modified by Makoto Matsumoto             */
			mt[mti] = (int) (internal &= 0xffffffffL);
			/* for >32 bit machines */
		}
	}


    /**
     * initialized by an array with array-length
     * @param init_key the array for initializing keys
     * @param key_length array length
     */
	private void init_by_array(long[] init_key, int key_length) {
		int i, j, k;
		long[] internal = new long[N];

		internal[0] = 0x12BD6AAL & 0xffffffffL;
		for (mti = 1; mti < N; mti++) {
			internal[mti] = (0x6C078965L * (internal[mti - 1] ^
			        (internal[mti - 1] >> 30)) + mti);
			/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
			/* In the previous versions, MSBs of the seed affect   */
			/* only MSBs of the array mt[].                        */
			/* 2002/01/09 modified by Makoto Matsumoto             */
			internal[mti] &= 0xffffffffL;
			/* for >32 bit machines */
			//System.out.println(Long.toHexString(mt[mti]));
		}

		i = 1;
		j = 0;
		k = (N > key_length ? N : key_length);
		for (; k > 0; k--) {
			internal[i] = (internal[i] ^ ((internal[i - 1]
			        ^ (internal[i - 1] >>> 30)) * 0x19660DL)) + init_key[j] + j;
			/* non linear */
			internal[i] &= 0xffffffffL;
			/* for WORDSIZE > 32 machines */
			i++;
			j++;
			if (i >= N) {
				internal[0] = internal[N - 1];
				i = 1;
			}
			if (j >= key_length) j = 0;
		}
		for (k = N - 1; k > 0; k--) {
			internal[i] = (internal[i] ^ ((internal[i - 1] ^ (internal[i - 1] >>> 30))
			        * 0x5D588B65L)) - i; /* non linear */
			internal[i] &= 0xffffffffL;
			/* for WORDSIZE > 32 machines */
			i++;
			if (i >= N) {
				internal[0] = internal[N - 1];
				i = 1;
			}
		}

		for (i = 1; i < N; i++)
			mt[i] = (int) (internal[i] & 0xffffffffL);

		mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */
	}

	/* generates a random number on [0,0xffffffff]-interval */
	int genrand_int32() {
		int y;

		if (mti >= N) { /* generate N words at one time */
			int kk;
			if (mti == N + 1)   /* if init_genrand() has not been called, */
				init_genrand(0x1571L); /* 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] ^ (y >>> 1) ^
				        ((y & 0x1) == 0 ? mag0 : mag1);
			}
			for (; kk < N - 1; kk++) {
				y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
				mt[kk] = mt[kk + (M - N)] ^ (y >>> 1) ^
				        ((y & 0x1) == 0 ? mag0 : mag1);
			}
			y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
			mt[N - 1] = mt[M - 1] ^ (y >>> 1) ^
			        ((y & 0x1) == 0 ? mag0 : mag1);

			mti = 0;
		}
		y = mt[mti++];

		/* Tempering */
		y ^= (y >>> 11);
		y ^= (y << 7) & 0x9d2c5680;
		y ^= (y << 15) & 0xefc60000;
		y ^= (y >>> 18);

		return y;
	}

	/* generates a random number on [0,0x7fffffff]-interval */
	private final int genrand_int31() {
		return (genrand_int32() >>> 1);
	}

	/* generates a random number on [0,1]-real-interval */
	private final double genrand_real1() {
		int i = genrand_int32();
		if (i > 0)
			return i / 4294967295.0;
		/* divided by 2^32-1 */
		else
			return ((double) (i & 0x7fffffff) + 0x80000000L) / 4294967295.0;
	}

	/* generates a random number on [0,1)-real-interval */
	private final double genrand_real2() {
		int i = genrand_int32();
		if (i > 0)
			return i / 4294967296.0;
		/* divided by 2^32 */
		else
			return ((double) (i & 0x7fffffff) + 0x80000000L) / 4294967296.0;
	}

	/* generates a random number on (0,1)-real-interval */
	private final double genrand_real3() {
		int i = genrand_int32();
		if (i > 0)
			return (i + 0.5) / 4294967296.0;
		/* divided by 2^32 */
		else
			return (((double) (i & 0x7fffffff) + 0x80000000L) + 0.5) / 4294967296.0;
	}

	/* generates a random number on [0,1) with 53-bit resolution*/
	private final double genrand_res53() {
		long a = genrand_int32() >>> 5, b = genrand_int32() >>> 6;
		return (a * 67108864.0 + b) / 9007199254740992.0;
	}
	/* These real versions are due to Isaku Wada, 2002/01/09 added */

	/**
	 * Returns a 64 bit uniformly distributed random number in the open unit
	 * interval [0.0,1.0) (including 0.0 and excluding 1.0).
	 */
	public double nextDouble() {
		return genrand_res53();
	}

	/**
	 *Returns a 32 bit uniformly distributed random number in the closed interval
	 * [Integer.MIN_VALUE,Integer.MAX_VALUE]
	 * (including Integer.MIN_VALUE and  Integer.MAX_VALUE)
	 */
	public int nextInt() {
		return genrand_int32();
	}

	/**
	 *Returns a 32 bit uniformly distributed random number in the closed interval
	 * [0,4294967295]
	 * (including 0 and  4294967295)
	 */
	public long nextLong() {
		int i = genrand_int32();
		if (i > 0)
			return i;
		else
			return (long) (i & 0x7fffffff) + 0x80000000L;
	}

	/**
	 *Returns a 64 bit uniformly distributed random number in the closed interval
	 * [Long.MIN_VALUE,Long.MAX_VALUE]
	 * (including Long.MIN_VALUE and  Long.MAX_VALUE)
	 */
	public long nextLong64() {
		int i = genrand_int32();
		int j = genrand_int32();
		long n;
		if (i > 0) {
			n = i;
			n <<= 32;
			if (j > 0)
				return n + j;
			else // i>0, j<0
				return n + (j & 0x7fffffff) + 0x80000000L;
		} else {//i < 0
			n = (i & 0x7fffffff) + 0x80000000L;
			n <<= 32;
			if (j > 0)
				return n + j;
			else//i<0, j <0
				return n + (j & 0x7fffffff) + 0x80000000L;
		}
	}

	/**
	 * Returns a 32 bit uniformly distributed random number in the open unit
	 * interval (0.0,1.0)  (excluding 0.0 and 1.0).
	 */
	public double raw() {
		return genrand_real3();
	}


	/**
	 * test
	 */
	public static void test() {
		int integer;
		MersenneTwister p = new MersenneTwister();
		long init[] = {0x123L, 0x234L, 0x345L, 0x456L};
		p.init_by_array(init, init.length);


		System.out.println("\nINT:  ");
		/*
		for(int i =0; i< 1000; i++) {
		    integer = p.genrand_int32();
		    if (integer > 0)
		        System.out.print(integer+" ");
		    else
		        System.out.print(((long) (integer & 0x7fffffff) + 0x80000000L) + " ");
		    if(i%5 == 4)
		        System.out.println();
		}*/

		for (int i = 0; i < 1000; i++) {
			System.out.print(p.nextLong() + " ");
			if (i % 5 == 4) System.out.println();
		}

		System.out.println("\nDOUBLE [0,1):  ");
		for (int i = 0; i < 1000; i++) {
			System.out.print(p.genrand_real2() + " ");
			if (i % 5 == 4) System.out.println();
		}

		p.init_genrand(723);
		System.out.println("\nINT:  ");
		for (int i = 0; i < 1000; i++) {
			integer = p.genrand_int32();
			if (integer > 0)
				System.out.print(integer + " ");
			else
				System.out.print(((long) (integer & 0x7fffffff) + 0x80000000L) + " ");
			if (i % 5 == 4) System.out.println();
		}

		System.out.println("\nDOUBLE [0,1]:  ");
		for (int i = 0; i < 1000; i++) {
			System.out.print(p.genrand_real1() + " ");
			if (i % 5 == 4) System.out.println();
		}

		System.out.println("\nDOUBLE [0,1):  ");
		for (int i = 0; i < 1000; i++) {
			System.out.print(p.genrand_real2() + " ");
			if (i % 5 == 4) System.out.println();
		}

		System.out.println("\nDOUBLE (0,1):  ");
		for (int i = 0; i < 1000; i++) {
			System.out.print(p.genrand_real3() + " ");
			if (i % 5 == 4) System.out.println();
		}

		System.out.println("\nDOUBLE 64 [0,1):  ");
		for (int i = 0; i < 1000; i++) {
			System.out.print(p.genrand_res53() + " ");
			if (i % 5 == 4) System.out.println();
		}

	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -