0

vbaを介して次のアルゴリズムを使用して、一連のランダム順列を生成しようとしています:

Function RandNumber(Bottom As Integer, Top As Integer, _
                Amount As Integer) As Integer()

Dim iArr As Variant
Dim i As Integer
Dim r As Integer
Dim temp As Integer
Dim bridge() As Integer

'Application.Volatile

ReDim iArr(Bottom To Top)

For i = Bottom To Top
    iArr(i) = i
Next i
Randomize
For i = Top To Bottom + 1 Step -1
    r = Int(Rnd() * (i - Bottom + 1)) + Bottom
    temp = iArr(r)
    iArr(r) = iArr(i)
    iArr(i) = temp
Next i

ReDim Preserve bridge(1 To Amount)
For i = Bottom To Bottom + Amount - 1
    bridge(i - Bottom + 1) = iArr(i)
Next i

RandNumber = bridge

End Function

基本的に行うことRandNumberは、ユーザーが提供する下位値と上位値に基づいて順列をランダムに与えることです。例RandNumber(1,2,1)は、1または2ランダムになります。

現在、次のルーチンでこの機能をテストしています

Sub RandNos()
Dim z() As Variant
ReDim Preserve z(1 To 2560)
For i = 1 To 2560
z(i) = RandNumber(1, 2, 1)
Next i
For i = 1 To 2560
ThisWorkbook.Sheets("Sheet2").Range("A1").Offset(i - 1, 0) = z(i)
Next i
End Sub

まったく驚いたことに、「乱数」は 256 回の実行後に正確に繰り返されます。(わかりました、上記の値 2560iは正確には同時発生ではありません。256 行の周りで何らかのパターンが起こっているのではないかと疑っていたのでi、2560 としました)

さらに、わずかに変更されたサブルーチンで上記の関数をテストすると、次のようになります。

Sub RandNos2()
For i = 1 To 2560
ActiveSheet.Range("A1").Offset((i - 1) Mod 256 + 1, Int((i - 1) / 256)) = RandNumber(1, 2, 1)
Next i
End Sub

パターンがなくなりました。(少なくとも、256 個の値の後に繰り返すパターンはなくなりました。別のパターンが出現するかどうかはわかりません)。

現在、私の知識に基づいて、Randomizeは適切なシードを生成することによってランダム性を制御することになっておりRandomize、vba では からシードを取得しますtimer。したがって、私の仮説は、最初のRandNos()サブルーチンでは更新が非常に迅速に行われるため、シードが十分に速く更新されないというものです。timer2番目のサブルーチンでテストするとパターンがなくなったという事実.私の仮説を支持します。

だからここで私の質問は

  1. 私の仮説は正しいですか。
  2. Excel VBA で「ランダムな」パターンを生成したいのですが。
  3. Randomizeここの使い方間違ってる?

この問題に関する提案をお寄せいただきありがとうございます。

編集: コメントの提案の 1 つは、一Randomize度だけ呼び出す必要があるというものでした。私はそれをやってみましたが、うまくいくようです。ただし、上記のように使用すると何がうまくいかないのかを知りたいRandomizeです。

4

3 に答える 3

4

あなたの編集に答えて、あなたの仮説は正しいです。

ランダム化には時間がかかり、シードが生成されます。シードは Rnd の出発点にすぎません。

ただし、Randomize は 1 対 1 ではないことに注意してください。つまり、Randomize への任意の入力 (つまり、時間) に対して、毎回同じシードが生成されるわけではありません。ランダム化には、与えられた入力ごとに 256 のシードのシーケンスがあることを発見したようです。したがって、ランダムであるはずの 256 個の数字の繰り返しシーケンスが得られますが、明らかにそうではありません。

参照: Randomize クラスと CS クラスの VBA ヘルプ ページ

于 2012-12-03T19:58:18.170 に答える
3

Randomize一度だけ電話してください。RandNos()が複数回呼び出される場合はRandomize、 を呼び出すメソッドで使用しますRandNos()

于 2012-06-17T18:59:26.720 に答える