【问题标题】:Shuffle to cover all possible permutations随机播放以涵盖所有可能的排列
【发布时间】:2014-08-21 15:48:44
【问题描述】:

.NET 框架中的 Random 对象采用 32 位整数作为种子。这意味着任何使用 Random 对象的洗牌算法都被限制为(最多)40 亿次可能的洗牌(假设洗牌是根据随机序列确定的,我无法想象为什么它不会)。这意味着一旦集合超过 13 个元素,就可以保证 shuffle 不会覆盖所有可能的排列。随着集合大小远离这个大小,shuffle 覆盖的可能排列的子集变得越来越微不足道。

40 亿是一个(主观上)很大的数字,但如果您正在生成一个集合的多个“随机”排列,那么重复的机会就会变得比它应该的要大得多(特别是当您考虑生日悖论/鸽洞原理时) .

有什么简单的方法不涉及我实现自己的随机数生成器吗?

【问题讨论】:

  • 有趣,所以最好的情况下覆盖率将是 4bil^n 其中 n 是我洗牌的次数。唯一的问题是,如果洗牌真的很快,我可能需要睡一毫秒以确保种子不同。
  • 如果您的应用/项目适合,您可以考虑使用 Random.org 的在线 API 进行随机生成;只是我的两分钱。
  • 如果您将其用于例如出于游戏目的,您可能应该切换到加密安全的 RNG。
  • 分而治之:int digitNum = 10;长 l = 0;随机 r = new Random(DateTime.Now.Millisecond); for (int i = 0; i
  • 请注意,DateTime.Millisecond 可能仅每隔几毫秒更改一次,具体取决于系统。

标签: c# .net algorithm random shuffle


【解决方案1】:

我不建议您创建自己的随机数生成器 (RNG)。他们背后的理论是相当扎实的。如果您需要“更随机”的东西,那么您需要使用加密安全的 RNG。使用 .Net 框架提供的默认生成器:

使用 System.Security.Cryptography;

var generator = RandomNumberGenerator.Create();

您可以使用它来获取一些可以转换为 int 或其他值类型的随机字节。

【讨论】:

    【解决方案2】:

    您可以将免费提供的ports of Mersenne Twister 之一用于C#。 MT19937 有一个 19937 位的状态空间,虽然您可以选择使用单个 int 为其播种,但如果您有合适的熵源来提供它,也可以使用全状态播种。

    【讨论】:

      猜你喜欢
      • 2012-03-11
      • 2023-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-11
      • 2014-04-02
      • 1970-01-01
      相关资源
      最近更新 更多