【问题标题】:C# Am I doing "Bays & Durham Randomization by Shuffling" correctly?C# 我是否正确地执行“Bays & Durham 随机化随机化”?
【发布时间】:2019-10-17 20:51:23
【问题描述】:

我尝试使用“Bays & Durham Randomization by Shuffling”算法即兴创作一个随机数生成器。我按照网上的教程制作了这段代码:

 public int[] GenerateRandomSequence_Improved(int n, int min, int max)
 {
       int[] seq = new int[n];
       for(int i = 0; i < n; i++)
       {
           int rand = GenerateNextRandomNumber(min, max);

           rand = min + rand % (max + 1 - min);
           seq[i] = rand;
       }
       return seq;
 }

我想知道我做得对不对..

编辑:这是 GenerateNextRandomNumber 方法的代码

public int GenerateNextRandomNumber(int min, int max)
{
       return cSharpRNG.Next(min,max);
}

【问题讨论】:

  • GenerateNextRandomNumber 的代码在哪里?
  • 我的错,我现在要添加它!
  • 能否提供在线教程的链接?
  • 好的,现在cSharpRNG.Next 不见了。
  • 我认为rand = min + rand % (max + 1 - min); 不是必需的,因为Random.Next(Int32, Int32) 已经返回了请求范围内的值。 (包括下限,不包括上限)。而且我没有看到任何洗牌。您只是用随机数初始化数组。

标签: c# random numbers


【解决方案1】:

根据 Knuth TAOCP Vol. 2页。 34 算法B,正确的算法如下,

public class BaysDurham
{
    private readonly int[] t;
    private int y;      // auxiliary variable

    // Knuth TAOCP Vol. 2 p. 34 Algorithm B

    public BaysDurham(int k)
    {
        t = new int[k];

        for (int i = 0; i < k; i++)
        {
            t[i] = rand.Next();
        }

        y = rand.Next();
    }

    public int Next()
    {
        var i = (int)((t.Length * (long) y) / int.MaxValue);   // mitigates the bias
        y = t[i];
        t[i] = rand.Next();
        return y;
    }

    private readonly Random rand = new Random();
}

我让你调整输出的范围,但只知道你使用模数的公式会引入明显的偏差并使分布不均匀please look at this

【讨论】:

    【解决方案2】:

    这是我认为正确实施 Bays-Durham 洗牌的方法。不过,由于模运算导致的索引偏差警告是正确的。

    .NET Core 2.2,x64 Win10

    using System;
    using System.Diagnostics;
    
    namespace BaysDurhamShuffling
    {
        public class BaysDurhamRNG
        {
            public int[] _table;
            public int   _xnext;
    
            public Random _rng = null;
    
            public BaysDurhamRNG(int n, int seed = 312357) {
                Debug.Assert(n > 1);
    
                _rng = new Random(seed);
                _table = new int [n];
                for(int k = 0; k != n; ++k) {
                    _table[k] = _rng.Next();
                }
                _xnext = _rng.Next();
            }
    
            public int next() {
                var x = _xnext; // store return value
    
                var j  = _xnext % _table.Length; // form the index j into the table
                _xnext = _table[j];              // get jth element of table and to copy it to the output stream on next call
                _table[j] = _rng.Next();         // replace jth element of table with next random value from input stream
    
                return x; // return what was stored in next value
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var rng = new BaysDurhamRNG (16, 12345);
    
                for(int k = 0; k != 30; ++k) {
                    var x = rng.next();
                    Console.WriteLine($"RV = {x}");
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-19
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 2013-09-29
      • 1970-01-01
      相关资源
      最近更新 更多