1 Востаннє редагувалося Betterthanyou (10.09.2016 20:58:03)

Тема: Парадокс Монти Холла

Я пам'ятаю ще рік назад дивився відео про парадокс Монти Холла

Хто ще не знає що це таке то перегляньте статтю
Хоч на відео детально розповідалося про цей парадокс я тоді (рік назад) подумав що це якийсь жарт, як різниця чи міняти свою думку чи ні якщо в кінці гри є всього двоє дверей шанс 50 на 50 виграти чи програти, але недавно я побачив ще раз схоже відео і вирішив перевірити чи це справді так, перше що мені прийшло на думку це створити таблиць всіх можливих варіантів комбінацій, щоб випадково не помилитися я вирішив зробити невелику програму яка сформує цю таблицю

Програма+скріншот
#include <iostream>
#include <Windows.h>

using namespace std;

void whatIt(int x)
{
    if (x == 0)
        cout << " | car      ";
    else
        cout << " | goat (" << x << ") ";
}

void table(int i, int j, int k)
{
    /*
    події залежать одна від одної тому їх потрібно відсіяти
    наприклад не може бути два автомобіля і ода коза в трьох дверях
    */
    if (i == j || j == k || k == i)
        return;

    static int ind = 0;
    cout << ++ind << ") ";//номер рядка
    /* i, j, k - це комбінація, */
    whatIt( i );
    whatIt( j );
    whatIt( k );
    cout << " |\n";
    for (int j(0); j < 41; j++)
        cout << '-';
    cout << "\n";
}

int main()
{
    SetConsoleTitleA("Monty Hall Problem");

    //генерація всіх можливих чисел
    for (int i(0); i < 3; i++)
    {
        for (int j(0); j < 3; j++)
        {
            for (int k(0); k < 3; k++)
            {
                //відсіювання не можливих комбінацій
                table(i, j, k);
            }
        }
    }

    system("pause");
    return 0;
}

https://replace.org.ua/extensions/om_images/img/57d45583da101/47482b12adf2d6aa63bf9f080add0837.png

якщо не нумерувати кози то вийде те саме що й у вікіпедії

Мені стало цікаво спробувати це на практиці тому я зробив симулятор цієї гри, якщо вам цікаво, ви можете переглянути проект на Github
https://github.com/OleksandrMyronchuk/M … ll-Problem
Завантажити виконуваний файл
https://www.dropbox.com/s/gvijkv7qhqaca … m.exe?dl=0
Якщо будуть проблеми з завантаженням чи у вас програма не запуститься то повідомте, я закину знанова
Якщо вас Windows буде попереджати про небезпеку, натисніть "More info" -> "Run anyway"

Скрін

https://replace.org.ua/extensions/om_images/img/57d45583da101/75e8062720fd93ad123e31219b21f74c.png

Подякували: 221VOLT, leofun01, Arete3

2 Востаннє редагувалося Betterthanyou (11.09.2016 17:08:01)

Re: Парадокс Монти Холла

Я зіграв 30 ігор змінюючи двері і залишаючи ті що вибрав перший раз. Нажаль кожного разу цифри дуже сильно відрізняються (потрібно більше зіграти щоб результати були 33% і 66%), але все одно тактика зміни дверей постійно перемагає
Ось приблизні результати

1) Не змінювати двері: 9 - перемог, 21 - програш

https://replace.org.ua/extensions/om_images/img/57d5727570f0d/08f1ef905c2b48421ddf418b11719fd1.png

2) Змінювати двері: 25 - перемог, 5 - програш

https://replace.org.ua/extensions/om_images/img/57d5727570f0d/2d494543c75d9f0e3572383527c14771.png

3 Востаннє редагувалося ADR (11.09.2016 17:51:42)

Re: Парадокс Монти Холла

якщо я правильно зрозумів, що ви зробили то, програма не повинна працювати:

При розв'язанні цієї задачі зазвичай розмірковують приблизно так: після того, як ведучий відчинив двері, за якими знаходиться коза, автомобіль може бути за одними з двох дверей, що залишились. Оскільки гравець не може отримати ніякої додаткової інформації про те, за якими дверима знаходиться автомобіль, то ймовірність знаходження автомобіля за кожними з дверей однакова, і зміна вибору не дає гравцю додаткових переваг. Однак такий хід роздумів неправильний. Якщо ведучий завжди знає, за якими дверима що знаходиться, то він завжди відкриває ті двері, за якими знаходиться коза, і завжди пропонує гравцю змінити вибір, тоді ймовірність того, що автомобіль знаходиться за дверима, які були обрані спочатку, дорівнює 1/3, і, відповідно, ймовірність того, що автомобіль знаходиться за дверима, що залишились, дорівнює 2/3. Таким чином, зміна початкового вибору збільшує шанси гравця вдвічі. Цей висновок суперечить інтуїтивному сприйняттю більшості людей, тому ця задача і називається парадоксом Монті Холла.

4 Востаннє редагувалося Master_Sergius (11.09.2016 19:12:21)

Re: Парадокс Монти Холла

Такі теорії вручну не перевіряються. Побтрібно автоматизувати процес. Ось наприклад, код для перевірки процентного відношення виграшів із великої кількості партій (наразі ввів 10000, щоб дуже довго не чекати). І схоже, що воно таки працює, дивина та й годі!

Without swap: 33.72%
With swap: 66.83%

Without swap: 34.10%
With swap: 67.10%

Without swap: 33.05%
With swap: 66.85%

Сам код:

import random

DOORS = ['car', 'goat', 'goat']

def open_goat(doors, player_choice):
    """Host opens doors with goat"""
    goat, unknown = None, None
    for index, value in enumerate(doors):
        if index != player_choice:
            if value == 'goat':
                goat = index
                rest = set([0,1,2]) - {player_choice} - {goat}
    for i in range(3):
        if i in rest:
            return (goat, i)

def play_it(doors, swap=False):
    """Play game"""
    player_choice = random.randint(0,2)
    goat, unknown = open_goat(doors, player_choice)
    if swap:
        return 'car' == doors[unknown]
    return 'car' == doors[player_choice]


# Test winrate
play_number = 10000
win_count = 0
for i in range(play_number):
    random.shuffle(DOORS)
    if play_it(DOORS):
        win_count += 1

print('Without swap: %.2f%%' % (win_count / play_number * 100))


win_count = 0
for i in range(play_number):
    random.shuffle(DOORS)
    if play_it(DOORS, swap=True):
        win_count += 1

print('With swap: %.2f%%' % (win_count / play_number * 100))

Отже, прошу перевіряти.

Подякували: Betterthanyou1

5

Re: Парадокс Монти Холла

ADR написав:

Якщо ведучий завжди знає, за якими дверима що знаходиться, то він завжди відкриває ті двері, за якими знаходиться коза

В мете так і працює програма, спочатку гравець вибирає будь які двері, потім програма (ведучий) відкриває двері за якими знаходиться коза і запитує гравця чи хоче гравець він змінити двері, далі програма каже чи виграв гравець чи ні і відкриває всі двері

приклад

https://replace.org.ua/extensions/om_images/img/57d5a13f4978f/2a5cc6bfb9a64846cf3cf2903494ca13.png

Ось я натиснув на двері номер 2, ці двері сталь жовтого кольору, і програма відкрила двері номер 1.
Алгоритм такий
1) Програма зарання сформувала що в яких дверях має бути ( це зберігається в масиві things ), 0 - це автомобіль, 1,2 - це кози
2) Програма чекає поки гравець натисне на двері (перший раз натисне)
3) Програма виводить повідомлення "Я вам допоміг, відкривши одні..." (прочитайте на скріні) і дивиться якщо за дверима що вибрав перший раз гравець машина то рандомно відкриває ті двері де є коза, в іншому випадку ( коли гравець вибрав першого разу двері з козою ) програма відкриває ті двері що не обрав гравець і немає за ними автомобіля
4) Програма чекає поки гравець натисне на двері (другий раз натисне) тобто він вибирає цього разу між двома дверима
5) В залежності від перемоги чи програшу виводиться повідомлення і відкриваються всі двері (а щоб користувач не забув свого вибору дверей, ті двері що вибрав гравець стають жовтого кольору)

уривок коду до 3 пункту
if(this->car == openDoor)
    {
        num = rand() % 2;
        if( num == this->car)
            if(++num == 2)
                num = 0;
    }
    else if(this->car != openDoor)
    {
        for(int i = 0; i < 3; i++)
        {
            if(i != this->car && i != openDoor)
            {
                num = i;
                break;
            }
        }
    }

Нагадую весь код на GitHub

Подякували: ADR1

6

Re: Парадокс Монти Холла

Прихований текст
Master_Sergius написав:

Такі теорії вручну не перевіряються. Побтрібно автоматизувати процес. Ось наприклад, код для перевірки процентного відношення виграшів із великої кількості партій (наразі ввів 10000, щоб дуже довго не чекати). І схоже, що воно таки працює, дивина та й годі!

Without swap: 33.72%
With swap: 66.83%

Without swap: 34.10%
With swap: 67.10%

Without swap: 33.05%
With swap: 66.85%

Сам код:

import random

DOORS = ['car', 'goat', 'goat']

def open_goat(doors, player_choice):
    """Host opens doors with goat"""
    goat, unknown = None, None
    for index, value in enumerate(doors):
        if index != player_choice:
            if value == 'goat':
                goat = index
                rest = set([0,1,2]) - {player_choice} - {goat}
    for i in range(3):
        if i in rest:
            return (goat, i)

def play_it(doors, swap=False):
    """Play game"""
    player_choice = random.randint(0,2)
    goat, unknown = open_goat(doors, player_choice)
    if swap:
        return 'car' == doors[unknown]
    return 'car' == doors[player_choice]


# Test winrate
play_number = 10000
win_count = 0
for i in range(play_number):
    random.shuffle(DOORS)
    if play_it(DOORS):
        win_count += 1

print('Without swap: %.2f%%' % (win_count / play_number * 100))


win_count = 0
for i in range(play_number):
    random.shuffle(DOORS)
    if play_it(DOORS, swap=True):
        win_count += 1

print('With swap: %.2f%%' % (win_count / play_number * 100))

Отже, прошу перевіряти.

Так, потрібно було зробити автоматизацію цього процесу, дякую.
В автоматизації є одна проблема, люди які не програмують не зможуть перевірити код, і будуть сумніватися в достовірності цього експерименту. В моїй програмі можна наперед вивести результати, тому і сумнівів не має бути. Хоча я ці програми в першу чергу робив для себе, цікаво ж.