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()
サブルーチンでは更新が非常に迅速に行われるため、シードが十分に速く更新されないというものです。timer
2番目のサブルーチンでテストするとパターンがなくなったという事実.私の仮説を支持します。
だからここで私の質問は
- 私の仮説は正しいですか。
- Excel VBA で「ランダムな」パターンを生成したいのですが。
Randomize
ここの使い方間違ってる?
この問題に関する提案をお寄せいただきありがとうございます。
編集: コメントの提案の 1 つは、一Randomize
度だけ呼び出す必要があるというものでした。私はそれをやってみましたが、うまくいくようです。ただし、上記のように使用すると何がうまくいかないのかを知りたいRandomize
です。