Экспериментальное подтверждение решения задачи Монти Холла
На днях познакомился с задачей Монти Холла в контексте той области психологии человека, которая ответственна за принятие решения в обычных жизненных ситуациях. Решение этой задачи вызвало у меня лёгкий шок и я решил проверить её экспериментально.
Надо сказать, что те оригинальные постановки задачи, которые я видел в википедии вызвали у меня некоторое замешательство.
Читаем:
«Представьте, что вы стали участником игры, в которой вам нужно выбрать одну из трех дверей. За одной из дверей находится автомобиль, за двумя другими дверями — козы. Вы выбираете одну из дверей, например, номер 1, после этого ведущий, который знает, где находится автомобиль, а где — козы, открывает одну из оставшихся дверей, например, номер 3, за которой находится коза. После этого он спрашивает вас, не желаете ли вы изменить свой выбор и выбрать дверь номер 2. Увеличатся ли ваши шансы выиграть автомобиль, если вы примете предложение ведущего и измените свой выбор?»
Раз уж речь зашла о вероятностях, я мысленно исключил логическую составляющую из игры, хотя в задаче об этом не было сказано ни слова. Так, у меня не было уверенности, что ведущий будет всегда открывать дверь с козлом. Ведущий мог как пытаться помочь игроку выйграть, так и помешать. Аналогично, не было сказано, могу ли я выбрать ту дверь, которую открыл ведущий (если бы там оказался автомобиль). В общем, прочитав улучшенную постановку задачи, я точно понял о чём речь.
Признаюсь, мне не верилось в решение задачи, хотя я и не плох в теории вероятностей. И несмотря на увиденную схему, которая мне всё прояснила, я решил проверить результат на практике.
Разумеется, проводить дома телешоу или множество испытаний «на пальцах» я не собирался. Да это и не за чем, раз под рукой есть компьютер, верно? Не имея в наличии какой-либо сносной IDE, я воспользовался старым добрым Javascript для написания программы, позволящей мне протестировать результат решения задачи. Следует отметить, что в википедии также упоминается модификация задачи со ста дверями и девяноставосемью открытыми дверями. Я не писал кода для общего случая. Также код не сильно причёсан. Основная его задача — просто подтвердить правильность решения задачи в её основной вормулировке. Итак, вот полный код на Javascript:
// Функция возвращает true, если игрок выйграл авто, иначе - false. // shouldChangeChoise - [bool] указывает должен ли игрок менять своё решение после открытия двери ведущим. function makeSingleTest(shouldChangeChoise) { // За тремя дверями случайным образом расставляются два козла и автомобиль. var doors = [0, 0, 0]; // 0 - козёл, 1 - авто. var indexOfDoorWithCar = getRandomNumber(2); doors[indexOfDoorWithCar] = 1; // Игрок выбирает случайную дверь. var firstChoosenDoorIndex = getRandomNumber(2); // Ведущий выбирает дверь с козлом. Эта дверь не может совпадать с той, которую выбрал игрок. var doorIndicesAvailableToShowman = [0, 1, 2]; // Исключаем дверь с призом. doorIndicesAvailableToShowman = removeItemFrom(doorIndicesAvailableToShowman, indexOfDoorWithCar); // Исключаем дверь, выбранную игроком. doorIndicesAvailableToShowman = removeItemFrom(doorIndicesAvailableToShowman, firstChoosenDoorIndex); // Выбираем из оставшихся одну дверь случайно. var randomIndexOfAvailable = getRandomNumber(doorIndicesAvailableToShowman.length - 1); var showmanSelectedDoorIndex = doorIndicesAvailableToShowman[randomIndexOfAvailable]; // Если аргумент shouldChangeChoise есть true, // то мы меняем своё решение на единственно возможное, // иначе оставляем старое решение. var finalChoosenDoorIndex; if (shouldChangeChoise) { var doorIndicesAvailableToPlayerForChange = [0, 1, 2]; // Исключаем открытую дверь. doorIndicesAvailableToPlayerForChange = removeItemFrom(doorIndicesAvailableToPlayerForChange, firstChoosenDoorIndex); // Исключаем своё старое решение. doorIndicesAvailableToPlayerForChange = removeItemFrom(doorIndicesAvailableToPlayerForChange, showmanSelectedDoorIndex); finalChoosenDoorIndex = doorIndicesAvailableToPlayerForChange[0]; } else { finalChoosenDoorIndex = firstChoosenDoorIndex; } var playerWon = finalChoosenDoorIndex == indexOfDoorWithCar; return playerWon; } // генерирует случайные целые числа в диапазоне 0 - maxValue. function getRandomNumber(maxValue) { return Math.floor(Math.random() * (maxValue + 1)); } // возвращает массив, содержащий все элементы из {array}, кроме {elementToRemove} function removeItemFrom(array, elementToRemove) { var newArray = []; for (var key in array) { var value = array[key]; if (value != elementToRemove) newArray.push(value); } return newArray; } function getDoorName(doorIndex) { return doorIndex == 0 ? 'LEFT' : doorIndex == 1 ? 'MIDDLE' : 'RIGHT'; } function getDoorNames(doorIndices) { var names = ''; for (var i = 0; i < doorIndices.length; ++i) { if (i > 0) names += ', '; names += getDoorName(doorIndices[i]); } return names; } var testNumber = 1000; var winsOnChangeDoor = 0; var winsOnConstantDoor = 0; for (var i = 0; i < testNumber; ++i) { if (makeSingleTest(true)) winsOnChangeDoor++; } for (var i = 0; i < testNumber; ++i) { if (makeSingleTest(false)) winsOnConstantDoor++; } document.write('User won in ' + winsOnChangeDoor/testNumber*100 + '% of situation when he changed his decision. And he won in ' + winsOnConstantDoor/testNumber*100 + '% of situations when he leaved his initial decision');
Обмен ссылками по стройке с гарантией размещения
После исполнения этого теста несколько раз по тысяче испытаний, я получил следующие результаты, подтверждающие корректность решения, представленного EldarMurtazin. Итак, игрок выигрывал лишь в 32-35% случаев, если оставался при своём исходном мнении, в то время как в случае изменения решения выигрывать удавалось в 65-68% случаев. ЧТД, как говорится.