🎲🐍 Моделируем игру в кости на Python с помощью метода Монте-Карло
В этой статье учимся использовать метод Монте-Карло для прогнозирования вероятностей. Моделирование Монте-Карло – это тип вычислительного алгоритма, оценивающий вероятность возникновения неопределенного события из-за участия случайных величин. Алгоритм основан на повторной случайной выборке в попытке определить вероятность. Это означает моделирование событий со случайными входными данными большое число раз для получения оценки. Также определяются и другие факторы, которые будут видны на примере. Моделирование по методу Монте-Карло используется в экономике, азартных играх, машиностроении, энергетической отрасли. Поэтому знание этого метода будет полезно для многих областей. Модель Монте-Карло легко понять на примере игры в кости. В этой игре будут задействованы 2 шестигранных кубика. Для выигрыша игроку требуется выбросить одинаковое число на обоих кубиках. Шестигранный кубик имеет 6 возможных исходов (1, 2, 3, 4, 5 и 6). С двумя кубиками 36 возможных исходов (1 и 1, 1 и 2, 1 и 3 и т. д., или 6 х 6 = 36 вариантов). В этой игре у заведения больше шансов на победу (30 исходов против 6 у игроков), следовательно, у заведения значительное преимущество. Предположим, игрок начинает с баланса в 1000$ и готов проиграть все, поэтому ставит 1$ на каждый бросок (оба кубика) и решает сделать 1000 бросков. Предположим, что заведение щедрое и выплата будет в 4 раза больше ставки, когда игрок выигрывает. Например, если игрок выиграет первый бросок, баланс увеличится на 4$, и раунд закончится с 1004$. Если чудом получится выиграть серию из 1000 бросков, то итого получится 5000$. В случае каждого неудачного раунда получится 0$. Смоделируем игру, чтобы выяснить, сделал ли игрок правильный выбор. Начнем код с импорта необходимых библиотек Python: Далее определим функцию, которая будет выдавать случайное целое число от 1 до 6 для обеих костей (имитация броска). Функция будет сравнивать значение обеих костей и возвращать логическое значение – одинаковы броски или нет. Позже это значение будет использоваться для определения действий в коде. Каждое моделирование методом Монте-Карло требует знание входных данных и информации, которую требуется получить. Входные данные определены, когда описывалась игра. Количество бросков за игру 1000 раз, сумма за бросок 1$. В дополнение требуется определить – сколько раз игра будет моделироваться. В качестве счетчика Монте-Карло используем переменную Число переменных, которые возможно отслеживать, растет с ростом сложности проекта, поэтому требуется определить, какая информация нужна. В данном примере будет отслеживаться вероятность выигрыша (выигрыш за игру, деленный на общее число бросков) и конечный баланс для каждой симуляции (игры). Эти переменные будут инициализироваться, как списки и будут обновляться в конце каждой игры. Следующий шаг – это настройка фигуры перед запуском симуляции: это позволит добавлять линии к рисунку после каждой игры. После запуска всех симуляций отобразим график, чтобы показать результаты. В коде ниже 2 цикла: внешний, который перебирает заданное кол-во симуляций (10000) и вложенный, который запускает каждую игру (1000 бросков). Перед запуском каждого цикла Цикл Как только количество бросков достигло 1000, рассчитываем вероятность выигрыша игрока, как количество выигрышей, деленное на общее количество бросков. Сохраняем конечный баланс завершенной игры в отслеживаемой переменной Последний шаг – вывод осмысленных данных из отслеживаемых переменных. Отобразим фигуру (показанную ниже), созданную в цикле Моделирование игры в кости:
Сделаем вывод из результатов. Из рисунка выше возможно определить, что игрок редко получает прибыль после 1000 бросков. Средний конечный баланс 10000 симуляций составляет 833,66$ (из-за рандомизации, возможны различия результатов). Казино остается в выигрыше даже, если выплачивает в четыре раза больше при победе игрока. Также заметим, что вероятность выигрыша составляет 0.1667 или 1/6. Выше было отмечено, что у игрока 6 выигрышных исходов из 36 возможных. Используя эти 2 числа ожидаемо, что игрок выиграет 6 из 36 бросков, или 1/6 бросков, что соответствует прогнозу Монте-Карло. *** Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста» Интересно, перейти к каналуЧто такое моделирование методом Монте-Карло?
Игра в кости
Импорт библиотек Python
Pyplot
из Matplotlib
и random
. Для визуализации результатов будет использоваться библиотека Pyplot
, для моделирования броска шестигранной игральной кости – random
.
# Импорт библиотек import matplotlib.pyplot as plt import random
Функция броска кубиков
# Создаем функцию броска кубика def roll_dice(): die_1 = random.randint(1, 6) die_2 = random.randint(1, 6) # Определим является ли значение на костях одинаковым if die_1 == die_2: same_num = True else: same_num = False return same_num
Входные данные и отслеживаемые переменные
num_simulations
. Чем больше это число, тем точнее прогнозируемая вероятность соответствует истинному значению.
# Входные данные num_simulations = 10000 max_num_rolls = 1000 bet = 1 # Отслеживаемые переменные win_probability = [] end_balance = []
Настройка фигуры
# Создание фигуры, для симуляции баланса fig = plt.figure() plt.title("Monte Carlo Dice Game [" + str(num_simulations) + " simulations]") plt.xlabel("Roll Number") plt.ylabel("Balance [$]") plt.xlim([0, max_num_rolls])
Моделирование Монте-Карло
while
инициализируется:while
будет моделировать игру на 1000 бросков. Внутри этого цикла бросаются кости, используя логическую переменную, возвращаемую функцией roll_dice()
для определения результата. Если кости одинаковые – в список баланса добавляется 4-кратная ставка и выигрыш к счету игрока. Если кости разные – вычитается ставка из списка баланса. В конце каждого броска добавляем счетчик в список num_rolls
.end_balance
.
# Цикл for запускает желаемое количество симуляций for i in range(num_simulations): balance = [1000] num_rolls = [0] num_wins = 0 # Выполняется до тех пор пока игрок не выкинет 1000 раз while num_rolls[-1] < max_num_rolls: same = roll_dice() # Результат если кости одинаковые if same: balance.append(balance[-1] + 4 * bet) num_wins += 1 # Результат если кости разные else: balance.append(balance[-1] - bet) num_rolls.append(num_rolls[-1] + 1) # Сохраняем отслеживаемую переменную и добавляем строку к рисунку win_probability.append(num_wins/num_rolls[-1]) end_balance.append(balance[-1]) plt.plot(num_rolls, balance)
Получение результатов
for
. Также рассчитаем и отобразим общую вероятность выигрыша и конечный баланс, усредняя списки win_probability
и end_balance
.
# Выведем график после завершения моделирования plt.show() # Усредненная вероятность выигрыша и конечного баланса overall_win_probability = sum(win_probability)/len(win_probability) overall_end_balance = sum(end_balance)/len(end_balance) # Вывод средних значений print("Average win probability after " + str(num_simulations) + " runs: " + str(overall_win_probability)) print("Average ending balance after " + str(num_simulations) + " runs: $" + str(overall_end_balance))
Average win probability after 10000runs: 0.16666139999999954 Average ending balance after 10000runs: $833.307
Анализ результатов
Материалы по теме
- 0 views
- 0 Comment
Свежие комментарии