产生的随机数思路如果可以的话 说说Random类 产生的随机数思路  谢谢呵呵

解决方案 »

  1.   

    好吧,我承认我是在百度上google来的:Random rand = new Random();
    如果在实例化时没有传递任何参数,那么Java就会将当前时间作为随机数生成器的种子,并由此在程序没一次执行是都产生不同的输出。而如果在实例化时提供种子,就可以在每次执行程序时都生成相同的随机数,并且它的输出是可以验证的。(一)  例如:Random rand = new Random();int k = rand.nextInt()+1; 此时rand.nextInt() 或者 rand.nextInt(20) ,程序在每次运行时都会产生不同的随机数。(二) Random rand = new Random(47);(47被Bruce Eckel成为魔幻数字)  此时若 int k = rand.nextInt()+1; 每次程序的运行k都会得到相同的值。 若 int k = rand.nextInt(100)+1;  返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和100(不包括)之间均匀分布的 int 值。nextInt 的常规协定是,伪随机地生成并返回指定范围中的一个 int 值。所有可能的 n 个 int 值的生成概率(大致)相同。此时每次程序运行 k 也会得到相同的值。
      

  2.   

    我找出了源代码(java.util.Random),(以int为例)如下:
    //private final AtomicLong seed;
    public Random(long seed){
      this.seed=new AthomicLong(0L);//AthomicLong为原子变量类
      setSeed(seed);
    }
    protected int next(int bits) {//线性同余算法
      long oldseed, nextseed;
      AtomicLong seed = this.seed;
      do {
        oldseed = seed.get();//get():获得当前值
       //private final static long multiplier = 0x5DEECE66DL;
       //private final static long mask = (1L << 48) - 1;
       //private final static long addend = 0xBL;
        nextseed = (oldseed * multiplier + addend) & mask;
      } while (!seed.compareAndSet(oldseed, nextseed));//如果 当前seed==oldseed,则以原子方式         //设置为给定的nextseed。
      return (int)(nextseed >>> (48 - bits));
    }
    public int nextInt(){
      return next(32);
    }
    public int nextInt(int n) {//里面真是复杂,不过好像都是可逆的.
      if (n <= 0)
        throw new IllegalArgumentException("n must be positive");
      if ((n & -n) == n)  // i.e., n is a power of 2
         return (int)((n * (long)next(31)) >> 31);
      int bits, val;
      do {
        bits = next(31);
        val = bits % n;
      }while (bits - val + (n-1) < 0);
      return val;
    }
    synchronized public void setSeed(long seed) {
      seed = (seed ^ multiplier) & mask;//seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
      this.seed.set(seed);//void set(long value):设定为给定值;
    //private double nextNextGaussian;
    //private boolean haveNextNextGaussian = false;
      haveNextNextGaussian = false;
    }
    public void setSeed(long seed)使用单个 long 种子设置此随机数生成器的种子。setSeed 的常规协定是它更改此随机数生成器对象的状态,使其状态好像是刚刚使用参数 seed 作为种子创建它的状态一样.
    注意另一个构造函数:
    public Random() { 
    //private static volatile long seedUniquifier = 8682522807148012L;
    // static long System.nanoTime():返回最准确的可用系统计时器的当前值,以毫微秒为单位。
      this(++seedUniquifier + System.nanoTime()); 
    }
      

  3.   

    附 算法:线性同余法
    一般计算机的随机数都是伪随机数,以一个真随机数(种子)作为初始条件,然后用一定的算法不停迭代产生随机数
    1)将种子设为X0,
    2)用一个算法X(n+1)= (a*X(n)+b) mod c产生X(n+1)
    一般将c取得很大,可产生0到c-1之间的伪随机数
    该算法的一个缺点是会出现循环。 
      

  4.   

    这里有个简便、快捷的伪随机数函数,有兴趣的话可以看一下,具体的算法说明在代码注释中public class RandomGenerator {    public static void main(String[] args) {
            for(int i = 0; i < 100; i++) {
                System.out.println(nextInt(10));
            }
        }
        
        public static int nextInt() {
            return xorShift(new Object().hashCode() ^ (int)System.nanoTime());
        }
        
        public static int nextInt(int limit) {
            return Math.abs(nextInt() ^ (int)System.nanoTime()) % limit;
        }    /**
         * George Marsaglia, <i>Xorshift RNGs</i>, Journal of Statistical Software,
         * 8(14), 2003. pdf: http://www.jstatsoft.org/v08/i14/paper
         *
         * @param num
         * @return
         */
        private static int xorShift(int num) {
            num ^= (num << 6);
            num ^= (num >>> 21);
            num ^= (num << 7);
            return num;
        }
    }
      

  5.   

    LZ可以去翻看API。具体请找下java.util.Random这个类,里面有些方法有说生成随机数的大致思想。
      

  6.   


    Random 使用的是线性同余算法,至于为什么有随机性,这是数论中知识的。要证明这个算法的随机性,需要一定的数论知识。另外,数论是数学中的一个分支,对于非数学专业的本科阶段来说不会学习到有关数论的知识,所以建议楼主不用花心细去研究了。
      

  7.   

    只需要知道 JDK 类库中有两种随机数发生器:Random 和 SecureRandom,并且知道这两个有什么区别,知道怎么用就可以了,至于是怎么样随机的,就交给数学家和计算机科学家去吧。