I am using a random number generator in my program, however it keeps returning the same value (0.71) every time i run the program.
code:
number = FormatNumber(Rnd(1), 2)
rdmlabelTxt.Text = number.ToString
is there a way to produce a different random number when starting the program?
thanks.
According to Microsoft "the same number sequence is generated" when you don't give a parameter. The article also suggests to "Before calling Rnd, use the Randomize statement without an argument to initialize the random-number generator with a seed based on the system timer."
I think this will solve your issue - let us know.
You are required to write a for loop to be able to generate different numbers
For i = 1 to 100
number = FormatNumber(Rnd(1), 2)
Cells(i, "A").Value = number
next i
You just have to use Randomize() call before your codes.
Randomize()
Dim number As Double = 0
number = FormatNumber(Rnd(1), 2)
rdmlabelTxt.Text = number.ToString
Related
It seems that Randomize() & Rnd() aren't used anymore.
Instead people make something like:
Dim rng as New Random()
Dim randomNo as Integer = rng.Next(10) ' this is a random number between 0 and 10.
Dim anotherRandomNo as Integer = rng.Next(10) ' a different random number.
Could someone tell me why this is considered "better" in most circumstances?
There are a few reasons.
Random has much greater functionality .. Have a look here
Also and more importantly the old Randomize is built into the instantiation of a Random object. By default, Rnd without randomize always started with the same seed number. If you didn't use randomize at the start of your program, each time it ran, it would generate the same sequence of numbers.
Finally, internally the Random object generates numbers in a different way with a better spread of randomness.
In my code,I have now realised I have to use the New Random function, my code was working before with the Randomize and then the numbers but now it comes up with loads of errors and wont even let me run the program. I think it is only a small error but I just need some help to get the final bit going
Heres the code and thanks for any help :)
I cannot get the code to work with the randomly generated number and I have to use the New Random function I cannot use randomize() Does anybody know how to help here is the code.
Dim timestook As Int32 = 1
Dim usersguess As Integer
Dim value = New Random(0 - 19)
Console.WriteLine("You have to guess this number. It is between 1 and 20. Good Luck !")
usersguess = Console.ReadLine()
'keep looping until they get the right value
While usersguess <> value
'now check how it compares to the random value
If usersguess < value Then
timestook = timestook + 1
Console.WriteLine("You're too low. Go higher ")
ElseIf usersguess > value Then
Console.WriteLine("You're too high. Go Lower.")
timestook = timestook + 1
End If
'If they are wrong the code will run again,after telling the user if they are too high or too low.
usersguess = Console.ReadLine()
End While
' Console.WriteLine("You're correct. Well Done")
If usersguess = value Then
Console.WriteLine("You took,{0}", timestook)
End If
Console.ReadLine()
End Sub
You'll want to do some googling on how to use random numbers. Your problem is that you aren't creating a Random object to handle the random number generation.
Here's how you can fix your code:
Dim randNumGen As New Random() 'Create Random object
Dim value As Integer = randNumGen.Next(0, 20) 'set value equal to a new random number between 0-19
Please note that this code could be further refactored for readability and simplicity (like changing timestook = timestook + 1 to timestook += 1 and selecting better variable names like numberOfGuesses as opposed to timestook, etc.
The expression New Random(0-19) does not do at all what you think it does, name it does NOT return an integer. Instead, it creates an instance of a Random object, which is a type that knows how to create new random values. The 0-19 part of the expression is the seed for the Random object's constructor, and is the same as just passing the value -19.
This looks like it's either homework or personal practice, so I feel like you will be better served in this case with a separate example using the Random type for reference than you would if I fixed the code sample in the question for you:
Dim rnd As New Random()
For i As Integer = 0 To 10
Console.WriteLine(rnd.Next(0, 20))
Next i
It's also worth mentioning here that you typically only want one Random object for your entire program, or at least only one Random object for each logical part of your program. Creating new Random objects resets the seeds, and for best results you want to follow the same seed on subsequent calls to the same instance for a while.
I am trying to generate a bunch of random permutations via the the following algorithm through 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
What RandNumber essentially does is that it randomly gives a permutation based on the bottom and top values provided by the user. Example RandNumber(1,2,1) will either be 1 or 2 randomly.
Now I am testing this function through the following routine
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
To my utter amazement the 'random' numbers are repeating exactly after 256 runs! (Ok, the value 2560 for i above is not exactly a co-incidence. I was suspecting that there is some pattern going on around 256 rows and thus took i as 2560)
Moreover, when I test the above function with slightly modified subroutine:
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
the pattern is gone. (At least the pattern of repeating after 256 values is gone. Not sure if another pattern emerges).
Now based on my knowledge the Randomize is supposed to control the randomness by generating appropriate seeds and Randomize in vba takes the seed from the timer. So my hypothesis is that in the 1st RandNos() subroutine the updates happen so quickly that the seeds don't get updated fast enough. The fact that pattern is gone when I test with the second subroutine, since in the second routine excel takes longer to write the code in the worksheet and hence the gives the code some chance to update the timer and with it the seed of the Random numbers - supports my hypothesis.
So my question here is
Is my hypothesis correct.
Should I still hope to generate a 'random' pattern in Excel VBA.
Am I making a wrong use of Randomize here
Thanks in advance for your suggestions on the issue.
EDIT: One of the suggestions in the comment was that we should call Randomize only once. I tried doing that and it seems to work. However, I would still like to know what goes wrong using Randomize as above.
in answer to your edit, your hypothesis is correct.
Randomize takes the time and generates a seed. A seed is just a starting point for Rnd.
However, note that Randomize is not one-to-one which means that for any given input into Randomize (i.e. the time) it doesn't generate the same seed every time. You appear to have discovered that Randomize has a sequence of 256 seeds for every given input. Therefore, you get a repeating sequence of 256 numbers which were supposed to be random but which clearly are not.
Reference: The VBA help page for Randomize and CS classes
You should call Randomize once only. If RandNos() is called more than once, use Randomize in the method that calls RandNos().
just for future reference to anyone else who encounters this problem, I decided to just try "slowing down" the subroutine enough to allow the system timer to reset. Application.wait did not work well, but I found that by including a simple debug.print line above the randomize call, it slowed the execution down just enough to get it to not repeat every 256. This not dramatically increase the overall run time of the subroutine. Just a thought for folks who would not mind sacrificing a little bit of optimization for a very simple fix on the pseudo-randomness.
I have previously been told that I should always use Randomize() before I use Rnd() in a VB.NET application. Yet, it always seems to work fine without it. What does adding Randomize() do for me in this case?
It doesn't appear to affect my application in the least.
In Visual Basic, Rnd() uses a mathematical operation to produce the next "random" number. Because the actual operation is known, given a specific value, you can predict the next value. However, given an arbitray start value the numbers have good distribution - these are "pseudo-random" numbers.
To keep Rnd() from startng at a predictable number (and hence giving the same sequence of "random" numbers every time), Randomize() should be called to use the machine clock to set the initial value (called a seed).
(In the .NET world, I'd use System.Random instead if you can.)
Randomize() initializes the first seed of Rnd(). If you won't use it - VB.NET will use the default seed number.
Randomize will set the seed to something time related, like the system uptime or the system date. So the function Rand() will show different values every time the app is executed. However, I highly recommend you to use the System.Random class instead of VisualBasic Rand(). No need to call any randomize() function
Here are some example code, this will generate six random integers from the lower to upper bounds:
Dim randObj As New Random( seed )
Dim j As Integer
For j = 0 To 5
Console.Write( "{0,11} ", randObj.Next( lower, upper ) )
Next j
Console.WriteLine( )
I am trying to generate a random number during testing using NUnit, but it keeps generating the same number. I am using the following function for this purpose.
dim dCount As Integer = Math.Floor((High - Low + 1) * Rnd() + Low)
dim divName As String = "abc" & dCount
Any idea why it is doing this?
Regards,
Sam
Presumably you're executing many tests in quick succession. I don't know exactly what Rnd() does in VB, but it sounds like it's got the typical "new RNG per call" problem.
Create a single instance of Random and use it repeatedly. Note that your maths can be replaced by a simple:
dim dCount as Integer = myRandom.Next(Low, High+1)
One caveat - Random isn't thread-safe. If you need to generate random numbers from different threads, either use locking or thread statics.
On another point: using random numbers will make your unit tests non-deterministic. Are you sure you have to? Sometimes it's appropriate, but not often IME.
Dim dCount As Integer = between(low, high)
Dim divName As String = "abc" & dCount
Dim myRandom As New Random
Private Function between(ByVal low As Integer, ByVal high As Integer) As Integer
between = myRandom.Next(low, high + 1)
End Function