## ProblemYou want to greatly extend the cycle length of Visual Basic's pseudorandom number generator. ## SolutionSample code folder: Chapter 06\RepeatRandom You can use the ## DiscussionThe The cycle length of the generator is greatly enhanced by maintaining a table of pseudorandom Public Function GetNextDouble() As Double ' ----- Return the next pseudorandom number as a Double. ' ----- Move to the next index positions. Index1 = (Index1 + 1) Mod TableSize Index2 = (Index2 + 1) Mod TableSize ' ----- Update the random numbers at those positions. RandomTable(Index1) += RandomTable(Index2) + Rnd() RandomTable(Index1) = RandomTable(Index1) Mod 1.0 ' ----- Return the newest random table value. Return RandomTable(Index1) End Function This table keeps the pseudorandom values well mixed while providing a nice flat distribution of the values with excellent statistical results. When the The table size is set to 32, but feel free to make the table larger or smaller as desired. A larger table will be slightly slower to initialize, but subsequent pseudorandom numbers will be calculated and returned just as fast. Another advantage of this class is that it can be used to return several types of pseudorandom numbers. The Public Class BetterRandom Private Const TableSize As Integer = 32 Private RandomTable(TableSize - 1) As Double Private Index1 As Integer Private Index2 As Integer Public Sub New() ' ----- Generate truly pseudorandom numbers. InitRandom(Now.Ticks.ToString) End Sub Public Sub New(ByVal Key As String) ' ----- Generate a repeatable random sequence. InitRandom(Key) End Sub Private Sub InitRandom(ByVal repeatKey As String) ' ----- Prepare the random number generator. Dim stringIndex As Integer Dim workNumber As Double Dim counter As Integer ' ----- All sequences start with the same base sequence. Randomize(Rnd(-1)) ' ----- Initialize the table using the key string. For counter = 0 To TableSize - 1 stringIndex = counter Mod repeatKey.Length workNumber = Math.PI / _ Asc(repeatKey.Substring(stringIndex, 1)) RandomTable(counter) = (Rnd() + workNumber) Mod 1.0 Next counter ' ----- Set the starting state for the table. Index1 = TableSize \ 2 Index2 = TableSize \ 3 ' ----- Cycle through a bunch of values to get a good ' starting mix. For counter = 0 To TableSize * 5 GetNextDouble() Next counter ' ----- Reset the random sequence based on our ' preparations. Randomize(Rnd(-GetNextSingle())) End Sub Public Function GetNextDouble() As Double ' ----- Return the next pseudorandom number as ' a Double. ' ----- Move to the next index positions. Index1 = (Index1 + 1) Mod TableSize Index2 = (Index2 + 1) Mod TableSize ' ----- Update the random numbers at those positions. RandomTable(Index1) += RandomTable(Index2) + Rnd() RandomTable(Index1) = RandomTable(Index1) Mod 1.0 ' ----- Return the newest random table value. Return RandomTable(Index1) End Function Public Function GetNextSingle() As Single ' ----- Return the next pseudorandom number as ' a Single. Return CSng(GetNextDouble()) End Function Public Function GetNextInteger(ByVal minInt As Integer, _ ByVal maxInt As Integer) As Integer ' ----- Return the next pseudorandom number within an ' Integer range. Return CInt(Int(GetNextDouble() * _ (maxInt - minInt + 1.0) + minInt)) End Function Public Function GetNextReal(ByVal minReal As Double, _ ByVal maxReal As Double) As Double ' ----- Return the next pseudorandom number within a ' floating-point range. Return GetNextDouble() * (maxReal - minReal) + minReal End Function Public Function GetNextNormal(ByVal mean As Double, _ ByVal stdDev As Double) As Double ' ----- Return the next pseudorandom number adjusted ' to a normal distribution curve. Dim x As Double Dim y As Double Dim factor As Double Dim radiusSquared As Double Do x = GetNextReal(-1, 1) y = GetNextReal(-1, 1) radiusSquared = x * x + y * y Loop Until radiusSquared <= 1.0 factor = Math.Sqrt(-2.0 * Math.Log(radiusSquared) / _ radiusSquared) Return x * factor * stdDev + mean End Function Public Function GetNextExp(ByVal mean As Double) As Double ' ----- Return the next pseudorandom number adjusted ' for exponential distribution. Return -Math.Log(GetNextDouble) * mean End Function End Class The following code demonstrates the Dim result As New System.Text.StringBuilder Dim generator As BetterRandom result.AppendLine("Never the same sequence:") generator = New BetterRandom result.AppendLine(generator.GetNextDouble.ToString) result.AppendLine(generator.GetNextDouble.ToString) result.AppendLine(generator.GetNextDouble.ToString) result.AppendLine() result.AppendLine("Always the same sequence:") generator = New BetterRandom( _ "Every string creates a unique, repeatable sequence") result.AppendLine(generator.GetNextDouble.ToString) result.AppendLine(generator.GetNextDouble.ToString) result.AppendLine(generator.GetNextDouble.ToString) MsgBox(result.ToString()) Figure 6-26 shows the never-and always-repeating sequences generated by this demonstration code. ## Figure 6-26. Two pseudorandom sequences are generated: one that's always unique and one that always repeats## See AlsoSearch Visual Studio Help for "Random Class" and "RNGCryptoServiceProvider Class" for information about other ways to generate pseudorandom numbers in Visual Basic. |

Visual Basic 2005 Cookbook: Solutions for VB 2005 Programmers (Cookbooks (OReilly))

ISBN: 0596101775

EAN: 2147483647

EAN: 2147483647

Year: 2006

Pages: 400

Pages: 400

Authors: Tim Patrick, John Craig

Similar book on Amazon

- Challenging the Unpredictable: Changeable Order Management Systems
- Enterprise Application Integration: New Solutions for a Solved Problem or a Challenging Research Field?
- Intrinsic and Contextual Data Quality: The Effect of Media and Personal Involvement
- Healthcare Information: From Administrative to Practice Databases
- Relevance and Micro-Relevance for the Professional as Determinants of IT-Diffusion and IT-Use in Healthcare

flylib.com © 2008-2017.

If you may any questions please contact us: flylib@qtcs.net

If you may any questions please contact us: flylib@qtcs.net