|
-
Apr 6th, 2010, 02:14 PM
#1
Thread Starter
Member
[RESOLVED] Probability 1-20 program

VB Code:
Public Class Form1
'The checkList array is used to check off which numbers
'have already been randomly picked.
Private checkList(20) As Boolean
'The counter is used to show how many times it took
'for all numbers to be randomly picked.
Private counter As Integer = 0
'The track variable tells me when I should end the while....loop
'I could have just used a long if or select case, but it just
'seems easier this way.
Private track As Integer = 0
'This value of this variable (true|false) determines
'whether the While....Loop continues running or not.
Private continueLoop As Boolean = True
'I need these variables to access the Random class
'so the program will generate a random number.
Dim generator As New Random
Dim randomValue As Integer
Private Sub cmdRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRun.Click
Dim i As Integer = 0
'This resets the checkList array.
For i = 0 To i < 19 Step 1
checkList(i) = False
Next i
'These three lines are just resetting the variables
'in case the program ran once before.
counter = 0
track = 0
continueLoop = True
'The loop starts and will end when the continueLoop is set to false.
While (continueLoop)
'When the track variable reaches 19 in the array index (0-19)
'for a total of 20 indexes or more simply put 20 numbers, then
'the continueLoop will be set to false. UPDATE: I seen a
'mistake on my part. The counter variable will get incremented
'by one, so the continueLoop variable is pointless, but since
'it is in there, then I'll leave it in. I used Exit While
'so the variable counter will not get incremented.
If (track = 19) Then
continueLoop = False
Exit While
End If
'This static sub procedure is supposed to sync the generator variable
'with the cpu clock to help the program generate better random values,
'instead of maybe some sort of random pattern.
Randomize()
'randomValue holds a random value of (1-20).
randomValue = generator.Next(1, 20)
'Depending on what number get randomly selected, is what
'case or option will get selected.
Select Case randomValue
Case 1
If (checkList(0) = True) Then
'has already been populated
track += 1
Else
checkList(0) = True
End If
Case 2
If (checkList(1) = True) Then
'has already been populated
track += 1
Else
checkList(1) = True
End If
Case 3
If (checkList(2) = True) Then
'has already been populated
track += 1
Else
checkList(2) = True
End If
Case 4
If (checkList(3) = True) Then
'has already been populated
track += 1
Else
checkList(3) = True
End If
Case 5
If (checkList(4) = True) Then
'has already been populated
track += 1
Else
checkList(4) = True
End If
Case 6
If (checkList(5) = True) Then
'has already been populated
track += 1
Else
checkList(5) = True
End If
Case 7
If (checkList(6) = True) Then
'has already been populated
track += 1
Else
checkList(6) = True
End If
Case 8
If (checkList(7) = True) Then
'has already been populated
track += 1
Else
checkList(7) = True
End If
Case 9
If (checkList(8) = True) Then
'has already been populated
track += 1
Else
checkList(8) = True
End If
Case 10
If (checkList(9) = True) Then
'has already been populated
track += 1
Else
checkList(9) = True
End If
Case 11
If (checkList(10) = True) Then
'has already been populated
track += 1
Else
checkList(10) = True
End If
Case 12
If (checkList(11) = True) Then
'has already been populated
track += 1
Else
checkList(11) = True
End If
Case 13
If (checkList(12) = True) Then
'has already been populated
track += 1
Else
checkList(12) = True
End If
Case 14
If (checkList(13) = True) Then
'has already been populated
track += 1
Else
checkList(13) = True
End If
Case 15
If (checkList(14) = True) Then
'has already been populated
track += 1
Else
checkList(14) = True
End If
Case 16
If (checkList(15) = True) Then
'has already been populated
track += 1
Else
checkList(15) = True
End If
Case 17
If (checkList(16) = True) Then
'has already been populated
track += 1
Else
checkList(16) = True
End If
Case 18
If (checkList(17) = True) Then
'has already been populated
track += 1
Else
checkList(17) = True
End If
Case 19
If (checkList(18) = True) Then
'has already been populated
track += 1
Else
checkList(18) = True
End If
Case 20
If (checkList(19) = True) Then
'has already been populated
track += 1
Else
checkList(19) = True
End If
End Select
counter = counter + 1
End While
txtNumOfChances.Text = counter
txtProbability.Text = 20 / counter
End Sub
End Class
I'm not sure about this program. It seems to work, but every time I run the program to see if it get different results, it doesn't. I don't see where the mistake is at. The program does work, but with the help of the static sub procedure function Randomize(), the program still don't seem to be generating new patterns. I understand that if I close the program down, that the same pattern may get used with every executing of the program, but I'm re-running through the command button on my form.
Anyway, maybe someone's eyes will detect what is happening and can tell me what that is by posting.
Thanks!
Last edited by kevin_10987; Apr 6th, 2010 at 07:49 PM.
-
Apr 6th, 2010, 03:04 PM
#2
Re: Probability 1-20 program
First of all, Randomize is used with the 'old' Rnd function, which you are not using. The Random class, which you are using, does not need it, so it is not doing anything.
The Random class bases its random numbers on a seed. You can supply the seed yourself, when creating a New Random object, but you are not. Because you are not, the class will use the system time as seed by default (this is a good thing!). So, you should see random results. If you run the program twice, the time will be different each run, and 'generator' should return a different sequence of numbers.
I'm not sure how you're seeing that it's not random, nor what you're doing exactly... Can you explain a bit more?
Finally, the whole Select Case block is redundant. You are doing the same thing in each case, except that you are using a different index to the checkList array (well, I think it's an array, you didn't specify).
So, you can replace the whole select case block with this:
Code:
If (checkList(randomValue - 1) = True) Then
'has already been populated
track += 1
Else
checkList(randomValue - 1) = True
End If
-
Apr 6th, 2010, 03:26 PM
#3
Hyperactive Member
Re: Probability 1-20 program
I think the Randomize() method you are calling is screwing something up. I don't think you need to call that in VB.Net. I wrote a little test VB program to generate random numbers for your problem and it works fine. Just adapt it for your use. Check it out:
vb Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Rnd As New Random() ' Inclusive lower bound but exclusive upper bound Dim RandomNumber As Integer = Rnd.Next(1, 21) MessageBox.Show(RandomNumber.ToString()) End Sub
Remember to click on the scales to the left and rep me if I helped 
-
Apr 6th, 2010, 03:30 PM
#4
Hyperactive Member
Re: Probability 1-20 program
 Originally Posted by NickThissen
First of all, Randomize is used with the 'old' Rnd function, which you are not using.
He/She is using it here:
vb Code:
'The loop starts and will end when the continueLoop is set to false. While (continueLoop) 'When the track variable reaches 19 in the array index (0-19) 'for a total of 20 indexes or more simply put 20 numbers, then 'the continueLoop will be set to false. UPDATE: I seen a 'mistake on my part. The counter variable will get incremented 'by one, so the continueLoop variable is pointless, but since 'it is in there, then I'll leave it in. I used Exit While 'so the variable counter will not get incremented. If (track = 19) Then continueLoop = False Exit While End If 'This static sub procedure is supposed to sync the generator variable 'with the cpu clock to help the program generate better random values, 'instead of maybe some sort of random pattern. Randomize() ' <-------------------------------------------------------- ** HERE **
Remember to click on the scales to the left and rep me if I helped 
-
Apr 6th, 2010, 03:55 PM
#5
Re: Probability 1-20 program
Yeah, but they are NOT using Rnd, which required Randomize. What Nick was saying was that Randomize is not needed for the Random object, which they are using. Still, I wouldn't expect Randomize to cause any harm. I would expect it to have no impact at all, but perhaps not. Taking it out would certainly be the first step.
The most common answer for this type of problem is that people put the declaration of the Random object inside a sub (as FireSnake did, but that case is actually almost certainly safe) which then gets called many times in a tight loop. Since you declared the Random object outside of the sub at form scope, you are doing it correctly. You should be getting a different random sequence every time you click RUN, yet you state that you are not. It would be very interesting to me if removing the Randomize statement fixed the problem, but I suspect it will not.
My usual boring signature: Nothing
 
-
Apr 6th, 2010, 04:00 PM
#6
Re: Probability 1-20 program
Yes, Shaggy is right. I meant the OP wasn't using the Rnd function, so there was no need for the Randomize function.
I also would be very surprised if the Randomize call was doing the harm. If it has any effect at all, I would expect it to randomize the output even more (so that, perhaps, the Random class uses the old Rnd function behind the scenes anyway... I doubt it). I would certainly not expect it to suddenly make the Random object use the same seed over and over.
Still, doesn't hurt to try, and since it isn't doing any good, just take it out.
-
Apr 6th, 2010, 07:16 PM
#7
Thread Starter
Member
Re: Probability 1-20 program
Thanks everyone for your great response. I also appreciate the comment by Nick.... on showing me why the Select....Case that I was using was redundant. I don't know why I was trying to make it more complicated than it had to be but the simple if....then worked great.
I'm going to post the output that I am getting by running the program a few times.
Code:
Number of chances: 33
Probability (%): 0.60606060606
Number of chances: 24
Probability (%): 0.833333333333333
Number of chances: 19
Probability (%): 1.05263157894737
Number of chances: 38
Probability (%): 0.526315789473684
Number of chances: 19
Probability (%): 1.05263157894737
Number of chances: 36
Probability (%): 0.555555555555556
Number of chances: 20
Probability (%): 1
Number of chances: 19
Probability (%): 1.05263157894737
Number of chances: 34
Probability (%): 0.588235294117647
Number of chances: 23
Probability (%): 0.869565217391304
Number of chances: 19
Probability (%): 1.05263157894737
Number of chances: 34
Probability (%): 0.588235294117647
Number of chances: 22
Probability (%): 0.909090909090909
Number of chances: 33
Probability (%): 0.60606060606
Now, I just want to clarify something. These are different numbers, but it seems so close that it just seems too close. It looks like the more numbers between 1-20 would get picked repeatedly. The thing that I wanted to clarify is, after I click my run command button three times, the program doesn't seem to want to run through the loop again, because it returns the same number of chances (usually, 20 or 19, which the probability being either 1 or 1.05XXXXXXX. It just generates the same value over and over like 20 and won't change until I terminate the program and click my run command button again. But after three times of clicking my command button; I must terminate the program again and run the program again to successfully run the program. It seems like after three runs, something is cached somewhere that is causing the program to behave improperly. Maybe there is something wrong with my installed copy of VB 2008 EE. With Microsoft stuff, one doesn't know whether it's their code or Microsoft's code. Last statement is a joke. Microsoft is cool.
I just wanted to say thanks for informing me that Randomize() is used with Rnd and not with an instance of the Random class. I used to use Rnd, and was informed to use Randomize(), so I just assumed that Randomize() still was needed. Thanks for correcting me on this.
Last edited by kevin_10987; Apr 6th, 2010 at 07:21 PM.
-
Apr 6th, 2010, 07:38 PM
#8
Thread Starter
Member
Re: Probability 1-20 program
I have another question.
VB Code:
' Inclusive lower bound but exclusive upper bound
Dim RandomNumber As Integer = Rnd.Next(1, 21)
When defining the boundaries to include for the Random class to generate numbers; does one have to include 1 more on the upper end? So if I want to include all numbers from 1-20, then I must write the lower boundary, upper boundary like (1,21) like "The Fire Snake" did.
By the way, sorry for not using the HighLight option. I haven't been on here for a while and forgot how to use it. When I clicked on VBCode, it said, please enter the option. I was like, what option, then it dawned on me, oh, type VB.
-
Apr 6th, 2010, 09:11 PM
#9
Thread Starter
Member
Re: Probability 1-20 program
I see a problem with my code. Why didn't I see it?!
VB Code:
If (checkList(randomValue - 1) = True) Then 'has already been populated track += 1 Else checkList(randomValue - 1) = True End If
The variable track is getting incremented every time the instance of the Random class generates a number. So if it generates the number two, four times in a row, then the variable track is already up to 4. That is not what I want. I want the counter variable to be equal to four, but not the variable track.
I just thought of something. Instead of the variable track; I could do something like this.
VB Code:
Dim i as Integer = 0 'I know, I already used i somewhere in the program. Well, I think. Dim bool1 as Boolean = True For (i=0 to i<19 step 1) if (checkList(i) = true) Then bool1 = True else bool1 = False Next i If (bool1) then 'end loop and show output else 'keep loop going End If
Last edited by kevin_10987; Apr 6th, 2010 at 09:18 PM.
-
Apr 7th, 2010, 03:18 AM
#10
Re: Probability 1-20 program
So, does that work? It's still not clear to me what you're doing.
Are you using that checkList stuff so that your program never uses the same random number twice? In other words, are you looking for non-repeating random numbers? That can be done much easier. You'd fill an List(Of Integer) with the numbers you need to choose from (in your case, 1 to 20). Then, you generate a random index in that list (so, between 0 and 19). You extract the number on that index from the list and use that as your random number. Then, you remove the number from the list, so you cannot choose it again. The second time you generate a number, you generate one between 0 and 18 (because there's now only 19 integers in the list). In general, you select a number between 0 and list.Count - 1. Because you remove each selected number from the list, you can never get the same number twice.
-
Apr 7th, 2010, 12:39 PM
#11
Thread Starter
Member
Re: Probability 1-20 program
Thanks everyone and thanks NickThissen for your suggestion to completely re-write it. My logic was pretty messed up. Here is my final solution and the output is what I wanted.
The original way I wrote the code didn't allow the program to run but 19 times, so the program would have never been accurate.
VB Code:
Public Class Form1 'The counter is used to show how many times it took 'for all numbers to be randomly picked. Private counter As Integer = 0 Private listOfNumbers As New ArrayList 'I need these variables to access the Random class 'so the program will generate a random number. Dim generator As New Random Dim randomValue As Integer Private Sub cmdRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdRun.Click 'These three lines are just resetting the variables 'in case the program ran once before. counter = 0 listOfNumbers.Clear() For i As Integer = 1 To 20 'populates the arraylist with 1-20 listOfNumbers.Add(i) Next i 'The loop starts While (True) 'randomValue holds a random value of (1-20). randomValue = generator.Next(1, 21) For i As Integer = 0 To listOfNumbers.Count - 1 If listOfNumbers.Count < 2 Then Exit While End If If listOfNumbers.Item(i).Equals(randomValue) Then listOfNumbers.RemoveAt(i) Exit For End If ToolStripProgressBar1.Value = CType((20 / _ listOfNumbers.Count) * 10, Integer) ToolStripStatusLabel1.Text = CType((20 / _ listOfNumbers.Count) * 10, Integer) Next i counter = counter + 1 End While txtNumOfChances.Text = counter txtProbability.Text = 20 / counter End Sub End Class
I added the progress bar to let me know whether the program was working or was stuck in some sort of infinite loop due to the looping through the arraylist.
Thanks all for helping me make this little project run and for pointing out suggestions that really cleaned up my code. It was a mess at the beginning.
Last edited by kevin_10987; Apr 7th, 2010 at 01:31 PM.
-
Apr 7th, 2010, 12:43 PM
#12
Hyperactive Member
Re: Probability 1-20 program
You have the correct random numbers being generated with 1,20? The documentation I have read says that the 20 is exclusive, meaning it won't generate a random number of 20.
Remember to click on the scales to the left and rep me if I helped 
-
Apr 7th, 2010, 12:46 PM
#13
Re: Probability 1-20 program
One final suggestion: you can use a List(Of Integer) instead of an ArrayList. The advantage is that a List(Of Integer) is what we call 'type-safe'. It can only contain Integers, so it also returns Integers if you get an item from it. An ArrayList contains Objects, so if you want to use an item in it, you'd need to cast it to an Integer explicitly. You got around that by using the Equals function, but it would be easier if you used a List(Of Integer). Then, line 33 in your above code would read
Code:
If listOfNumbers.Item(i) = randomValue Then
You only need to change the declaration in line 7, from ArrayList to List(Of Integer). You add/remove items in the same way, so that code can remain the same.
-
Apr 7th, 2010, 01:27 PM
#14
Thread Starter
Member
Re: Probability 1-20 program
I didn't noticed the 1,20 in the generator.next parameters, but for some reason it was working. I guess I'm going to have to reduce the size of the arraylist and only generate numbers from 1-3 or something just to see if the program is working correctly.
I just read what you are saying about the parameters in the next method about how the maximum number is not included. I did change it though. The numbers seems accurate now and isn't generating any kind of error.
The best someone could draw 20 numbers out of a hat (must put the number back in the hat) and also you must check off the number that you drew out. The game doesn't end until all numbers have been crossed off. Anyway, with luck, it would take 33 tries. The worst scenario is around 100 tries.
I just thought this would be a neat little program to help me practice my visual basic skills.
If a person had 5000 numbers to randomly choose from, then it would take around 10,000 tries, at best, to cross off all 20 numbers. The program shows it shouldn't take more than 20,000 tries to cross off all 20 numbers.
-
Apr 7th, 2010, 01:38 PM
#15
Thread Starter
Member
Re: Probability 1-20 program
 Originally Posted by NickThissen
One final suggestion: you can use a List(Of Integer) instead of an ArrayList. The advantage is that a List(Of Integer) is what we call 'type-safe'. It can only contain Integers, so it also returns Integers if you get an item from it. An ArrayList contains Objects, so if you want to use an item in it, you'd need to cast it to an Integer explicitly. You got around that by using the Equals function, but it would be easier if you used a List(Of Integer). Then, line 33 in your above code would read
Code:
If listOfNumbers.Item(i) = randomValue Then
You only need to change the declaration in line 7, from ArrayList to List(Of Integer). You add/remove items in the same way, so that code can remain the same.
Thanks for that suggestion "Nick" about the List (Of Integer). That is pretty cool! I don't remember reading that in any book of mine.
-
Apr 7th, 2010, 01:40 PM
#16
Hyperactive Member
Re: Probability 1-20 program
 Originally Posted by kevin_10987
Thanks for that suggestion "Nick" about the List (Of Integer). That is pretty cool! I don't remember reading that in any book of mine.
It is a generic collection. I love it. I use List(Of ) all the time and they are very helpful.
Remember to click on the scales to the left and rep me if I helped 
-
Apr 7th, 2010, 01:51 PM
#17
Re: [RESOLVED] Probability 1-20 program
Generics only showed up in 2005, so books that were written, or in the works, around the time that 2005 came out, wouldn't mention the generics. However, there are lots more of them than just the List. There are also dictionaries, queues, stacks, and several others. They are good to know about, because type safety reduces bugs and code.
My usual boring signature: Nothing
 
-
Apr 7th, 2010, 02:01 PM
#18
Fanatic Member
Re: [RESOLVED] Probability 1-20 program
not meaning to put out the bonfire but this can be solved with a formula without doing what is like a monte carlo analysis. monte carlo is not the best algorithm for calculating probability, over numbers 1-50 or so it isn't too bad but this is a logarithmic algorithm and could cause major problems if you reused the code in something else that wanted to know how many times to draw a million numbers from a hat for example.
If debugging is the process of removing bugs, then programming must be the process of putting them in.
-
Apr 9th, 2010, 10:40 AM
#19
Thread Starter
Member
Re: [RESOLVED] Probability 1-20 program
 Originally Posted by Megalith
not meaning to put out the bonfire but this can be solved with a formula without doing what is like a monte carlo analysis. monte carlo is not the best algorithm for calculating probability, over numbers 1-50 or so it isn't too bad but this is a logarithmic algorithm and could cause major problems if you reused the code in something else that wanted to know how many times to draw a million numbers from a hat for example.
I understand what you are saying about how a number with 7 digits would halt the execution of this program, but using a mathematical formula wouldn't give me the solutions that I was looking for. I was looking for a program that would show how many tries it would take for any "Joe" that wants to try and see if he/she can get all twenty numbers in 20 tries. Of course, that is a perfect score.
If I used a formula, the random aspect of the problem wouldn't be there, so the program wouldn't feel like "Donnie Baker", "Floyd the Truck Driver", "Jumbo the Elephant", Kenny Tarmac", "Ernie Furglar", "Randy", "Herm Johnson", "Bob Bile", "Hadji", "Ian St. Ian", "Dick Metcalf", "Doc Whiskey", "Dick Mango", or anybody else that wanted to play the game.
By the way, what would this formula look like as a logarithmic equation? Maybe I'm wrong and this logarithmic equation would show how many times it would take each person to draw twenty numbers. But each time a person steps up to play, then the results must be different, because no one is going to draw all twenty numbers every time in sixty-seven tries.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|