Kebaan Posted August 17, 2008 Posted August 17, 2008 After watching the movie 21 (about blackjack) and the serie Numb3rs, Iøve obviously seen that if there are 3 choices, and theres a car behind one of the gates and goats behind the others. As an example I'll say you choose gate number one, so I tell you that behind gate number 2 there is a goat. The question is: "do you want to chage your guess to gate number 3?" In these movies they say that you would have a much higher chance of winning the car if you change your guess. At first i did not understand why, so i wanted to make an experiment in autoit. So here it is. I just wanted to show you and if I've made something in a weird way, please let me know how i should've made it =D I know that my ASCII drawing could be made with some GUI instead, but i didn't feel like doing that yet expandcollapse popup;----------------------------------------------------------------------------------------; ; If you get the following choices: ; ; ______ ______ ______ ; ; | | | | | | ; ; | 1 | | 2 | | 3 | ; ; |______| |______| |______| ; ; Youre told that on of them is a car, the other two is goats. ; ; If you choose 1, and the gamemaster tell you that gate number 2 is a goat. ; ; Would you change your guess to gate number 3? ; ; ; ; This is a simulation that shows that you would have a better chance of winning the car ; ; if you did that! ; ; @Author: Kebaan ; ;----------------------------------------------------------------------------------------; Global $one, $two, $three, $prize, $car = "car", $goat = "goat", $choice, $carcount = 0, $carcount1, $percent MsgBox(0, "Three gates - but only one car!", "You get the following choices:" & @CRLF & " ______ ______ ______" & @CRLF & "| | | | | |" & @CRLF & "| 1 | | 2 | | 3 |" & @CRLF & "|______| |______| |______|" & @CRLF & @CRLF & "The 'gamemaster' tells you that there are one car and two goats behind the gates." & @CRLF & "If you choose gate number one, and the gamemaster tells you that gate number two is a goat." & @CRLF & "Would you want to change your guess to gate number three?" & @CRLF & @CRLF & "This is a simulation that shows that you would have a better chance of winning the car if you did!") Global $NumberOfSimulations = InputBox("Times to run the simulation?", "Here you can choose how many times you want to run the simulation." & @CRLF & @CRLF & "The precision of the result depends on how many times you run the simulation.") For $i = 1 to $NumberOfSimulations $prize = Random(1, 3, 1);===> Find a random gate to place the car. If $prize = 1 Then $one = $car $two = $goat $three = $goat ElseIf $prize = 2 Then $one = $goat $two = $car $three = $goat Else $one = $goat $two = $goat $three = $car EndIf;===> Define the gates' content. $choice = Random(1, 3, 1);===> Make a random guess. If $choice = 1 and $two = $goat Then $choice = 3 If $three = $car Then $carcount = $carcount + 1 Else $carcount = $carcount EndIf ElseIf $choice = 1 and $three = $goat Then $choice = 2 If $two = $car then $carcount = $carcount + 1 Else $carcount = $carcount EndIf ElseIf $choice = 2 and $one = $goat Then $choice = 3 If $three = $car then $carcount = $carcount + 1 Else $carcount = $carcount EndIf ElseIf $choice = 2 and $three = $goat Then $choice = 1 If $one = $car then $carcount = $carcount + 1 Else $carcount = $carcount EndIf ElseIf $choice = 3 and $one = $goat Then $choice = 2 If $two = $car then $carcount = $carcount + 1 Else $carcount = $carcount EndIf Else $choice = 2 and $three = $goat $choice = 1 If $one = $car then $carcount = $carcount + 1 Else $carcount = $carcount EndIf EndIf;===> Lots of logic, made to simulate that the guess is changed! $prize = Random(1, 3, 1);===> Find a random gate to place the car. If $prize = 1 Then $one = $car $two = $goat $three = $goat ElseIf $prize = 2 Then $one = $goat $two = $car $three = $goat Else $one = $goat $two = $goat $three = $car EndIf;===> Define the gates' content. $choice = Random(1, 3, 1);===> Make a random guess. If $choice = 1 Then If $one = $car Then $carcount1 = $carcount1 + 1 Else $carcount1 = $carcount1 EndIf ElseIf $choice = 2 Then If $two = $car Then $carcount1 = $carcount1 + 1 Else $carcount1 = $carcount1 EndIf Else $choice = 3 If $three = $car Then $carcount1 = $carcount1 + 1 Else $carcount1 = $carcount1 EndIf EndIf;===> Lots of logic, made to simulate that you stick to your first guess! Next $percent1 = $carcount1 / $NumberOfSimulations * 100 $percent = $carcount / $NumberOfSimulations * 100 MsgBox( 0, "Number of cars won in %", "If you stuck to your first guess you would have won " & $percent1 & "% of the times!" & @CRLF & "But if you changed your guess you would have won " & $percent & "% of the times!")
monoceres Posted August 17, 2008 Posted August 17, 2008 Hi!This problem is called the monty hall problem. Read more about it here I also made a script some time ago to prove this, it has an GUI and it deals with the problem in a different way.Maybe you could learn a thing or two expandcollapse popup#include <GUIConstants.au3> #include <WindowsConstants.au3> #include <GUIEdit.au3> #NoTrayIcon Global $car, $choosed, $removed, $switchedfrom Global $switch=True Global $totalwon=0, $totalgames=0 Global $tests=0, $start=False Opt("GUIOnEventMode", 1) #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Monty Hall", 224, 276, 193, 125) $Label1 = GUICtrlCreateLabel("Number of tests:", 8, 8, 60, 17*2) $Input1 = GUICtrlCreateInput("10000", 72, 8, 121, 21, BitOR($ES_RIGHT,$ES_AUTOHSCROLL,$ES_NUMBER)) $Label2 = GUICtrlCreateLabel("Change door?", 8, 40, 63, 17*2) $Combo1 = GUICtrlCreateCombo("Yes", 72, 40, 121, 25) GUICtrlSetData(-1,"No") $Button1 = GUICtrlCreateButton("Start!", 8, 72, 187, 25, 0) GUICtrlSetOnEvent(-1,"_starta") $Edit1 = GUICtrlCreateEdit("", 8, 112, 209, 153, BitOR($ES_AUTOVSCROLL,$ES_READONLY,$ES_WANTRETURN,$WS_VSCROLL)) _GUICtrlEdit_SetLimitText($Edit1,10^100) GUICtrlSetData(-1, "") GUISetOnEvent(-3,"close") GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 Sleep(10) If $start=True Then $start=False _calc() EndIf WEnd Func _starta() $start=True EndFunc Func _calc() If GUICtrlRead($Combo1)="Yes" Then $switch=True Else $switch=False EndIf $tests=GUICtrlRead($Input1) GUICtrlSetData($Edit1,"") For $i=1 To $tests $car=Random(0,2,1) $choosed=Random(0,2,1) Do $removed=Random(0,2,1) Until $removed<>$car AND $removed<>$choosed If $switch Then For $j=0 To 2 If $j<>$choosed And $j<>$removed Then $choosed=$j ExitLoop EndIf Next EndIf If $choosed=$car Then $totalwon+=1 $totalgames+=1 _GUICtrlEdit_AppendText($Edit1,"Victory! ("&$totalwon&" / "&$totalgames&" ("&Round(($totalwon/$totalgames)*100,2)&" %))"&@CRLF) Else $totalgames+=1 _GUICtrlEdit_AppendText($Edit1,"Lose! ("&$totalwon&" / "&$totalgames&" ("&Round(($totalwon/$totalgames)*100,2)&" %))"&@CRLF) EndIf Next EndFunc Func close() Exit EndFuncPs. I think it would be better to post this in example script Broken link? PM me and I'll send you the file!
Kebaan Posted August 17, 2008 Author Posted August 17, 2008 Yea i thought about that, but when looking ón all the other scripts in there i thought my script was very small and too newbyish Your on is noce but i think my one is faster? And I've got an update for yours you should do this in the start of your _calc function i think? $totalwon = 0 $totalgames = 0 Because as it is now the %calculation is wrong if you start doing a simulation where you do not change the doors and afterwards make it while changing doors (or the other way around of course) But I'll try to figure out how the GUI works =) thanks for the script
SaphuA Posted August 17, 2008 Posted August 17, 2008 (edited) I was trying to be a smart-ass and made the same simulation in just 22 lines... but it doesn't work! Does anyone see what I'm doing wrong?Here's the code:dim const $TESTS = 4 dim const $SIMULATIONS = 10000 $output = "" for $j=1 to $TESTS $win1 = 0 for $i=1 to $SIMULATIONS $car = Random(1, 3, 1) $choice = Random(1, 3, 1) if $choice == $car then $win1 += 1 next $result1 = Round(($win1 / $SIMULATIONS) * 100) $win2 = 0 for $i=1 to $SIMULATIONS $car = Random(1, 3, 1) $choice = Random(1, 3, 1) if $choice <> $car then $win2 += Random(0, 1, 1) next $result2 = Round(($win2 / $SIMULATIONS) * 100) if $j > 1 then $output &= @LF & @LF $output &= "Test " & $j & @LF & "Stick: " & $win1 & "/" & $SIMULATIONS & " (" & $result1 & "%)" & @LF & "Switch: " & $win2 & "/" & $SIMULATIONS & " (" & $result2 & "%)" next MsgBox(0, "", $output)Here's the thought behind it:- Line's 6-10 is the test for sticking with your choice. The only thing that needs to be checked is that the first choice is the same as the location of the car. This part works well (as I always get a result of approx 33%).- Line's 13-17 is the test for switching your choice. It will first check if your first choice is not equal to the car (because if it is you will never win anyway). Otherwise you'll still have a 50% chance to win. So I simply used Random(0,1,1) to simulate this. However, something in here's goes wrong but I have no idea what.Anyone? Edited August 17, 2008 by SaphuA http://www.saphua.com/
Kebaan Posted August 17, 2008 Author Posted August 17, 2008 (edited) I don't understand line 18-20.. but on line 16 i don't understand why you would add random 0 or 1.. If you do not get the car you should add 1 all the time? so the code should be? dim const $TESTS = 4 dim const $SIMULATIONS = 10000 $output = "" for $j=1 to $TESTS $win1 = 0 for $i=1 to $SIMULATIONS $car = Random(1, 3, 1) $choice = Random(1, 3, 1) if $choice == $car then $win1 += 1 next $result1 = Round(($win1 / $SIMULATIONS) * 100) $win2 = 0 for $i=1 to $SIMULATIONS $car = Random(1, 3, 1) $choice = Random(1, 3, 1) if $choice <> $car then $win2 += 1 next $result2 = Round(($win2 / $SIMULATIONS) * 100) if $j > 1 then $output &= @LF & @LF $output &= "Test " & $j & @LF & "Stick: " & $win1 & "/" & $SIMULATIONS & " (" & $result1 & "%)" & @LF & "Switch: " & $win2 & "/" & $SIMULATIONS & " (" & $result2 & "%)" next MsgBox(0, "", $output) I've tested and now it works .. but would you please explain lin 19-21? EDIT: nvm, i understand the lines now thanks Edited August 17, 2008 by Kebaan
Uten Posted August 17, 2008 Posted August 17, 2008 Funny you brought this up. I remember the lecture where I encountered this. Apparently it was a woman who solved, and explained, this kind of problem domain. The fact that she beet here male colleagues to it did not fall in good earth (as we say in Norway). They even gave here the nick name "The Goat". At least that is the story our prof. gave.. I just wanted to show you and if I've made something in a weird way, please let me know how i should've made it =DSince you ask. I don't know how you should have made it. this is how I would have done it. Lesson to learn is: small testable functions. Comments in the code. Tests to verify the functions. When you know it works you can add the snazzy GUI. Or you can work on some other statistical functions to verify or contradict the results you get. expandcollapse popupopt("MustDeclareVars", 1) Func MontyHallGame() ; Chose on of three boxes. Then you get to know one loosing box ; With this additional information Probability theory now ; indicates that you should switch your choice. ; ; Returns 1 if you win otherwise 0. ; @extended contains 1 if you selected the winner on the first choice ; ; Chose one of three boxes. When you have chosen Local $selected, $ext=0, $winner, $knownLoser ; One is the winning box $winner = Random(0,2,1) ; You select one box sleep(random(0, 10,1)) $selected = Random(0,2,1) ; If you have a winner, you dont know it. So set a flag to let us know later. $ext = 1 $ext = $selected AND $winner ; At this point you get to know one looser box $knownLoser = GetAMontyHallLooser($selected, $winner) ; Switch selection based on previous selection and new knowledge. Return SetExtended($ext, $winner = SwitchMontyHallChoice($knownLoser, $selected)) EndFunc Func GetAMontyHallLooser($selected, $winner) ; The participant chose $selected ; The game host knows the $winner Local $ret Do $ret = Random(0,2,1) Until $ret <> $selected AND $ret <> $winner Return $ret EndFunc func testGetAMontyHallLooser() ; Verify GetAMontyHallLooser function assert(0 = GetAMontyHallLooser(1, 2)) assert(1 = GetAMontyHallLooser(0, 2)) assert(2 = GetAMontyHallLooser(0, 1)) assert(0 = GetAMontyHallLooser(2, 1)) assert(2 = GetAMontyHallLooser(1, 0)) assert(1 = GetAMontyHallLooser(2, 0)) EndFunc Func SwitchMontyHallChoice($known, $select) If $known+$select = 1 then Return 2 If $known+$select = 3 then Return 0 If $known+$select = 2 then Return 1 EndFunc Func testSwitchMontyHallChoice() ; Verify SwitchMontyHallChoice function assert(1 = SwitchMontyHallChoice(0, 2)) assert(0 = SwitchMontyHallChoice(1, 2)) assert(2 = SwitchMontyHallChoice(0, 1)) EndFunc func assert($val, $msg="", $erl=@ScriptLineNumber, $err=@error, $ext=@extended) If not $val Then ConsoleWrite("(" & $erl & ") := [" & $err & "][" & $ext & "] " & $msg & @CRLF) EndFunc ; ========================================= ; Run self tests If not @Compiled Then testAssert() exit testGetAMontyHallLooser() testSwitchMontyHallChoice() EndIf ; ========================================= ; === Main part Local $i, $wins, $target ; Run test For $r = 1 to 10 For $i = 1 to 1000 $wins += MontyHallGame() $target += @extended Next ConsoleWrite("Wins:=" & $wins & ", target:=" & $target & @crlf) $wins = 0 $target = 0 next Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling
SaphuA Posted August 17, 2008 Posted August 17, 2008 (edited) No you're wrong. In the second case, where the player always decides to pick something different, 2 things can happen: - If the player picks the car, he can only pick a goat so he wins nothing. - If he picks a goat, he can either pick a car or a goat, so he then has 50% chance of winning or losing. So in my code I first check to see if the player did NOT pick the car (if he did it's over anyway). if $choice <> $car If that is true I increase the score with: $win += Random(0, 1, 1) Since it's random, there is a 50% chance that it returns 0 and 50% chance that it returns 1. So either he get's added 0 score or 1. In theory, it sounds perfectly fine to me, yet there's still a flaw in my code. Edited August 17, 2008 by SaphuA http://www.saphua.com/
Kebaan Posted August 17, 2008 Author Posted August 17, 2008 - If he picks a goat, he can either pick a car or a goat, so he then has 50% chance of winning or losing.If that was right you had made it right - but! you forget that the gamehost will reveal one of the goats after your first choice. So if you pick a goat, he will show you the other one, and you will only have the car left @Uten, thanks for the reply. I'm learning alot of this I don't understand all your code though, but i think I will when i have time to read abit up on it
SaphuA Posted August 17, 2008 Posted August 17, 2008 Ohhh yes! I was a total idiot. Then your edited version is indeed the correct one. http://www.saphua.com/
Uten Posted August 17, 2008 Posted August 17, 2008 (edited) SaphuA, care to elaborate where I'm wrong. I don't get it. I'm not saying I ain't. Is my understanding of the game wrong or is it the implementation?From the wikipage:Suppose you're on a game show, and you're given the choice of three doors: Behind one door is a car; behind the others, goats. You pick a door, say No. 1, and the host, who knows what's behind the doors, opens another door, say No. 3, which has a goat. He then says to you, "Do you want to pick door No. 2?" Is it to your advantage to switch your choice?This was how I remembered it from the lecture. Just had to look at it since you made your claim.Remember that the player do not get to open the first door he chose. Neither do he get the knowledge that there is a car or a donkey behind it. All he gets to know is where there is a donkey after he has made his choice!so your analysis - If the player picks the car, he can only pick a goat so he wins nothing.- If he picks a goat, he can either pick a car or a goat, so he then has 50% chance of winning or losing.does not look correct to me.UtenEdit: A tad late there I see.. Got to start typing faster and checking less.. Edited August 17, 2008 by Uten Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling
Uten Posted August 18, 2008 Posted August 18, 2008 (edited) It was a reply on kebaan Now that you have removed my name, it could be. When you first posted it, it was addressed to me!EDIT: Look at my next post. Edited August 18, 2008 by Uten Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling
SaphuA Posted August 18, 2008 Posted August 18, 2008 Now that you have removed my name, it could be. When you first posted it, it was addressed to me!Lies! http://www.saphua.com/
Uten Posted August 18, 2008 Posted August 18, 2008 I have to admit you that your right about the name SaphuA. Dog out the deleted mail notification from a backup and found that I have mixed up the part where notification inserts my name, with your post. Sincerely sorry about that SaphuA. Uten Please keep your sig. small! Use the help file. Search the forum. Then ask unresolved questions :) Script plugin demo, Simple Trace udf, TrayMenuEx udf, IOChatter demo, freebasic multithreaded dll sample, PostMessage, Aspell, Code profiling
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now