随机整数中最可能的位

时间:2012-05-23 15:15:36

标签: c# c random

我做过这样的实验 - 用C和C#制作了1000万个随机数。然后计算设置随机整数中15位的每个位的次数。 (我选择了15位,因为C支持的随机整数最多只有0x7fff)。

我得到的是这个: enter image description here
我有两个问题:

  1. 为什么有3个最可能的位?在C情况下,最有可能位8,10,12。和 在C#6,8,11中最有可能。

  2. 似乎C#最可能的位大部分移位了2个位置,然后与C最可能位进行比较。为什么是这样 ?因为C#使用其他RAND_MAX常量还是什么?

  3. <小时/> 我的C测试代码:

    void accumulateResults(int random, int bitSet[15]) {
        int i;
        int isBitSet;
        for (i=0; i < 15; i++) {
            isBitSet = ((random & (1<<i)) != 0);
            bitSet[i] += isBitSet;
        }
    }
    
    int main() {
        int i;
        int bitSet[15] = {0};
        int times = 10000000;
        srand(0);
    
        for (i=0; i < times; i++) {
            accumulateResults(rand(), bitSet);
        }
    
        for (i=0; i < 15; i++) {
            printf("%d : %d\n", i , bitSet[i]);
        }
    
        system("pause");
        return 0;
    }
    

    并测试C#的代码:

    static void accumulateResults(int random, int[] bitSet)
    {
        int i;
        int isBitSet;
        for (i = 0; i < 15; i++)
        {
            isBitSet = ((random & (1 << i)) != 0) ? 1 : 0;
            bitSet[i] += isBitSet;
        }
    }
    
    static void Main(string[] args)
    {
        int i;
        int[] bitSet = new int[15];
        int times = 10000000;
        Random r = new Random();
    
        for (i = 0; i < times; i++)
        {
            accumulateResults(r.Next(), bitSet);
        }
    
        for (i = 0; i < 15; i++)
        {
            Console.WriteLine("{0} : {1}", i, bitSet[i]);
        }
    
        Console.ReadKey();
    }
    

    非常感谢!!顺便说一句,操作系统是Windows 7,64位架构&amp; Visual Studio 2010。

    修改
    非常感谢@David Heffernan。我在这里犯了几个错误:

    1. C和C#程序中的种子不同(C使用零和C# - 当前时间)。
    2. 我没有尝试使用Times变量的不同值来研究结果的可重复性。
    3. 这是我在分析设置第一位的概率取决于random()被调用次数时得到的结果: enter image description here
      因此,许多人注意到 - 结果不可重复,不应该被认真对待。 (除了某种形式的确认C / C#PRNG足够好:-))。

3 个答案:

答案 0 :(得分:10)

这只是普通或花园抽样变异。

想象一下,你会反复掷十次硬币的实验。你不会期望每次都有五个头。这取决于抽样变异。

以同样的方式,您的实验将受样本变化的影响。每个位遵循相同的统计分布。但是采样变化意味着您不会期望在0和1之间精确地分配50/50。

现在,你的情节误导你认为变异具有某种意义或具有意义。如果您从0开始绘制图形的Y轴,您将对此有更好的理解。该图形如下所示:

enter image description here

如果RNG表现得如此,则每个位将跟随binomial distribution,概率为0.5。此分布具有方差 np(1 - p)。对于您的实验,这给出了250万的差异。取平方根得到大约1,500的标准偏差。因此,您只需从检查结果中看到,您看到的变化并不是显而易见的。您有15个样本,没有一个超过真实均值的1.6个标准偏差。这没什么可担心的。

您试图辨别结果的趋势。你说有“3个最可能的位”。这只是你对这个样本的特殊解释。尝试使用不同种子为您的RNG再次运行程序,并且您的图表看起来会有所不同。它们仍然具有相同的质量。有些位设置比其他位更多。但是没有任何可辨别的模式,当你在包含0的图形上绘制它们时,你会看到水平线。

例如,这是您的C程序为随机种子98723498734输出的内容。

enter image description here

我认为这足以说服你再进行一些试验。当你这样做时,你会发现没有特殊的位被给予有利的治疗。

答案 1 :(得分:2)

你知道偏差大约是2500 / 5,000,000,下降到0.05%?

答案 2 :(得分:1)

请注意,每个位的频率差异仅约0.08%(-0.03%至+ 0.05%)。我认为我不会认为这很重要。如果每一位完全同样可能,我会发现PRN​​G非常值得怀疑,而不仅仅是有点可疑。您应该期望在过程中存在一定程度的差异,这些过程应该或多或少地建模随机性......