高效随机数算法Java实现

本文介绍了如何用Java实现梅森旋转算法(Mersenne Twister/MT19937),该算法是一种高效的伪随机数生成器。文章起源于解决一个生成不重复随机数字的面试问题,虽然MT19937不能直接解决这个问题,但其高效性能在许多场景下非常有用。文章提供了算法背景、实现代码以及测试结果。
摘要由CSDN通过智能技术生成

前言

事情起源于一位网友分享了一个有趣的面试题:

生成由六位数字组成的ID,要求随机数字,不排重,不可自增,且数字不重复。ID总数为几十万。

初次解答

我一开始想到的办法是

  1. 生成一个足够大的ID池(其实就是需要多少就生成多少)
  2. 对ID池中的数字进行随机排序
  3. 依次消费ID池中的数字
    可惜这个方法十分浪费空间,且性能很差。

初遇梅森旋转算法

后面咨询了网友后得知了一个高效的随机数算法:梅森旋转(Mersenne Twister/MT)。通过搜索资料得知:

梅森旋转算法(Mersenne twister)是一个伪随机数发生算法。由松本真和西村拓士在1997年开发,基于有限二进制字段上的矩阵线性递归。可以快速产生高质量的伪随机数,修正了古典随机数发生算法的很多缺陷。

最为广泛使用Mersenne Twister的一种变体是MT19937,可以产生32位整数序列。

PS:此算法依然无法完美解决面试题,但是也算学到了新知识

MT19937算法实现

后面通过Google,找到了一个高效的MT19937的Java版本代码。原代码链接为http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/JAVA/MTRandom.java

import java.util.Random;

/**
 * MT19937的Java实现
 */
public class MTRandom extends Random {
    
    // Constants used in the original C implementation
    private final static int UPPER_MASK = 0x80000000;
    private final static int LOWER_MASK = 0x7fffffff;

    private final static int N = 624;
    private final static int M = 397;
    private final static int MAGIC[] = { 0x0, 0x9908b0df };
    private final static int MAGIC_FACTOR1 = 1812433253;
    private final static int MAGIC_FACTOR2 = 1664525;
    private final static int MAGIC_FACTOR3 = 1566083941;
    private final static int MAGIC_MASK1   = 0x9d2c5680;
    private final static int MAGIC_MASK2   = 0xefc60000;
    private final static int MAGIC_SEED    = 19650218;
    private final static long DEFAULT_SEED = 5489L;

    // Internal state
    private transient int[] mt;
    private transient int mti;
    private transient boolean compat = false;

    // Temporary buffer used during setSeed(long)
    private transient int[] ibuf;

    /**
     * The default constructor for an instance of MTRandom.  This invokes
     * the no-argument constructor for java.util.Random which will result
     * in the class being initialised with a seed value obtained by calling
     * System.currentTimeMillis().
     */
    public MTRandom() { }

    /**
     * This version of the constructor can be used to implement identical
     * behaviour to the original C code version of this algorithm including
     * exactly replicating the case where the seed value had not been set
     * prior to calling genrand_int32.
     * <p>
     * If the compatibility flag is set to true, then the algorithm will be
     * seeded with the same default value as was used in the original C
     * code.  Furthermore the setSeed() method, which must take a 64 bit
     * long value, will be limited to using only the lower 32 bits of the
     * seed to facilitate seamless migrati
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值