洗牌以覆盖所有可能的排列

本文关键字:有可能 排列 覆盖 | 更新日期: 2023-09-27 18:11:07

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

40亿是一个(主观地)很大的数字,但如果你对一个集合生成多个"随机"排列,那么重复的机会就会变得比它应该的大得多(特别是当你考虑生日悖论/鸽子洞原则时)。

是否有简单的任何方法围绕这一点,不涉及我实现我自己的随机数生成器?

洗牌以覆盖所有可能的排列

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

使用System.Security.Cryptography;

var generator = RandomNumberGenerator.Create();

你可以使用这个来获得一些随机的字节,你可以将这些字节转换为int,或者其他的值类型。

您可以使用Mersenne Twister到c#的免费端口之一。MT19937有一个19937位的状态空间,虽然您可以选择用单个int来播种它,但如果您有一个合适的熵源来提供它,那么也可以使用全状态播种。