homepage/source/_articles/2019-05-01-predictor.md

138 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Гадалка Шеннона
description: Демо-версия электронной гадалки Шеннона
keywords: [гадалка, угадыватель, шеннон, чет-нечет]
styles:
- /static/predictor.css
scripts:
- /static/predictor.js
---
В студенческое время я наткнулся на интересную статью об [игре "Чет-нечет"][game]
на домашней страничке пользователя [ltwood][ltwood].
Правила очень простые. Игрок загадывает один вариант из двух: "чет" или "нечет",
а оппонент пытается угадать выбор игрока. Если угадать не удалось, то очко получает
загадавший, а если угадать получилось - то угадывающий. Кто первым наберет 20 очков,
тот и молодец!
Кажется, что в этой игре все случайно. Случайно загадывается число, потом случайно
второй игрок пытается угадать что же было загадано. Я очень сильно удивился, когда
попробовал поиграть в эту игру с программой и за десять попыток так ни разу и не выиграл.
Парадокс в том, что мы умаем_ что загадываем числа случайно. На самом деле все не так,
и последовательность загаданных чисел не случайна.
Исходного кода оригинальной гадалки в открытом доступе нет, есть только [описание алгоритма][algo],
по которому я сделал свою реализацию на TypeScrypt.
## Демоверсия
Попробуйте набрать 50 очков и выиграть. Чтобы выбирать вариант с клавиатуры,
кликните внутри серой рамки, а потом пользуйтесь клавишами "1" - нечет или "2" - чет.
---
<div id="app"></div>
---
## Как Это работает
Математически алгоритм на [странице][algo] сайта ltwood.
Я рассмотрю простой пример, чтобы показать принцип.
В основе алгоритма находится популяция "демонов" - автоматов, которые на основании ходов
игрока и предсказанных значениях выдают новое предсказание. Демонами управляет
супервайзер. Задача супервайзера в том, чтобы опросить всех демонов, выбрать ответ
от одного их них, а после получения ответа игрока пометить тех, кто выдал правильный ответ.
Алгоритм состоит из двух шагов:
- предсказать следующих ход игрока;
- учесть реальный ход игрока, добавив веса тому демону, который предугадал ход.
Рассмотрим работу на примере одного демона.
Пусть у нас есть демон, который смотрит на последний хода игрока
и на свое последнее предсказание.
Строим два вектора:
- `[<1 ход демона>, <1 ход игрока>, 0]`
- `[<1 ход демона>, <1 ход игрока>, 1]`
В самом начале, когда у демона нет никакой информации о ходах игрока, эти векторы
будут выглядеть как `[0]` и `[1]`. Но с накоплением данных, они всегда будут каждый
по 5 элементов.
После чего смотрим, который из таких наборов в прошлом приносил победу чаще,
и соответственно выбираем или вариант с 0, или с 1.
После получения действительного хода игрока, мы увеличиваем вес того набора,
который оказался верным. И далее снова предсказываем ход.
Теперь с числами.
#### Ход 1
У демона нет информации, наборы `[0]` и `[1]` равнозначны, выбираем `[0]`,
а значит предсказываем ход игрока 0.
Игрок загадывал 1. Обновляем веса:
```
[0] = 0
[1] = 1
```
#### Ход 2
Строим векторы на основе последних ходов:
```
0: [0, 1, 0]
1: [0, 1, 1]
```
Для этих векторов тоже еще нет весов, так что снова выбираем первый, предсказываем 0.
Игрок снова выбрал 1. Обновляем веса (помним, что еще были прошлые вектора из одного элемента):
```
[0] = 0
[1] = 1
[0, 1, 0] = 0
[0, 1, 1] = 1
```
#### Ход 3
Картина такая же, как на втором ходу, но отличие в том, что у нас есть веса с прошлого хода:
```
0: [0, 1, 0] - 0
1: [0, 1, 1] - 1
```
Выбираем вариант 1, игрок снова выбирает 1. Предсказание удалось!
## Расширение алгоритма
Это был самый элементарный вариант. Понятно, что на таком далеко не уедешь,
и никого не обыграешь. Чтобы хорошо предугадывать ходы игроков, используется
несколько демонов с разной величиной просматриваемой истории. Следит за ними
"супервайзер", который ведет для каждого демона рейтинг. На основе этого рейтинга
выбираются ответы тех демонов, которые были наиболее успешны в своих предсказаниях.
## Ссылки
- [Код гадалки][repo]
- [Описание алгоритма][algo]
- [Описание игры у ltwood][game]
[ltwood]: https://sites.google.com/site/ltwood/
[game]: https://sites.google.com/site/ltwood/projects/heshby
[algo]: https://sites.google.com/site/ltwood/projects/heshby/algorithm
[repo]: https://github.com/anwinged/predictor