В сцене из фильма аудитории на лекции задаётся вопрос (произвольная трактовка): если перед вами 3 двери, за одной из которых приз, вы выбрали одну из них, я открыл другую, за которой приза нет, то будете ли вы менять свой выбор? Проверяемое утверждение гласит, что стоит менять выбор двери при открытии очередной пустой — это математически обоснованно.
Я сделал версию для любого количества дверей, а тестировал (и сделал скрины результатов) на 10, 100 и 1000 дверей. Мой код также подтвердил, что менять выбор — лучше. Прошу посмотреть код на предмет корректности.
Код Игоря из файла
Код
Option Explicit
Sub Simulator()
Randomize: Columns(7).ClearContents
Dim r&, rc&, a(), i&, j&, m&, p&, v&, b&, c&, rez&()
For j = 1 To 35
ReDim rez(1 To 3): rc = 1000: ReDim a(1 To rc, 1 To 6)
For r = 1 To rc
m = 1
For i = 1 To 3
a(r, i) = Rnd: If a(r, i) > a(r, m) Then m = i
Next
a(r, m) = m: b = 14: b = b And Not 2 ^ m
a(r, 4) = Int(1 + 3 * Rnd): b = b And Not 2 ^ a(r, 4)
If a(r, 4) <> m Then
For i = 1 To 3
If b = 2 ^ i Then Exit For
Next
a(r, 5) = i: rez(3) = rez(3) + 1
Else
p = Int(1 + Rnd * 2): c = 0: rez(1) = rez(1) + 1
For i = 1 To 3
If i <> m Then c = c + 1
If c = p Then a(r, 5) = i: Exit For
Next
End If
For i = 1 To 3
If i <> a(r, 4) And i <> a(r, 5) Then a(r, 6) = i: Exit For
Next
Next
Cells(j, 7) = rez(1)
Next
Cells(3, 1).Resize(rc, 6) = a: Cells(1, 4).Resize(1, 3) = rez
End Sub
Мои скрины и Код
Скрины результатов для 10, 100 и 1000 дверей
Код
Код
Option Base 1
Option Explicit
Option Private Module
'==================================================================================================
Private Function GetRnd(lMin&, lMax&) As Long
Randomize
GetRnd = Int((lMax - lMin + 1) * Rnd + lMin)
End Function
'==================================================================================================
' Изменяет lTry на количество попыток
' Возвращает номер очередной выбранной двери и добавляет её в словарь
Private Function ChooseNextDoor(lMin&, lMax&, dic As Dictionary, Optional lTry&) As Long
lTry = 0
Do
lTry = lTry + 1
ChooseNextDoor = GetRnd(lMin, lMax)
If Not dic.Exists(ChooseNextDoor) Then Exit Function
Loop
End Function
'==================================================================================================
'==================================================================================================
' Возвращает количество попыток, пройденных для нахождения искомого lPrize (статичный выбор)
Function PlayerStatic(lPrize&, lMin&, lMax&) As Long
Dim dicOpen As New Dictionary
Dim lDelta&, lChoose&, lOpen&
lDelta = lMax - lMin + 1 ' количество "дверей" в списке
If lDelta < 3 Then Stop: End
lChoose = GetRnd(lMin, lMax) ' ВЫБИРАЕМ дверь (один раз)
Do
PlayerStatic = PlayerStatic + 1 ' считаем попытки
If lChoose = lPrize Then Exit Function ' если ВЫБРАЛИ на призовую, то выходим
lOpen = ChooseNextDoor(lMin, lMax, dicOpen) ' ОТКРЫВАЕМ очередную дверь (НЕоткрытую ранее)
If lOpen = lPrize Then Exit Function ' если ОТКРЫЛИ призовую, то выходим
dicOpen.add lOpen, 0 ' ДОБАВЛЯЕМ в словарь ОТКРЫТЫХ дверей очередную ОТКРЫТУЮ дверь
If dicOpen.Count = lDelta - 1 Then ' если открыты все, кроме одной, то ОТКРЫВАТЬ не из чего (следующим шагом гарантированно будет ОТКРЫТА ПРИЗОВАЯ дверь)
PlayerStatic = PlayerStatic + 1
Exit Function
End If
Loop
End Function
'--------------------------------------------------------------------------------------------------
' Возвращает количество попыток, пройденных для нахождения искомого lPrize (постоянная смена выбора)
Function PlayerChange(lPrize&, lMin&, lMax&) As Long
Dim dicChoose As New Dictionary, dicOpen As New Dictionary
Dim lDelta&, lChoose&, lOpen&, fAllChosen As Boolean
lDelta = lMax - lMin + 1 ' количество "дверей" в списке
If lDelta < 3 Then Stop: End
dicOpen.add lPrize, 0 ' ДОБАВЛЯЕМ в словарь ОТКРЫТЫХ дверей ПРИЗОВУЮ дверь, чтобы не открыть
Do
PlayerChange = PlayerChange + 1 ' считаем попытки
If fAllChosen Then ' если все двери уже были выбраны …
dicOpen.Remove lPrize ' … УДАЛЯЕМ из словаря ОТКРЫТЫХ дверей ПРИЗОВУЮ, чтобы она участвовала в ВЫБОРЕ
lChoose = ChooseNextDoor(lMin, lMax, dicOpen) ' … ВЫБИРАЕМ очередную дверь с учётом открытых
dicOpen.add lPrize, 0 ' … ДОБАВЛЯЕМ в словарь ОТКРЫТЫХ дверей ПРИЗОВУЮ
Else ' в противном случае …
lChoose = ChooseNextDoor(lMin, lMax, dicChoose) ' … ВЫБИРАЕМ очередную дверь с учётом ВЫБРАННЫХ и ОТКРЫТЫХ дверей ранее
End If
If lChoose = lPrize Then Exit Function ' если попали на призовую, то выходим
dicChoose.add lChoose, 0 ' ДОБАВЛЯЕМ в словарь ВЫБРАННЫХ дверей очередную ВЫБРАННУЮ дверь
dicOpen.add lChoose, 0 ' ДОБАВЛЯЕМ в словарь ОТКРЫТЫХ дверей очередную ВЫБРАННУЮ дверь, чтобы не открыть её
lOpen = ChooseNextDoor(lMin, lMax, dicOpen) ' ОТКРЫВАЕМ очередную дверь (НЕпризовую, НЕоткрытую ранее и не выбранную)
dicOpen.Remove lChoose ' УДАЛЯЕМ из словаря ОТКРЫТЫХ дверей очередную ВЫБРАННУЮ дверь
dicOpen.add lOpen, 0 ' ДОБАВЛЯЕМ в словарь ОТКРЫТЫХ дверей очередную ОТКРЫТУЮ дверь
If dicOpen.Count = lDelta - 1 Then ' если открыты все, кроме одной, то ВЫБИРАТЬ не из чего (следующим шагом гарантированно будет ВЫБРАНА ПРИЗОВАЯ дверь)
PlayerChange = PlayerChange + 1
Exit Function
End If
If dicChoose.Count = lDelta Then ' если словарь выбранных дверей содержит все двери …
fAllChosen = True ' … ставим флаг
dicChoose.RemoveAll ' … очищаем словарь
End If
If Not fAllChosen Then
If Not dicChoose.Exists(lOpen) Then dicChoose.add lOpen, 0 ' ДОБАВЛЯЕМ в словарь ВЫБРАННЫХ дверей очередную ОТКРЫТУЮ дверь (если ещё не все двери были выбраны)
End If
Loop
End Function
'==================================================================================================
'==================================================================================================
Sub TestPlay()
Dim t!, l&, lPrize&, lTry&
Dim lStMin&, lStMax&, lStTot&
Dim lChMin&, lChMax&, lChTot&
Const lMin& = 1, lMax& = 10, lCyc& = 10000
lStMin = lMax
lChMin = lMax
t = Timer
For l = 1 To lCyc
lPrize = GetRnd(lMin, lMax) ' номер двери с призом
lTry = PlayerStatic(lPrize, lMin, lMax)
lStTot = lStTot + lTry
If lStMin > lTry Then lStMin = lTry
If lStMax < lTry Then lStMax = lTry
lTry = PlayerChange(lPrize, lMin, lMax)
lChTot = lChTot + lTry
If lChMin > lTry Then lChMin = lTry
If lChMax < lTry Then lChMax = lTry
Next l
Debug.Print Format$(Timer - t, "0.00")
Debug.Print "Min", "Av", "Max", "Tot"
Debug.Print "St"
Debug.Print Format$(lStMin, "#,##0"), Format$(lStTot / lCyc, "#,##0.0"), Format$(lStMax, "#,##0"), Format$(lStTot, "#,##0")
Debug.Print "Ch"
Debug.Print Format$(lChMin, "#,##0"), Format$(lChTot / lCyc, "#,##0.0"), Format$(lChMax, "#,##0"), Format$(lChTot, "#,##0")
End Sub
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Умом понимаю, что наверное математики правы, а вот сердцем - нет. Вот реально, не понимаю и все тут. St - не менять выбор и Ch - менять выбор ? Немного непонятна статистика, насколько выгоднее менять выбор.
seggi: Немного непонятна статистика, насколько выгоднее менять выбор.
на 1000 дверей - уже почти в 2 раза меньше попыток нужно (см. скрины)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
давайте еще раз) во вложенном файле вы видите эмуляцию последней 1 тыс. игр и статисику угадываний игроком произовой двери, если он выбирал дверь и оставался на своем выборе для 35 тыс. эмулированных игр А:С - макрос присвоил ячейкам 3 случайные числа и в позиции максимального из них расположил приз т.е. приз случайно оказался за одной из 3-х дверей Д - игрок точно так же случайно выбирает какую-то дверь Е - ведущий знает где приз и знает что выбрал Игрок а) открывает случайную из двух дверей, если Игрок угадал приз, или б) открывает ВНИМАНИЕ! единственную оставшуюся пустую (приз за одной дверью, Игрок выбрал другую, без приза осталась одна дверь, она и открывается) вот это и есть развязка в 2/3 случаев Игрок не угадает дверь с призом, соотв. 2/3 что приз за одной из двух оставшихся дверей см. описание в п. б) ведущий открыл пустую дверь теперь эти 2/3 за одной дверь - обязательно выбираем ее.
(чуть упростил код по сравнению с 1-ым вариантом, но это НИКАК не поменяло статистику))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Игорь, всё правильно. В файле Excel мы проверяем не вероятность события (мы ее знаем), а корректность работы функций Excel, эмулирующих случайный выбор.
Владимир, я не проверял, RND на корректность, меня вполне устраивает его работа а проверить правильность можно, например, так: эмулировать 100 раз по 1000 игр, посчитать среднее эмулировать 100 раз по 10тыс. игр, посчитать среднее эмулировать 100 раз по 100тыс. игр, посчитать среднее и посмотреть есть-ли корреляция между количеством эмулированных игр и отношением среднего для выборки к теоретическому среднему возможно, займусь этим сегодня вечером)
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
Ігор Гончаренко, если говорить о выборе после первой открытой, то он 50:50. Мы ж не оцениваем вероятности статистические что после открытия двери 3 приз оказывается за дверью 1 с такой то вероятностью. А снова выбор 1 из 2х. Другое дело что менять выбор не факт что нужно.
Вот если ведущий случайно открыл одну из оставшихся дверей и там нет приза, то вероятность, что приз за выбранной дверью = вероятность, что приз за не открытой оставшейся = 50% (на самом деле по 33%, просто они равны, так как в 33% открытий ведущего за открытой им дверью будет приз ). Однако, в игре ведущий знает, где приз и 100% открывает дверь без приза. После такого действия ведущего вероятность приза за первовосхождение выбранной - 33%, за оставшейся - 67%.
Можно в Таблице games_count изменить число игр и нажать Обновить все. Результат ожидаем Выбор нужно менять. Если кто-то хочет проверить на более 1млн игр, уберите загрузку запроса на лист. Результаты считаются в PP. Правда я уверен, что в этом нет необходимости Распределение будет таким же.
с учетом выше сказанного давайте вернемся к условиям задачи есть игрок и ведущий, есть 3 двери за одной из которых есть приз (понятно - случайно за какой) Игорок тычет пальцем в одну из дверей "здесь!" ведущий знает где приз, где пусто и не зависимо от того угадал Игрок дверь с призом или нет, открывает пустую дверь, и спрашивает у игрока "не хотите-ли вы изменить свой выбор в пользу оставшейся закрытой двери?" вопрос: что делать Игроку, остаться на начальном выборе или сменить выбор? или поставим вопрос по другому каковы шансы что за другой дверью приз?
мой ответ. вероятность 2/3, нужно менять дверь, у двери, которую я выбрал первоначально вероятность была 1/3. сменой двери не факт, что я выиграю, но повышаю вероятность выигрыша ровно в 2 раза есть другие мнения? или может кто-то хочет что-то уточнить по условиям задачи? смелее))
в сообщении 14 нет дополнительных данных, я просто решил напомнить условия задачи чтобы снять возможное недопонимание 1/3 больше 2/3 ровно в 2 раза смена двери при описанных выше условиях увеличивает вероятность выигрыша ровно в 2 раза
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
БМВ, да когда вероятность становится 50%? Вероятность, что приз за дверью, выбранной игроком, как была 33%, так и осталась. Действия ведущего ничего не изменили. А вот вероятность, что приз за одной из 2-х дверей, не выбранных игроком, изначально 67%. А ведущий нам просто открывает одну точно непризовую из них. Таким образом за третьей дверью приз в вероятностью 67%.
Если, как я уже писал, ведущий будет открывать одну из не выбранных дверей случайно (он не знает, где приз), то вероятность, что приз за выбранной дверью так же 33%. Просто в 33% случаев ведущий будет открывать приз и игра закончится. Так же приз в 33% игр за выбранной дверью (ну не изменилась она), в 33% игр в не выбранной и не открытой ведущим. В таком случае можно говорить, что после того, как ведущий открыл непризовую дверь, вероятность найти приз 50/50. Просто треть игр до этой стадии не дойдет. И по сути тут вероятности 33/33. Выбор можно не менять. А можно и менять. Игрок получит приз в игре с вероятностью 33%.
Но мы вообще в другую игру играем Ведущий знает, где приз, и 100% откроет непризовую дверь. Тогда вероятности выбранная/не выбранная - 33%/67%.
Кстати. Суть вопроса: найти оптимальную стратегию и вероятность, с которой игрок получает приз. Ответ: изменить первоначальный выбор, вероятность выигрыша 67% (это в 2 раза больше, чем без изменения выбора).
Рад, что вам нравится, ребята) Ведущий всё решает, я вам точно говорю - просто он "в голове" как будто игнорируется) БМВ, я тебя очень понимаю, но эти циферки грёбаные...)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
вы только вопрос задали (причём не по теме), а мы с Игорем дали код. К тому же, я создал отдельную тему для обсуждения, чтобы не засорять чужую а за вопрос - спасибо Ігор Гончаренко
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Где-то предлогалось для лучшего понимания того стоит или не стоит менять дверь и понимания как меняется процент, предположить, что дверей не 3, а 1000. Вы выбираете дверь, ведущий открывает 998 дверей, за которыми нет приза. Стоит ли поменять дверь? Очевидно, что да По сути то же самое ведущий делает и в случае с тремя дверьми, только не так кардинально меняется процент.
whateverlover: предположить, что дверей не 3, а 1000
у меня работает для любого количества дверей больше 2ух
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
whateverlover написал: Вы выбираете дверь, ведущий открывает 998 дверей, за которыми нет приза. Стоит ли поменять дверь? Очевидно, что да
Я вот тоже не понимаю, почему вероятность не распределяется равно на оставшиеся двери. Пытаясь понять пришле лишь к такой логике, что если ведущий не 993 раз открыл двери но не тронул эту дверь (выбранную то он все равно не может тронуть) значит у этой двери вероятность выше. Но если он ее слегка потрогает.. и врочем это лишь фантазии..
нет у первоначально выбранной двери никакого вероятностного преимущества по условиям задачи, ведущий открывает остальные двери, кроме двери с призом), а если она уже выбрана, просто не задумываясь открывает любые двери, кроме одной
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!