The proper way to use the Randomize Statement
The randomize statement is used to initialize the random number generator and should only be called once in your program before any use of the Rnd Function. The Rnd function is used to generate the next "random" number in a sequence of pseudo-random numbers. The Randomize statement sets the starting point of that sequence.
I've seen some code on these forums where people use the Randomize statement before each call to the Rnd function.
Code:
'Incorrectly generate 10 random numbers
For i = 1 To 10
Randomize
NewNumber(i) = Rnd
Next i
The thinking here is that by picking a new starting point each time you can improve the randomness of the generator. This is not true, in fact if you do this you will actually decrease the randomness of the numbers.
The correct use of the function is to move the Randomize statement outside of the loop
Code:
'Correct generation of 10 random numbers
Randomize
For i = 1 To 10
NewNumber(i) = Rnd
Next i
Using both methods, let's generate a large quantity (15 million) of random numbers between 1 and 1000 and count how many times each number is generated. If the numbers are truly random, each "bin" will have close to the same number of counts in it. A generator that is flawed will show a preference for certain bins.
Following is a simple piece of code that tests both of the above methods by generating numbers, putting them into bins and plotting the results on MSChart objects. First, here are the results:
Notice the difference between the two plots. The "incorrect" method does not evenly generate the random numbers as well as the correct method does.
Conclusion:
Call the Randomize Function only once at the beginning of you program before any call to the Rnd function is made.
Calling the Randomize function before each Rnd call only bypasses the built-in random number generator by reseeding the generator at each iteration. The results above show how the numbers generated by this technique are not as random as they would be by proper use of the functions.
Code:
'Code that tests two ways of generating random numbers.
Option Explicit
Dim Counter(1 To 1000)
Dim Percentage(1 To 1, 0 To 1000)
Dim StopThis As Boolean
Private Sub Form_Load()
With MSChart1
.chartType = VtChChartType2dBar
.RowCount = 1
.ColumnCount = UBound(Counter)
Percentage(1, 0) = "Incorrect (Randomize) Method"
.ChartData = Percentage
End With
With MSChart2
.chartType = VtChChartType2dBar
.RowCount = 1
.ColumnCount = UBound(Counter)
Percentage(1, 0) = "Correct Method"
.ChartData = Percentage
End With
End Sub
Private Sub Command1_Click()
Dim TotalCounts As Long
Dim Index As Long, i As Long
Percentage(1, 0) = "Correct Method"
While i < 30 And Not StopThis
Index = Int((UBound(Counter) * Rnd) + 1)
Counter(Index) = Counter(Index) + 1
TotalCounts = TotalCounts + 1
Percentage(1, Index) = CDbl(Counter(Index) / TotalCounts) * UBound(Counter) - 0.9
If TotalCounts Mod 500000 = 0 Then
i = i + 1
MSChart2.ChartData = Percentage
Label1 = i
DoEvents
End If
Wend
For i = 1 To UBound(Counter)
Counter(i) = 0
Next
i = 0
TotalCounts = 0
Percentage(1, 0) = "Incorrect (Randomize) Method"
While i < 30 And Not StopThis
Randomize Timer
Index = Int((UBound(Counter) * Rnd) + 1)
Counter(Index) = Counter(Index) + 1
TotalCounts = TotalCounts + 1
Percentage(1, Index) = CDbl(Counter(Index) / TotalCounts) * UBound(Counter) - 0.9
If TotalCounts Mod 500000 = 0 Then
i = i + 1
MSChart1.ChartData = Percentage
Label1 = i
DoEvents
End If
Wend
If StopThis Then Unload Me
End Sub
Private Sub cmdStop_Click()
StopThis = True
End Sub