随机发生器:线性同余法

49 篇文章 0 订阅
47 篇文章 0 订阅

线性同余法

这里不做过多介绍,搜一下就知道
核心函数:
x n + 1 = ( a ∗ x n + b ) % m x_{n+1}=(a*x_n+b) \% m xn+1=(axn+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)
在这里插入图片描述
使用excel来将采样数据的线表图显示效果
在这里插入图片描述

References

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值