Наиболее вероятные биты в случайном целочисленном

Я сделал такой эксперимент - сделал 10 миллионов случайных чисел из C и С#. А затем подсчитали, сколько раз каждый бит из 15 бит в случайном целое установлен. (Я выбрал 15 бит, потому что C поддерживает случайное целое число только до 0x7fff).

У меня есть это: enter image description here
У меня есть два вопроса:

  • Почему существует 3 наиболее вероятных бита? В C наиболее вероятны биты бит 8,10,12. А также в C# бит 6,8,11 наиболее вероятны.

  • Также кажется, что наиболее вероятные биты С# в основном сдвинуты на 2 позиции, а затем сравниваются с наиболее вероятными битами C. Почему это? Потому что С# использует другую константу RAND_MAX или что?


Мой тестовый код для 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();
}

Очень спасибо! Btw, OS - это Windows 7, 64-битная архитектура и Visual Studio 2010.

ИЗМЕНИТЬ
Очень спасибо @David Heffernan. Здесь я сделал несколько ошибок:

  • Семя в программах на C и C было другим (C использовал нуль и С# - текущее время).
  • Я не пытался экспериментировать с различными значениями переменной Times для исследования воспроизводимости результатов.

Вот что я получил, когда проанализировал, как устанавливается вероятность того, что первый бит установлен, зависит от количества раз, когда был вызван случайный(): enter image description here
Так как многие заметили - результаты не воспроизводятся и не должны восприниматься всерьез. (За исключением некоторой формы подтверждения того, что C/С# PRNG достаточно хороши:-)).

Ответ 1

Это просто обычная или садовая выборка.

Представьте себе эксперимент, в котором вы бросаете монету десять раз, многократно. Вы не ожидали получить пять голов каждый раз. Это до вариации выборки.

Точно так же ваш эксперимент будет подвержен вариации выборки. Каждый бит следует за тем же статистическим распределением. Но выборка выборки означает, что вы не ожидаете точного разделения 50/50 между 0 и 1.

Теперь ваш сюжет вводит вас в заблуждение, думая, что вариация как-то значительна или имеет смысл. Вы бы лучше поняли это, если бы вы построили ось Y графика, начиная с 0. Этот график выглядит следующим образом:

enter image description here

Если RNG ведет себя так, как должно, каждый бит будет следовать за биномиальным распределением с вероятностью 0,5. Это распределение имеет дисперсию np (1 - p). Для вашего эксперимента это дает отклонение в 2,5 миллиона. Возьмите квадратный корень, чтобы получить стандартное отклонение около 1500. Таким образом, вы можете просто увидеть результаты ваших результатов, что вариация, которую вы видите, не является явно необычной. У вас есть 15 образцов, и ни один из них не превышает 1,6 стандартных отклонений от истинного среднего. Это не о чем беспокоиться.

Вы попытались определить тенденции в результатах. Вы сказали, что есть "3 наиболее вероятных бита". Это только ваша конкретная интерпретация этого образца. Попробуйте запустить свои программы снова с разными семенами для ваших RNG, и у вас будут графики, которые выглядят немного иначе. У них все равно будет одинаковое качество. Некоторые биты устанавливаются больше, чем другие. Но не будет различимых паттернов, и когда вы построите их на графике, который содержит 0, вы увидите горизонтальные линии.

Например, здесь ваша программа C выдает для случайного семени 98723498734.

enter image description here

Я думаю, этого должно быть достаточно, чтобы убедить вас провести еще несколько испытаний. Когда вы это сделаете, вы увидите, что нет специальных битов, которым предоставляется благоприятное лечение.

Ответ 2

Вы знаете, что отклонение составляет около 2500/5 000 000, что составляет 0,05%?

Ответ 3

Отметим, что разница частоты каждого бита изменяется только на 0,08% (от -0,03% до + 0,05%). Я не думаю, что считаю это значительным. Если бы каждый бит был в равной степени вероятен, я бы нашел, что PRNG очень сомнительный, а не просто несколько сомнительный. Вы должны ожидать некоторого уровня дисперсии в процессах, которые должны быть более или менее случайными моделирования...