
Nov 9th, 2012, 12:57 PM
#1
Thread Starter
New Member
The Monty Hall Problem
I'm writing a quick a simulation for The Monty Hall Problem but it comes up with winning a car 75% of the time, even with 20k simulations. It does that every time, but I can't understand why. It should win a car 66% of the time. Any ideas? Here's my procedure for a single simulation:
Code:
Private Function Simulate() As Boolean 'true means a car was won; false means a goat was won
Dim Door(2) As Boolean
Dim doornum As SByte
Dim choice As SByte = 0 'initially choose the first door every time
Randomize()
doornum = Math.Round(Rnd() * 2) 'generate a random number between 0 and 2
Door(doornum) = True 'set a random door to have a car behind it
If Door(1) = False Then 'if the second (zerobased) door is opened,
choice = 2 'choose the third
ElseIf Door(2) = False Then 'if the third door is opened,
choice = 1 'choose the second
End If 'change choice to one of the other doors
If Door(choice) Then 'if the new choice has a car,
Return True
Else 'if the new choice doesn't have a car
Return False
End If
End Function
Cheers

Nov 9th, 2012, 01:38 PM
#2
Re: The Monty Hall Problem
Nope... 75% of the time is correct... Mythbusters covered this once on why it comes out the way it does....
Mythbusters Monty Hall
tg

Nov 10th, 2012, 09:02 AM
#3
Re: The Monty Hall Problem
I don't know what answer Myth Busters came up with as all the video links seem to have been taken down by the copyright police. However, if it's the standard Monty Hall problem then the answer should be 66%.
The reason you are getting 75% is that your method for generating random numbers is somewhat skewed (in this particular case you'll get twice as many 1's as 0's or 2's).
There's a couple of easy fixes:
1) If using the VBMath.Rnd() method, use the formula recommended in the MSDN here which in this case would simplify to
Code:
doornum = CInt(Math.Floor(3 * Rnd()))
2) Create an instance of the Random Class. You would create only one instance at Class level (prevents sequence repetition) and use its .Next method in your function.
Code:
Public Class Whatever
Private rnGen As New Random ' at Class Level
Private Function Simulate() As Boolean 'true means a car was won; false means a goat was won
Dim Door(2) As Boolean
Dim doornum As SByte
Dim choice As SByte = 0 'initially choose the first door every time
doornum = rnGen.Next(3)
' code
End Function
End Class

Nov 12th, 2012, 04:06 PM
#4
Thread Starter
New Member
Re: The Monty Hall Problem
Thanks very much Inferrd, that was exactly the problem. I replaced Math.Round(Rnd() * 2) with Int(Rnd() * 3) and it worked great. I do understand where I went wrong now  half of the real numbers between 0 and 2 round to 1, but only a quarter round to each 0 and 2.
Thanks again

Nov 12th, 2012, 09:04 PM
#5
Re: The Monty Hall Problem
Since this is .NET, you shouldn't be using Randomize and Rnd. You should scrap that in favor of the Random object. For one thing, the way you are using Randomize will cause you trouble if you were to test the program by calling Simulate in a tight loop. The issue is that Randomize will seed the random number generator with the current system time down to the second. By calling Simulate in a tight loop, you would end up calling Randomize more than once per second, which would mean that it would seed more than once with the same value, which would mean that your sequence would be exactly the same over and over and over, until the second advanced and you got a new sequence again and again.
The Random object has the same issue, of course, but if you create it a single Random object at form scope then you won't have that issue. You could also solve the problem by calling Randomize only one time, such as in Form Load, but what's the point of using Rnd, which sucks, versus the GetNext method of Random, which is far easier to get right?
My usual boring signature: Nothing
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
