天天看点

随机发生器:线性同余法Code运行效果References

线性同余法

这里不做过多介绍,搜一下就知道

核心函数:

x n + 1 = ( a ∗ x n + b ) % m x_{n+1}=(a*x_n+b) \% m xn+1​=(a∗xn​+b)%m

x n + 1 x_{n+1} xn+1​就是我们下一个要算的随机数

x 0 x_0 x0​是我们的种子数

Code

// jave.lin 2019.08.20
    public class Ran
    {
        private static Random s_r = new Random();

        private int seed;
        private Random ran;

        public Ran(int seed = int.MinValue)
        {
            if (seed == int.MinValue)
            {
                this.seed = s_r.Next();
            }
            else
            {
                this.seed = seed;
            }
            ran = new Random(this.seed);
        }

        public int Range(int min, int max)
        {
            return ran.Next(min, max);
        }

        public int Seed => seed;
    }
           
// jave.lin 2019.08.20
    // linear congruential method
    // references:
    // - 随机数原理揭秘:线性同余法;http://blog.sina.com.cn/s/blog_d324e9ca0102wk4b.html
    // - 线性同余法:https://baike.baidu.com/item/%E7%BA%BF%E6%80%A7%E5%90%8C%E4%BD%99%E6%B3%95/10528746?fr=aladdin
    public class LinearCongruentialMethod
    {
        private static Ran r = new Ran();

        public int seed;

        private int a;
        private int b;
        private int m;
        private float invMF;
        private double invMD;

        public LinearCongruentialMethod(int s = -1)
        {
            //seed = s == -1 ? r.Range(int.MinValue, int.MaxValue) : s;
            //a = r.Range(int.MinValue, int.MaxValue);
            //b = r.Range(int.MinValue, int.MaxValue);
            //m = r.Range(1099999999, 2099999999);
            seed = s == -1 ? r.Range(0, int.MaxValue) : s;
            a = -536363;
            b = 83517;
            m = 2099999999;
            invMF = 1 / (float)m;
            invMD = 1 / (double)m;
        }

        public int Ran() => seed = (seed * a + b) % m;
        public float RanF() => float.MinValue + RanF01() * (float.MaxValue - float.MinValue);
        public double RanD() => double.MinValue + RanD01() * (double.MaxValue - double.MinValue);

        public int Range(int min, int max) => (int)(min + RanF01() * (max - min)); 
        public float RanF(float min, float max) => min + RanF01() * (max - min);
        public double RanD(double min, double max) => min + RanD01() * (max - min);

        // 这里我简写:n121意思是:negative 1 to 1==>n121==>[-1~1)
        public float RanFn121() => (Ran() * invMF);
        public double RanDn121() => (Ran() * invMD);

        // [0~1)
        public float RanF01() => RanFn121() * 0.5f + 0.5f;
        public double RanD01() => RanDn121() * 0.5f + 0.5f;
    }
           

运行效果

使用该随机发生器生成的白色噪点(white noise)

随机发生器:线性同余法Code运行效果References

使用excel来将采样数据的线表图显示效果

随机发生器:线性同余法Code运行效果References

References

  • 随机数原理揭秘:线性同余法
  • 线性同余法