0

この共有関数を使用して、基本的な乱数の生成を行っています。

Public Shared Function RandomNumber(ByVal MaxNumber As Integer, Optional ByVal MinNumber As Integer = 0) As Integer

    'initialize random number generator
        Dim r As New Random(Date.Now.Ticks And &HFFFF)

        If MinNumber > MaxNumber Then
            Dim t As Integer = MinNumber
            MinNumber = MaxNumber
            MaxNumber = t
        End If

        Return r.Next(MinNumber, MaxNumber)

End Function

このように呼び出されます:dim x as integer = Random(2100000000)

非常に単純で、シード値はMSの例から直接得られます。

問題は次のとおりです。番号が重複することがありますが、通常は少なくとも5分または10分間隔で作成されます。関数を1秒に複数回呼び出しているのか、ミリ秒に呼び出しているのかがわかります。これは、シードを「壊す」ためです。しかし、これらは長期間にわたって現れています。他に何がこれを引き起こしている可能性がありますか?

4

4 に答える 4

3

重複シードの問題?

最初に呼び出されたときに一度初期化されるように、r を static として定義する方がよい場合があります。この回答を参照してくださいVB.NETの乱数

于 2012-08-01T23:46:53.093 に答える
2

Randomコンストラクターは、Integer32 ビットの をパラメーターとして受け取ります。spencer7593が言ったように、わずか 16 ビットで、6.5ms ごとにシーケンスを繰り返しています。試す:

Dim r As New Random(Date.Now.Ticks And &HFFFFFFFF)

ただし、これは同じことを行います。

Dim r As New Random()

いっそのこと、Random毎回新しいオブジェクトを作成しないでください:

Private Static r As New Random()  
Public Shared Function RandomNumber(MaxNumber As Integer, Optional MinNumber As Integer = 0) As Integer  
    ...
    Return r.Next(MinNumber, MaxNumber)  
End Function  
于 2012-08-02T03:38:21.510 に答える
1

Q: 他に何が原因でしょうか?

A: 純粋にランダムに発生している可能性があります。乱数はまさにそれです:ランダム。別の時点から数秒または数時間離れているかどうかに関係なく、任意の時点で、数値が他の数値と同じように表示される可能性があります。番号が繰り返されないという保証はありません。

一方、シード値は 16 ビット程度しかないようです。これは合計で 65,536 通りの可能性があります。1 ミリ秒に 10,000 ティックあるので、6.5 ミリ秒ごとに同じシードを再利用する可能性があります。

VB Random がそのシードを超えた別の種類のエントロピーを使用しているかどうかはまったく明らかではありません。(ただし、インクルードのためにエントロピーを収集すると、初期化が遅くなるため、パフォーマンス上の考慮事項としてそうではない場合があります。)

ドキュメントによると、同じシード値を使用して 2 つの Random オブジェクトを作成すると、一意の番号の重複シーケンスを作成する Random オブジェクトが生成されます。

http://msdn.microsoft.com/en-us/library/ctssatww.aspx


なぜそれが起こっているのかという質問に答えると思います。

次の質問は、なぜ新しいRandomオブジェクトをインスタンス化する必要があるのですか? 複数のオブジェクトが必要な場合は、それらのいくつかをインスタンス化しますが、それぞれに異なるシード値を使用していることを確認するのが 1 つの方法です。

ただし、そこに行く前に、1 つ Randomだけを使用することを検討することをお勧めします。乱数を取得するための呼び出しはRandom、乱数が必要になるたびに新しい を作成するのではなく、既存の から処理できます。

于 2012-08-01T23:46:13.173 に答える
0

別の方法を試してください:

Public Function RandomNumber2(ByVal MaxNumber As Integer, Optional ByVal MinNumber As Integer = 0) As Integer
    ' Initialize the random-number generator.
    Randomize()
    ' Generate random value between MaxNumber and MinNumber.
    Return CInt(Int((MaxNumber * Rnd()) + MinNumber))
End Function

詳細については、 Randomize 関数 (Visual Basic)を参照してください。お役に立てれば。

于 2012-08-02T09:56:03.330 に答える