Экспериментальное подтверждение решения задачи Монти Холла

22 декабря 2010 г.


На днях познакомился с задачей Монти Холла в контексте той области психологии человека, которая ответственна за принятие решения в обычных жизненных ситуациях. Решение этой задачи вызвало у меня лёгкий шок и я решил проверить её экспериментально.

Надо сказать, что те оригинальные постановки задачи, которые я видел в википедии вызвали у меня некоторое замешательство.
Читаем:
«Представьте, что вы стали участником игры, в которой вам нужно выбрать одну из трех дверей. За одной из дверей находится автомобиль, за двумя другими дверями — козы. Вы выбираете одну из дверей, например, номер 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% случаев. ЧТД, как говорится.

Теги:
рубрика Интернет