Опубликован: 09.12.2017 | Доступ: свободный | Студентов: 737 / 31 | Длительность: 02:06:00
Специальности: Программист
Лекция 5:

Игра "Быки и коровы"

< Лекция 1 || Лекция 5: 123456
Аннотация: Игра "Быки и коровы" На этом уроке продолжается рассмотрение предыдущей игры "Задумай число". Обсуждается алгоритм бинарного поиска, дающий оптимальную стратегию поиска задуманного числа. Приводится реализация этой стратегии. В интерфейсе игры появляется новая кнопка "Компьютер, отгадай число". Рассматривается проект, реализующий новую игру "Быки и коровы", где также требуется отгадать число, задуманное компьютером. Найти задуманное число в этой игре сложнее, поскольку разрешается задавать вопрос только одного типа "Число равно N?" По техническим причинам не состоялась запись следующей лекции, где рассматривалась вариация проекта "Быки и коровы", в которой задуманная комбинация случайным образом выбиралась из множества, включающего 12 картинок. В тексте, сопровождающем данный урок, дается краткое описание этого проекта.

Урок начинается с разбора домашнего задания, выполненного школьником. В домашней работе требовалось добавить новые кнопки в интерфейс игры и написать в коде соответствующие обработчики события. Школьник добавил две кнопки "Больше или равно" и "Меньше или равно". Корректно написал соответствующие обработчики события. Хотя ответ на поставленный вопрос формировался не вполне точно, предложенное решение заслуживает хорошей оценки. Неточности ответа легко устранимы.

Когда школьники, играя в игру, отгадывали число, задуманное компьютером, то, как правило, получали звание "магистр игры". Это позволило на интуитивном уровне понять суть одного из классических алгоритмов поиска данных в упорядоченном множестве – алгоритма дихотомии или бинарного поиска, ради изучения которого и была написана данная игра.

В чем состоит суть игры "Задумай число"? Компьютер задумывает число из некоторого интервала [min, max]. Границы интервала сообщаются игроку. У игрока есть возможность выбрать некоторое число N из данного интервала и задать компьютеру вопрос одного из трех типов: "число N больше задуманного", "число N меньше задуманного", "число N равно задуманному". На каждый вопрос компьютер отвечает "да", если утверждение справедливо, и "нет" в противном случае. Чтобы стать магистром игры нужно задать не более K вопросов, где K зависит от интервала [min, max].

Оптимальная стратегия игры определяется алгоритмом бинарного поиска, который также называют алгоритмом дихотомии или методом деления пополам. Рассмотрим его подробнее.

Алгоритм бинарного поиска

Суть данного алгоритма рассмотрим на примере поиска задуманного числа в заданном интервале [min, max]. Какова исходная неопределенность? В заданном интервале находится maxmin + 1 число. Так в интервале [0,100] находится сто одно число и задуманное число может быть любым из них. Так что неопределенность равна числу чисел в данном интервале. Как задать вопрос так, чтобы максимально возможно уменьшить неопределенность. Серединой интервала является число mid, равное (maxmin) / 2, в нашем примере – это число 50. Задав вопрос "задуманное число больше (меньше) mid", при любом ответе неопределенность сокращается вдвое. Получив ответ "да" на вопрос "задуманное больше mid?" значение нижней границы интервала min меняется на число mid + 1. В противном случае меняется верхняя граница max на значение mid. С каждым вопросом интервал сокращается вдвое. Когда интервал сокращается до одного числа, то вопрос на равенство гарантировано дает задуманное число. Общее число вопросов, которое следует задать, равно округлённому в большую сторону значению функции Log(N) – двоичному алгоритму числа N, где N – исходная неопределенность, число чисел в интервале.

Рассмотрим пример. Задумано число 83 в интервале [0, 100]. Оптимальное число вопросов, позволяющее отгадать задуманное число равно Log 101, округленному до ближайшего целого, что дает число 7. Вот последовательность из 7-и вопросов, позволяющая отгадать задуманное:

  1. Число больше 50? – Да.
  2. Число больше 75? – Да.
  3. Число больше 88? – Нет.
  4. Число больше 81? – Да.
  5. Число больше 84? – Нет.
  6. Число больше 82? – Да.
  7. Число равно 83? – Да.

Алгоритм бинарного поиска широко применяется в самых разных прикладных задачах, - всюду, где требуется найти элемент в отсортированном множестве, над элементами которого определена операция сравнения на "больше", "меньше".

Как играет компьютер?

Компьютер, конечно же, "знает" оптимальную стратегию и потому всегда достигает звания "Магистр игры" любого уровня. В приводимом варианте стратегии используется вопрос типа "Число больше". С каждым вопросом интервал неопределенности сокращается вдвое, пока не будет содержать ровно один элемент, который и является задуманным числом. Стратегия компьютера определяется разобранным выше методом бинарного поиска. Так что обработчик события Click командной кнопки "Компьютер, отгадай число" представляет собой реализацию алгоритма бинарного поиска, дополненную выводом соответствующих сообщений. Вот как выглядит код обработчика события Click:

        /// <summary>
        /// Стратегия компьютера
        /// Реализация алгоритма бинарного поиска
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonCompGuess_Click(object sender, EventArgs e)
        {
            int min_c = min;
            int max_c = max;
            int mid = (min + max) / 2;
            countQuestion = 0;
            listBoxQA.Items.Add(COMP);
            //Бинарный поиск
            while (min_c != max_c)
            {
                countQuestion++;
                question = countQuestion.ToString() + ". ";
                question += "Число больше ";
                question += mid + "?";
                
                if (number > mid)
                {
                    question += " - Да!";
                    min_c = mid + 1;
                }
                else
                {
                    question += " - Нет!";
                    max_c = mid;
                }
                mid = (min_c + max_c) / 2;
                listBoxQA.Items.Add(question);
            }
            //границы интервала неопределенности совпадают. 
            //Ответ найден
            countQuestion++;
            question = countQuestion.ToString() + ". ";
            question += "Число равно ";
            question +=  min_c + "?";
            question += " - Да!";
            textBoxResult.Text = COMP_ANSWER + number;
            listBoxQA.Items.Add(question);
        }
< Лекция 1 || Лекция 5: 123456