4

重複の可能性:
乱数ジェネレーターが計画どおりに動作しない (C#)

乱数を生成する簡単なルーチンを作成しました

private int randomNumber()
{
    Random random = new Random();
    int randomNum = random.Next(0, 100);
    Response.Write(randomNum);
    return randomNum;
}

同じ方法で、page_load 全体の 2 つの異なる段階でこれを呼び出します。

// A/B Test
if (randomNumber() <= 50)
{
...

ただし、両方の数値が常に同じであることがわかりました。何か案は?

4

4 に答える 4

13

インスタンスを作成するRandomと、現在の時刻がシードされます。したがって、それらを同時に複数作成すると、同じ乱数列が生成されます。の単一のインスタンスを作成して使用する必要がありますRandom

于 2012-05-24T16:22:48.063 に答える
7

new Random()現在時刻をシードとして初期化されます。十分に速く呼び出すと、シードは同じになり、Next()呼び出しの結果も同じになります。

于 2012-05-24T16:22:30.267 に答える
3

クラスに Random の単一のインスタンスを用意し、それを再利用して乱数を生成することで、これを解決できます。

public class TestPage : Page
{
    private Random Generator {get;set;}
    public Test()
    {
        this.Generator = new Random();
    }
    private int randomNumber()
    {
        return this.Generator.Next(0, 100);
    }
}

これにより、すべてのリクエストに対して Random クラスが作成されます。これをユーザーのグループにしたい場合は、生成ロジックをシングルトンでラップし、すべてのユーザーで同じインスタンスを共有できます。

于 2012-05-24T16:26:26.583 に答える
2

ランダム

時間依存の既定のシード値を使用して、Random クラスの新しいインスタンスを初期化します。

MSDN から。

デフォルトのシード値はシステム クロックから派生し、有限の分解能を持ちます。その結果、既定のコンストラクターの呼び出しによって連続して作成されるさまざまな Random オブジェクトは、同じ既定のシード値を持つため、同じ乱数のセットが生成されます。この問題は、単一の Random オブジェクトを使用してすべての乱数を生成することで回避できます。また、システム クロックによって返されるシード値を変更し、この新しいシード値を明示的に Random(Int32) コンストラクターに提供することによって、この問題を回避することもできます。詳細については、Random(Int32) コンストラクターを参照してください。

于 2012-05-24T16:24:49.190 に答える