Использование структуры дерево для задач кодирования
Ознакомься с решением задачи расшифровки сообщения с помощью дерева.
Алина недавно прочитала книгу известного британского научно-популярного писателя об истории создания различных способов шифрования, о борьбе шифровальщиков и дешифровальщиков, об исторических интригах и военных тайнах. Составленный ею шифр содержит в себе не только отзыв о прочитанной книге, но и некоторый секрет, которым она готова поделиться с теми, кого заинтересовало шифрование и кодирование.
Вот таблица кодовых слов ее шифра и само зашифрованное сообщение:
Посмотрите на код, он состоит из двух одинаковых половинок. Это удивительно, может он состоит из повторяющихся фрагментов, например «но-но» или «фифти-фифти»?
Разделим задачу на две, если нам надо получить целое слово, почему бы не попробовать разобраться с одной из похожих половинок?
Надо попробовать все варианты.
Что же это? Неужели Алина написала фразу «мими»? Что бы это могло означать? Посмотрим словари. Нет, потом, ведь у нас остался еще один вариант.
Конечно, Алина, не стоило так оценивать книгу, но что не сделаешь ради красивой задачи! В чем же состоял этот «некоторый секрет»? В том, что мы столкнулись с неоднозначным декодированием. Построим дерево символов.
Имея 3 символа, можно закодировать только три буквы, а нам надо 6, поэтому будем удлинять код, наращивая в нем количество символов. Из трех символов можно составить 9 кодовых слов длиной в два символа. Но код «!» и «!!» нельзя использовать одновременно. Потому что нельзя будет этот код декодировать однозначно. А в коде Алины есть коды разной длины, начинающиеся на одни и те же символы. Это и ввело нас в заблуждение.
В теории кодирования сформулирован алгоритм составления кодов разной длины, неравномерного кодирования — правило Фано.
Алгоритм использует для составления кодов структуру «дерево». При этом важное условие для однозначного декодирования то, что никакой код не является префиксом, т.е. началом другого кода.
Для задач кодирования используют структуру «дерево», чтобы избежать неоднозначного декодирования.
Дерево — это граф, в котором нет циклов, т. е. в нём нельзя из некоторой вершины пройти по нескольким различным рёбрам и вернуться в ту же вершину. Отличительной особенностью дерева является то, что между любыми двумя его вершинами существует единственный путь.
Всякая иерархическая система может быть представлена с помощью дерева. У дерева выделяется одна главная вершина, называемая его корнем. Каждая вершина дерева (кроме корня) имеет только одного предка, обозначенный предком объект входит в один класс высшего уровня. Любая вершина дерева может порождать несколько потомков — вершин, соответствующих классам нижнего уровня. Такой принцип связи называется «один-ко-многим». Вершины, не имеющие порождённых вершин, называются листьями.
Родственные связи между членами семьи удобно изображать с помощью графа, называемого генеалогическим или родословным деревом.
Ресурс «Живая Родословная» (145555) — инструмент для формирования и анализа генеалогических деревьев, содержащий примеры родословных. С его помощью вы можете изучить генеалогические деревья многих известных семей и построить генеалогическое дерево своей семьи (http://sc.edu.ru/).
1.3.3. Использование графов при решении задач
Графы удобно использовать при решении некоторых классов задач.
Пример 1. Для того чтобы записать все трёхзначные числа, состоящие из цифр 1 и 2, можно воспользоваться графом (деревом) на рис. 1.7.
Рис. 1.7. Дерево для решения задачи о записи трёхзначных чисел
Дерево можно не строить, если не требуется выписывать все возможные варианты, а нужно просто указать их количество. В этом случае рассуждать нужно так: в разряде сотен может быть любая из цифр 1 и 2, в разряде десятков — те же два варианта, в разряде единиц — те же два варианта. Следовательно, число различных вариантов: 2*2*2 = 8.
В общем случае, если известно количество возможных вариантов выбора на каждом шаге построения графа, то для вычисления общего количества вариантов нужно все эти числа перемножить.
Пример 2. Рассмотрим несколько видоизменённую классическую задачу о переправе.
На берегу реки стоит крестьянин (К) с лодкой, а рядом с ним — собака (С), лиса (Л) и гусь (Г). Крестьянин должен переправиться сам и перевезти собаку, лису и гуся на другой берег. Однако в лодку кроме крестьянина помещается либо только собака, либо только лиса, либо только гусь. Оставлять же собаку с лисой или лису с гусем без присмотра крестьянина нельзя — собака представляет опасность для лисы, а лиса — для гуся. Как крестьянин должен организовать переправу?
Для решения этой задачи составим граф, вершинами которого будут исходное размещение персонажей на берегу реки, а также всевозможные промежуточные состояния, достигаемые из предыдущих за один шаг переправы. Каждую вершину-состояние переправы обозначим овалом и свяжем рёбрами с состояниями, образованными из неё (рис. 1.8),
Недопустимые по условию задачи состояния выделены пунктирной линией; они исключаются из дальнейшего рассмотрения. Начальное и конечное состояния переправы выделены жирной линией.
На графе видно, что существуют два решения этой задачи. Приведём соответствующий одному из них план переправы:
1) крестьянин перевозит лису;
2) крестьянин возвращается;
3) крестьянин перевозит собаку;
4) крестьянин возвращается с лисой;
5) крестьянин перевозит гуся;
6) крестьянин возвращается;
7) крестьянин перевозит лису.
Пример 3.
Рассмотрим следующую игру:
сначала в кучке лежат 5 спичек;
два игрока убирают спички по очереди, причём за 1 ход можно убрать 1 или 2 спички;
выигрывает тот, кто оставит в кучке 1 спичку.
Выясним, кто выигрывает при правильной игре — первый (I) или второй (II) игрок.
Решение:
Используем метод построения дерева.
Первый играющий может убрать одну спичку (в этом случае их останется 4) или сразу 2 (останется 3), эти два варианта отобразим при помощи дерева:
если первый игрок оставил 4 спички, второй может своим ходом оставить 3 или 2; а если после первого хода осталось 3 спички, второй игрок может выиграть, взяв две спички и оставив одну:
если осталось 3 или 2 спички, то 1-ый игрок (в обеих ситуациях) выиграет своим ходом:
Проанализируем стратегию игры:
если первый игрок своим первым ходом взял две спички, то второй сразу выигрывает; если же он взял одну спичку, то своим вторым ходом он может выиграть, независимо от хода второго игрока;
итак, убрав всего одну спичку первым ходом, 1-ый игрок всегда может выиграть на следующем ходу;
тогда как второй игрок не может выиграть, независимо от действий первого: потому что, если первый игрок сначала убрал одну спичку, второй всегда проиграет.
Ответ: при правильной игре (стратегии игры) выиграет первый игрок; для этого ему достаточно своим первым ходом убрать одну спичку.
На рис. 1.9 представлен граф, называемый деревом игры; на нём отражены все возможные варианты, в том числе ошибочные (проигрышные) ходы игроков.
8. Что такое дерево? Моделями каких систем могут служить деревья? Приведите пример такой системы.
9. Сколько трёхзначных чисел можно записать с помощью цифр 2, 4, 6 и 8 при условии, что в записи числа не должно быть одинаковых цифр?
10. Сколько существует трёхзначных чисел, все цифры которых различны?
11. Для составления цепочек используются бусины, помеченные буквами А, В, С, D, Е. На первом месте в цепочке стоит одна из бусин А, С, Е. На втором — любая гласная, если первая буква гласная, и любая согласная, если первая согласная. На третьем месте — одна из бусин С, D, Е, не стоящая в цепочке на первом месте. Сколько цепочек можно создать по этому правилу?
12. Два игрока играют в следующую игру. Перед ними лежит куча из 6 камней. Игроки берут камни по очереди. За один ход можно взять 1, 2 или 3 камня. Проигрывает тот, кто забирает последний камень. Кто выигрывает при безошибочной игре обоих игроков — игрок, делающий первый ход, или игрок, делающий второй ход? Каким должен быть первый ход выигрывающего игрока? Ответ обоснуйте.
Домашнее задание. §1.3, вопросы и задания № 1–4, 7, 11 к параграфу; № 35, 37, 39, 41 в РТ. Дополнительное задание: № 44 или № 45 в РТ.