C# 四种随机数生成算法 线性同余 莱默算法 Wichmann-Hill 延迟斐波那契数列

.Net自带随机数的调用,实质为线性同余,后面有介绍。

double[][] matrix = new double[20][];  // 20 rows
matrix = LoadData("C:\\Somewhere\\SomeFile.txt");
int lo = 0;
int hi = 20;
Random rnd = new Random(0);  // Create generator, seed = 0
x = rnd.NextDouble();  // [0.0, 1.0)
//后面三种算法如要生成范围内的正整数,则用以下的方法补充
int randomRow = (int)((hi - lo) * x + lo);  // [0, 19]
// Do something with randomRow

The Lehmer Algorithm 莱默算法
X(i) = a * X(i-1) mod m

public class LehmerRng
{
  private const int a = 16807;
  private const int m = 2147483647;
  private const int q = 127773;
  private const int r = 2836;
  private int seed;
  public LehmerRng(int seed)
  {
    if (seed <= 0 || seed == int.MaxValue)
      throw new Exception("Bad seed");
    this.seed = seed;
  }
  public double Next()
  {
    int hi = seed / q;
    int lo = seed % q;
    seed = (a * lo) - (r * hi);
    if (seed <= 0)
      seed = seed + m;
    return (seed * 1.0) / m;
  }
}

The Wichmann-Hill Algorithm

public WichmannRng(int seed)
{
  if (seed <= 0 || seed > 30000)
    throw new Exception("Bad seed");
  s1 = seed;
  s2 = seed + 1;
  s3 = seed + 2;
}

  public double Next()
  {
    s1 = 171 * (s1 % 177) - 2 * (s1 / 177);
    if (s1 < 0) { s1 += 30269; }
    s2 = 172 * (s2 % 176) - 35 * (s2 / 176);
    if (s2 < 0) { s2 += 30307; }
    s3 = 170 * (s3 % 178) - 63 * (s3 / 178);
    if (s3 < 0) { s3 += 30323; }
    double r = (s1 * 1.0) / 30269 + (s2 * 1.0) / 30307 + (s3 * 1.0) / 30323;
    return r - Math.Truncate(r);  // orig uses % 1.0
  }
}

线性同余算法,系统自带的就是这个算法
The Linear Congruential Algorithm
X(i) = (a * X(i-1) + c) mod m

public class LinearConRng
{
  private const long a = 25214903917;
  private const long c = 11;
  private long seed;
  public LinearConRng(long seed)
  {
    if (seed < 0)
      throw new Exception("Bad seed");
    this.seed = seed;
  }
  private int next(int bits) // helper
  {
    seed = (seed * a + c) & ((1L << 48) - 1);
    return (int)(seed >> (48 - bits));
  }
  public double Next()
  {
    return (((long)next(26) << 27) + next(27)) / (double)(1L << 53);
  }
}

延迟斐波那契数列
The Lagged Fibonacci Algorithm
X(i) = X(i-7) + X(i-10) mod m

public class LaggedFibRng
    {
        private const int k = 10; // Largest magnitude"-index"
        private const int j = 7; // Other "-index"
        private const int m = 2147483647;  // 2^31 - 1 = maxint
        private List<int> vals = null;
        private int seed;
        public LaggedFibRng(int seed)
        {
            vals = new List<int>();
            for (int i = 0; i < k + 1; ++i)
                vals.Add(seed);
            if (seed % 2 == 0) vals[0] = 11;
            // Burn some values away
            for (int ct = 0; ct < 1000; ++ct)
            {
                double dummy = this.NextDouble();
            }
        }  // ctor
        public double NextDouble()
        {
            // (a + b) mod n = [(a mod n) + (b mod n)] mod n
            int left = vals[0] % m;    // [x-big]
            int right = vals[k - j] % m; // [x-other]
            long sum = (long)left + (long)right;  // prevent overflow
            seed = (int)(sum % m);  // Because m is int, result has int range
            vals.Insert(k + 1, seed);  // Add new val at end
            vals.RemoveAt(0);  // Delete now irrelevant [0] val
            return (1.0 * seed) / m;
        }
        public int NextInteger(int Low,int High)
        { 
            return (int)((High - Low) * NextDouble() + Low);
        }
    }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值