2

次のコードは非常に簡単です。ランダムに選択されたピクセルでデザイン サーフェスを塗りつぶします。特別なことは何もありません (2 番目のメソッドの XXXXXXX は今のところ無視してください)。

private void PaintBackground()
{
    Random rnd = new Random();

    Bitmap b = new Bitmap(this.Width, this.Height);
    for (int vertical = 0; vertical < this.Height; vertical++)
    {
        for (int horizontal = 0; horizontal < this.Width; horizontal++)
        {
            Color randomColour = GetRandomColor(rnd);
            b.SetPixel(horizontal, vertical, randomColour);
        }
    }

    Graphics g = this.CreateGraphics();
    g.DrawImage(b, new Point(0, 0));
}

public Color GetRandomColor(Random rnd)
{
    XXXXXXXXXXXXXXXX

    byte r = Convert.ToByte(rnd.Next(0, 255));
    byte g = Convert.ToByte(rnd.Next(0, 255));
    byte b = Convert.ToByte(rnd.Next(0, 255));

    return Color.FromArgb(255, r, g, b);
}

私が持っている質問はこれです...

XXXXXXXXX を「Random rnd = new Random();」に置き換えた場合 テスト パターンは完全に同じ色の水平バーに変化するため、ランダムではありません。

誰か私にこれがなぜなのか説明してくれませんか?

2 回目の試行での唯一の違いは、GetRandomColour メソッドが Random クラスの新しいインスタンスを作成して使用することですが、水平バーがどのように作成されるかわかりません。

4

4 に答える 4

7

MSDNから:

乱数の生成はシード値から始まります。同じシードを繰り返し使用すると、同じ一連の数値が生成されます。異なるシーケンスを生成する 1 つの方法は、シード値を時間依存にすることです。これにより、Random の新しいインスタンスごとに異なるシリーズが生成されます。デフォルトで は、Random クラスのパラメーターなしのコンストラクターは、システム クロックを使用してシード値を生成します。、そのパラメーター化されたコンストラクターは、現在の時間のティック数に基づいて Int32 値を取ることができます。ただし、クロックの分解能は有限であるため、パラメーターなしのコンストラクターを使用して異なる Random オブジェクトを連続して作成すると、同一の乱数シーケンスを生成する乱数ジェネレーターが作成されます。次の例は、連続してインスタンス化された 2 つの Random オブジェクトが同一の一連の乱数を生成することを示しています。

したがって、同じシードを指定すると、Random インスタンスは同じ数列を生成します。あなたの例では、システムクロックの解像度が有限であるため、ランダムインスタンスはシードと同じティックカウントを使用して作成され、同じシーケンスになります。

への連続した呼び出しGetRandomColor()は、システム クロックの 1 つのタイム スライス内で実行されます。これをテストするには、 でメソッドの速度を落としてみてくださいThread.Sleep(1)。さまざまな色が生成されているのがわかります。

于 2010-01-19T12:48:06.917 に答える
3

アプリケーションは非常に高速に実行されるため、PRNG が初期化されているシードはループ全体で同じままです。

したがって、真にランダムではないため、疑似乱数ジェネレーターという名前が付けられています。

于 2010-01-19T12:46:49.977 に答える
1

作成時のランダムには、デフォルトのシード ゼロがあります。その関数でそれを再作成すると、常に同じ番号が得られます。コンストラクターで作成し、再利用して異なる乱数を取得します。

于 2010-01-19T12:48:15.277 に答える
1

ランダムは実際にはランダムではありません。それらは「疑似ランダム」です。(マシンの観点から) 実際に行っていることは、開始点で同じランダムを何度も生成することだけです。本当に必要なことは、コンストラクターに「シード」を渡すか、Next() メソッドを呼び出すことができるより高いスコープのランダムを用意することです。

于 2010-01-19T12:48:43.543 に答える