10

私はそのような実験をしました - C と C# から 1000 万の乱数を作りました。そして、ランダムな整数の15ビットから各ビットが設定されている回数を数えました。(C は までのランダムな整数のみをサポートするため、15 ビットを選択しました0x7fff)。

私が持っているのはこれです: ここに画像の説明を入力
私は2つの質問があります:

  1. 最も可能性の高いビットが 3 つあるのはなぜですか? Cビット8,10,12が最も可能性が高い場合。そして、C#ビット単位6,8,11が最も可能性が高いです。

  2. また、C# の最も可能性の高いビットは、C の最も可能性の高いビットと比較して、ほとんど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();
}

どうもありがとう !!ところで、OS は Windows 7、64 ビット アーキテクチャ、Visual Studio 2010 です

。EDIT
@David Heffernan に感謝します。ここでいくつかの間違いを犯しました:

  1. C と C# プログラムのシードは異なっていました (C はゼロを使用し、C# - 現在時刻を使用していました)。
  2. Times結果の再現性を調査するために、変数の値を変えて実験することはしませんでした。

最初のビットが設定される確率が random() が呼び出された回数にどのように依存するかを分析したときに得たものは次のとおり ここに画像の説明を入力
です。(C/C# PRNG で十分であるという何らかの形の確認を除いて:-))。

4

3 に答える 3

10

これは、一般的な、または庭のサンプリングのバリエーションです。

コインを 10 回繰り返し投げる実験を想像してみてください。毎回 5 つの表が出るとは思わないでしょう。それはサンプリングの変動にかかっています。

同様に、実験はサンプリング変動の影響を受けます。各ビットは、同じ統計分布に従います。ただし、サンプリングの変動は、0 と 1 の間で正確に 50/50 の分割が期待できないことを意味します。

さて、あなたのプロットは、バリエーションが何らかの形で重要である、または意味を持っていると誤解させています. 0 から始まるグラフの Y 軸をプロットすると、これをよりよく理解できます。そのグラフは次のようになります。

ここに画像の説明を入力

RNG が正常に動作する場合、各ビットは確率 0.5の二項分布に従います。この分布には分散np(1 − p)があります。あなたの実験では、これにより 250 万の分散が得られます。平方根を取ると、約 1,500 の標準偏差が得られます。したがって、結果を調べるだけで、表示される変動が明らかに異常ではないことがわかります。15 個のサンプルがあり、真の平均からの標準偏差が 1.6 を超えるサンプルはありません。それは心配する必要はありません。

結果の傾向を識別しようとしました。あなたは「3つの最も可能性の高いビット」があると言いました。それは、このサンプルに対するあなたの特定の解釈にすぎません。RNG の異なるシードを使用してプログラムを再度実行すると、少し異なるグラフが表示されます。彼らはまだ同じ品質を持っています。一部のビットは他のビットより多く設定されています。しかし、識別可能なパターンはなく、0 を含むグラフにプロットすると、横線が表示されます。

たとえば、C プログラムが のランダム シードに対して出力するものは次のとおりです98723498734

ここに画像の説明を入力

これで、さらにいくつかの試行を実行するよう説得するのに十分だと思います. そうすれば、優遇される特別なビットがないことがわかります。

于 2012-05-23T15:29:28.637 に答える
2

偏差が約2500/5,000,000で、0.05%に下がることをご存知ですか?

于 2012-05-23T15:25:46.237 に答える
1

各ビットの周波数の差は約 0.08% (-0.03% ~ +0.05%) しか変化しないことに注意してください。私はそれを重要だとは考えていないと思います。すべてのビットがまったく同じ確率であるとすれば、PRNG はやや疑わしいというよりも、非常に疑わしいと思います。多かれ少なかれモデリングのランダム性であると思われるプロセスで、ある程度の分散が予想されるはずです...

于 2012-05-23T15:33:09.987 に答える