Главная страница
Навигация по странице:

  • 𝛼(𝑏) = 01 и 𝛼(𝑐) = 00. Будет ли этот код однозначным

  • , доставляющие этот минимум

  • 12.3.3. Останется ли утверждение предыдущей задачи в силе, если частоты расположены в невозрастающем порядке (возможны равные)

  • (частоты двух самых редких букв объединены)

  • А. шень Издание шестое, дополненное Москва


    Скачать 1.62 Mb.
    НазваниеА. шень Издание шестое, дополненное Москва
    Дата17.09.2022
    Размер1.62 Mb.
    Формат файлаpdf
    Имя файлаshen-progbook.pdf
    ТипКнига
    #681926
    страница15 из 19
    1   ...   11   12   13   14   15   16   17   18   19
    11.5.2. Могут ли при этом остаться неотмеченные позиции и чему они соответствуют?
    Ответ. Это позиции, в которых оба игрока могут гарантировать сколь угодно длинную игру без проигрыша. Впрочем, правило тро- екратного повторения позиции в шахматах в этом случае позволяет считать партию ничейной. (На самом деле учёт этого правила суще- ственно осложняет ситуацию, поскольку теперь в понятие позиции на- до включать информацию о том, какие конфигурации фигур на доске уже встречались.)
    
    А. Л. Брудно заметил, что есть ситуация, в которой такой «ретро- спективный» анализ требует совсем небольших ресурсов и может быть реализован на очень небольшой памяти, хотя для человека соответству- ющая задача не проста: пусть белые имеют короля на поле c3, которого им запрещено двигать, и ферзя (на каком-то другом поле) и хотят по- ставить мат одинокому чёрному королю. Ограничение (неподвижность короля), затрудняющее жизнь человеку-шахматисту, облегчает анализ
    (уменьшая количество позиций почти что в 64 раза за счёт того, что не надо рассматривать разные положения короля!)

    11.5. Ретроспективный анализ
    229
    Использование таблицы описанного типа можно считать примене- нием метода динамического программирования (мы не вычисляем цену игры для одной и той же позиции снова и снова, обходя дерево, а за- полняем таблицу цен систематически).

    12. ОПТИМАЛЬНОЕ
    КОДИРОВАНИЕ
    12.1. Коды
    Имея 2
    𝑛
    символов, мы можем кодировать каждый из них 𝑛 бита- ми, поскольку существует 2
    𝑛
    комбинаций из 𝑛 битов. Например, мож- но закодировать 4 = 2 2
    символа А, Г, Т, Ц (используемые при запи- си геномов) двухбитовыми комбинациями 00, 01, 10 и 11. Другой при- мер: последовательностями из 8 битов (байтами) можно закодировать
    256 символов (и этого хватает на латинские и русские буквы, знаки препинания и др.).
    Более формально: пусть нам дан алфавит, то есть конечное мно- жество, элементы которого называются символами или буквами этого алфавита. Кодом для алфавита 𝐴 называется функция (таблица) 𝛼, ко- торая для каждого символа 𝑎 из 𝐴 указывает двоичное слово 𝛼(𝑎), на- зываемое кодовым словом, или просто кодом этого символа. (Двоичное слово | конечная последовательность нулей и единиц.) Не требуется,
    чтобы коды всех символов имели равные длины.
    Мы допускаем, чтобы разные символы имели одинаковые коды. Со- гласно нашему определению, разрешается все буквы алфавита закоди- ровать словом 0 (и даже пустым словом) | но, конечно, такой код будет бесполезен. Хороший код должен позволять декодирование (восстано- вление последовательности символов по её коду).
    Формально это определяется так. Пусть фиксирован алфавит 𝐴 и код 𝛼 для этого алфавита. Для каждого слова 𝑃 в алфавите 𝐴 (то есть для любой конечной последовательности букв алфавита 𝐴) рассмотрим двоичное слово 𝛼(𝑃 ), которое получается, если записать подряд коды всех букв из 𝑃 (без каких-либо разделителей). Код 𝛼 называется одно- значным, если коды различных слов различны: 𝛼(𝑃 ) ̸= 𝛼(𝑃

    ) при 𝑃 ̸= 𝑃

    12.1.1. Рассмотрим трёхбуквенный алфавит {𝑎, 𝑏, 𝑐} и код 𝛼(𝑎) = 0,

    𝛼(𝑏) = 01 и 𝛼(𝑐) = 00. Будет ли этот код однозначным?

    12.2. Неравенство Крафта { Макмиллана
    231
    Решение. Нет, поскольку слова 𝑎𝑎 и 𝑐 кодируются одинаково.
    
    12.1.2. Для того же алфавита рассмотрим код 𝛼(𝑎) = 0, 𝛼(𝑏) = 10

    и 𝛼(𝑐) = 11. Будет ли этот код однозначным?
    Решение. Будет. Чтобы доказать это, достаточно объяснить, как можно восстановить слово 𝑃 по его коду 𝛼(𝑃 ). Если 𝛼(𝑃 ) начинается с нуля, то ясно, что слово 𝑃 начинается с 𝑎. Если 𝛼(𝑃 ) начинается с единицы, то слово 𝑃 начинается с 𝑏 или с 𝑐 | чтобы узнать, с чего именно, достаточно посмотреть на второй бит слова 𝛼(𝑃 ). Восстановив первую букву слова 𝑃 , мы забываем о ней и о её коде, и продолжаем всё сначала.
    
    Верно и более общее утверждение. Назовём код префиксным, если коды букв не являются началами друг друга (слово 𝛼(𝑝) не является началом слова 𝛼(𝑞), если буквы 𝑝 и 𝑞 различны).
    12.1.3. Докажите, что любой префиксный код является однознач- ным.
    Решение. Декодирование можно вести слева направо. Первая буква восстанавливается однозначно: если для двух букв 𝑝 и 𝑞 слова 𝛼(𝑝)
    и 𝛼(𝑞) являются началами кода, то одно из слов 𝛼(𝑝) и 𝛼(𝑞) является на- чалом другого, что невозможно для префиксного кода. И так далее. 
    12.1.4. Приведите пример однозначного кода, не являющегося пре- фиксным.
    [Указание. Пусть 𝛼(𝑎) = 0, 𝛼(𝑏) = 01, 𝛼(𝑐) = 11. Этот код является
    «суффиксным», но не префиксным.]
    
    12.1.5. Найдите таблицу для азбуки Морзе. Объясните, почему её
    можно использовать на практике, хотя она не является ни префиксным,
    ни даже однозначным кодом.
    
    12.2. Неравенство Крафта { Макмиллана
    Зачем вообще нужны коды с разной длиной кодовых слов? Дело в том, что на практике разные символы алфавита встречаются с разной частотой, и выгодно закодировать частые символы короткими слова- ми. (Это соображение, кстати, учитывалось при составлении азбуки
    Морзе.)
    Пусть для каждой буквы 𝑎 алфавита 𝐴 фиксирована её частота
    𝑝(𝑎) | положительное число, причём суммы частот всех букв равны

    232 12. Оптимальное кодирование единице. Тогда для любого кода 𝛼 можно определить среднюю длину этого кода как сумму
    𝐸 =
    ∑︁ 𝑝(𝑎)|𝛼(𝑎)|
    по всем буквам 𝑎 ∈ 𝐴, где |𝛼(𝑎)| | длина кодового слова 𝛼(𝑎) буквы 𝑎.
    (Смысл этого определения: если в слове длины 𝑁 буква 𝑎 встречается с частотой 𝑝(𝑎), то таких букв будет 𝑁𝑝(𝑎) и на их кодирование уйдёт
    𝑁𝑝(𝑎)|𝛼(𝑎)| битов; общая длина кода будет ∑︀ 𝑁𝑝(𝑎)|𝛼(𝑎)| и в среднем на кодирование каждой буквы уйдёт 𝐸 битов.)
    Теперь возникает задача: для данных частот построить однознач- ный код минимальной средней длины. Теоретически это можно сделать перебором (если в коде есть хотя бы одно очень длинное кодовое слово,
    то его средняя длина велика, поэтому такие коды можно не рассматри- вать; остаётся конечное число вариантов). Но можно обойтись и без перебора, и в этом разделе мы научимся это делать.
    Для начала поймём, что мешает нам выбирать кодовые слова корот- кими. Оказывается, что есть ровно одно препятствие: длины 𝑛
    1
    , . . . , 𝑛
    𝑘
    кодовых слов должны удовлетворять неравенству
    2

    𝑛
    1
    + 2

    𝑛
    2
    + . . . + 2

    𝑛
    𝑘
    6 1,
    называемому в теории кодирования неравенством Крафта { Макмил- лана.
    12.2.1. Проверьте, что оно выполнено для рассмотренных выше примеров однозначных кодов.
    
    12.2.2. Докажите, что для всякого префиксного кода выполняется неравенство Крафта { Макмиллана.
    Решение. Отрезок [0, 1] можно разбить на две половины. Назовём левую 𝐼
    0
    , а правую 𝐼
    1
    . Каждую из них разобьём пополам: отрезок 𝐼
    0
    разделится на левую половину 𝐼
    00
    и правую 𝐼
    01
    , аналогично 𝐼
    1
    делит- ся на 𝐼
    10
    и 𝐼
    11
    . И так далее: любому двоичному слову 𝑥 соответствует отрезок 𝐼
    𝑥
    . Длина этого отрезка есть 2
    −|
    𝑥|
    , где |𝑥| | длина слова 𝑥.
    Если слово 𝑥 является началом слова 𝑦, то отрезок 𝐼
    𝑥
    содержит отре- зок 𝐼
    𝑦
    ; если ни одно из слов 𝑥 и 𝑦 не является началом другого, то отрезки 𝐼
    𝑥
    и 𝐼
    𝑦
    не перекрываются (на том знаке, где 𝑥 и 𝑦 впервые расходятся, 𝐼
    𝑥
    и 𝐼
    𝑦
    попадают в разные половины).
    Рассмотрим теперь отрезки, соответствующие словам префиксно- го кода. Они не перекрываются. А значит, сумма их длин не больше единицы, что и даёт неравенство Крафта { Макмиллана.
    

    12.2. Неравенство Крафта { Макмиллана
    233 12.2.3. Пусть даны 𝑘 целых положительных чисел 𝑛
    1
    , . . . , 𝑛
    𝑘
    , удовле- творяющие неравенству Крафта { Макмиллана. Докажите, что можно построить префиксный код для 𝑘-буквенного алфавита с длинами ко- довых слов 𝑛
    1
    , . . . , 𝑛
    𝑘
    Решение. И здесь полезно использовать соответствие между слова- ми и отрезками и представлять себе дело так: у нас есть единичный отрезок [0, 1], и мы выделяем его части пользователям по требованию.
    Если пользователь приходит с числом 𝑛
    𝑖
    , то это значит, что ему надо выдать в пользование один из отрезков длиной 2

    𝑛
    𝑖
    , соответствую- щих кодовым словам длины 𝑛
    𝑖
    . (Тем самым годятся не любые отрезки такой длины, а лишь «правильно расположенные».) Код должен быть префиксным, это значит, что отрезки разных пользователей не долж- ны перекрываться. Нам дано, что суммарная длина всех требований не больше единицы. Как их удовлетворить? Можно отводить место сле- ва направо, при этом рассматривать требования в порядке убывания длин (тогда более короткие отрезки будут правильно расположены по- сле предыдущих более длинных).
    
    12.2.4. Покажите, что выделять кодовые слова (место на отрезке)
    можно и в порядке поступления требований (как иногда говорят, в «ре- жиме on-line»): пользователь приходит с числом 𝑛
    𝑖
    и уходит с правильно расположенным отрезком длины 2

    𝑛
    𝑖
    , причём если выполнено неравен- ство Крафта { Макмиллана, то никто не уйдёт обиженным (всем хватит места, и перераспределять его не придётся).
    [Указание. Нужно поддерживать свободное пространство как объ- единение правильно расположенных отрезков попарно различных длин,
    выделяя каждому пользователю кусок из кратчайшего подходящего от- резка и доразбивая остаток.]
    
    12.2.5. Покажите, что неравенство Крафта { Макмиллана выполня- ется не только для любого префиксного кода, но и вообще для любого однозначного кода. (Именно это доказал Макмиллан; Крафт доказал неравенство для префиксных кодов.)
    Решение. Есть разные способы решить эту задачу; мы приведём простое и красивое, хотя и несколько загадочное, решение. Пусть име- ется однозначный код с 𝑘 кодовыми словами 𝑃
    1
    , . . . , 𝑃
    𝑘
    . Нам надо дока- зать, что их длины 𝑛
    𝑖
    = |𝑃
    𝑖
    |
    удовлетворяют неравенству Крафта { Мак- миллана. Представим себе, что вместо нулей и единиц используются символы 𝑎 и 𝑏 (какая разница, из чего составлять коды?). Запишем

    234 12. Оптимальное кодирование формально сумму всех кодовых слов как алгебраическое выражение
    𝑃
    1
    + 𝑃
    2
    + . . . + 𝑃
    𝑘
    (многочлен от 𝑎 и 𝑏, в котором одночлены записаны как произведе- ния переменных 𝑎 и 𝑏, без возведения в степень). Теперь (ещё более странное на первый взгляд действие) возведём это выражение в сте- пень 𝑁 (произвольное натуральное число) и раскроем скобки, сохраняя порядок переменных (не собирая вместе одинаковые переменные) в од- ночленах:
    (𝑃
    1
    + 𝑃
    2
    + . . . + 𝑃
    𝑘
    )
    𝑁
    = сумма одночленов.
    Например, для кода со словами 0, 10, 11 (которые теперь записываются как 𝑎, 𝑏𝑎, 𝑏𝑏) и для 𝑁 = 2 получаем
    (𝑎 + 𝑏𝑎 + 𝑏𝑏)
    2
    = (𝑎 + 𝑏𝑎 + 𝑏𝑏)(𝑎 + 𝑏𝑎 + 𝑏𝑏) =
    = 𝑎𝑎 + 𝑎𝑏𝑎 + 𝑎𝑏𝑏 + 𝑏𝑎𝑎 + 𝑏𝑎𝑏𝑎 + 𝑏𝑎𝑏𝑏 + 𝑏𝑏𝑎 + 𝑏𝑏𝑏𝑎 + 𝑏𝑏𝑏𝑏.
    В этом примере все одночлены в правой части различны (если не пере- ставлять переменные), и это не случайно: так будет для любого одно- значного кода. В самом деле, по определению однозначности никакое слово не может быть получено двумя способами при соединении кодо- вых слов.
    Теперь подставим 𝑎 = 𝑏 = 1/2 в наше равенство (если оно верно для букв, то оно верно и для любых их числовых значений). Слева получится
    (2

    𝑛
    1
    + 2

    𝑛
    2
    + . . . + 2

    𝑛
    𝑘
    )
    𝑁
    (в скобке как раз выражение из неравенства Крафта { Макмиллана).
    Правую часть мы оценим сверху, сгруппировав слова по длинам: име- ется не более 2
    𝑙
    слагаемых длины 𝑙, каждое из которых равно 2

    𝑙
    ,
    и потому слагаемые данной длины в сумме не превосходят единицы,
    а правая часть не превосходит максимальной длины слагаемых, то есть
    𝑁 max 𝑛
    𝑖
    . Итак, получаем, что
    (2

    𝑛
    1
    + 2

    𝑛
    2
    + . . . + 2

    𝑛
    𝑘
    )
    𝑁
    < 𝑁 max 𝑛
    𝑖
    ,
    и это верно при любом 𝑁. Если основание степени в левой части больше единицы, то при больших 𝑁 это неравенство нарушится (показательная функция растёт быстрее линейной). Поэтому для однозначного кода выполняется неравенство Крафта { Макмиллана.
    

    12.3. Код Хаффмана
    235 12.3. Код Хаффмана
    Теперь задача о коде минимальной средней длины приобретает та- кую форму: для данных положительных 𝑝
    1
    , . . . , 𝑝
    𝑘
    , равных в сумме еди- нице, найти целые положительные 𝑛
    1
    , . . . , 𝑛
    𝑘
    , для которых выполнено неравенство Крафта { Макмиллана, а сумма
    𝑘
    ∑︁
    𝑖=1
    𝑝
    𝑖
    𝑛
    𝑖
    является минимально возможной (среди наборов 𝑛
    1
    , . . . , 𝑛
    𝑘
    , удовлетво- ряющих неравенству). Задача
    12.2.5
    показывает показывает, что сред- няя длина однозначного кода не меньше этого минимума, а задача
    12.2.3
    говорит, что этот минимум достигается, причём даже для префиксного кода. Как же найти числа 𝑛
    1
    , . . . , 𝑛
    𝑘

    , доставляющие этот минимум?
    12.3.1. Докажите, что для двух букв оптимальный код состоит из двух слов длины 1, независимо от частот букв.
    
    Чтобы решить задачу в общем случае, начнём с нескольких простых замечаний.
    12.3.2. Пусть частоты расположены в убывающем порядке: 𝑝
    1
    >
    > 𝑝
    2
    > . . . > 𝑝
    𝑘
    . Докажите, что тогда длины слов оптимального кода идут в неубывающем порядке: 𝑛
    1 6 𝑛
    2 6 . . . 6 𝑛
    𝑘
    Решение. Если бы более редкая буква имела бы более короткое кодо- вое слово, то, обменяв кодовые слова, мы сократили бы среднюю длину кода.
    

    12.3.3. Останется ли утверждение предыдущей задачи в силе, если частоты расположены в невозрастающем порядке (возможны равные)?
    Решение. Нет: если, скажем, имеются три буквы с частотой 1/3, то оптимальный код будет иметь длины слов 1, 2, 2 (если бы два кодовых слова имели длину 1, то на третье уже не осталось бы места), и они могут идти в любом порядке.
    
    Заметим, однако, что при поиске оптимального кода (для невоз- растающих частот) мы вправе ограничиваться лишь кодами, в кото- рых длины кодовых слов неубывают (поскольку кодовые слова для букв одинаковых частот можно переставлять без изменения средней длины кода).

    236 12. Оптимальное кодирование
    12.3.4. Пусть частоты расположены в невозрастающем порядке
    (𝑝
    1
    > 𝑝
    2
    > . . . > 𝑝
    𝑘
    ), а длины слов в оптимальном коде расположены в не- убывающем порядке 𝑛
    1 6 𝑛
    2 6 . . . 6 𝑛
    𝑘
    . Докажите, что 𝑛
    𝑘−1
    = 𝑛
    𝑘
    (при
    𝑘 > 2).
    Решение. Предположим, что это не так, и что есть единственное са- мое длинное кодовое слово длины 𝑛
    𝑘
    . Тогда неравенство Крафта { Мак- миллана не может обращаться в равенство, поскольку все слагаемые,
    кроме наименьшего (последнего), кратны удвоенному последнему сла- гаемому. Значит, в этом неравенстве есть запас, причём не меньший последнего слагаемого. А тогда можно уменьшить 𝑛
    𝑘
    на единицу, не нарушая неравенства, что противоречит предположению об оптималь- ности исходного кода.
    
    Эта задача показывает, что при поиске оптимального кода можно рассматривать лишь коды, в которых две самые редкие буквы имеют коды одинаковой длины.
    12.3.5. Как свести задачу отыскания длин кодовых слов оптималь- ного кода для 𝑘 частот
    𝑝
    1
    > 𝑝
    2
    > . . . > 𝑝
    𝑘−2
    > 𝑝
    𝑘−1
    > 𝑝
    𝑘
    к задаче поиска длин оптимального кода для 𝑘 − 1 частот
    𝑝
    1
    , 𝑝
    2
    , . . . , 𝑝
    𝑘−2
    , 𝑝
    𝑘−1
    + 𝑝
    𝑘

    (частоты двух самых редких букв объединены)?
    Решение. Мы уже знаем, что можно рассматривать лишь коды с
    𝑛
    𝑘−1
    = 𝑛
    𝑘
    . Неравенство Крафта { Макмиллана тогда запишется как
    2

    𝑛
    1
    + 2

    𝑛
    2
    + . . . + 2

    𝑛
    𝑘−2
    + 2

    𝑛
    𝑘−1
    + 2

    𝑛
    𝑘
    =
    = 2

    𝑛
    1
    + 2

    𝑛
    2
    + . . . + 2

    𝑛
    𝑘−2
    + 2

    𝑛
    6 1,
    если положить 𝑛
    𝑘−1
    = 𝑛
    𝑘
    = 𝑛 + 1. Таким образом, числа 𝑛
    1
    , . . . , 𝑛
    𝑘−2
    , 𝑛
    должны удовлетворять неравенству Крафта { Макмиллана для 𝑘 − 1
    букв. Средняя длины этих двух кодов будут связаны:
    𝑝
    1
    𝑛
    1
    + . . . + 𝑝
    𝑘−2
    𝑛
    𝑘−2
    + 𝑝
    𝑘−1
    𝑛
    𝑘−1
    + 𝑝
    𝑘
    𝑛
    𝑘
    =
    = 𝑝
    1
    𝑛
    1
    + . . . + 𝑝
    𝑘−2
    𝑛
    𝑘−2
    + (𝑝
    𝑘−1
    + 𝑝
    𝑘
    )𝑛 + [𝑝
    𝑘−1
    + 𝑝
    𝑘
    ].
    Последнее слагаемое (квадратная скобка) не зависит от выбираемого кода, поэтому минимизировать надо остальное, то есть как раз сред- нюю длину кода с длинами слов 𝑛
    1
    , . . . , 𝑛
    𝑘−2
    , 𝑛 для частот 𝑝
    1
    , 𝑝
    2
    , . . .
    . . . , 𝑝
    𝑘−2
    , 𝑝
    𝑘−1
    + 𝑝
    𝑘
    . После этого надо положить 𝑛
    𝑘−1
    = 𝑛
    𝑘
    = 𝑛 + 1, и это даст оптимальный код для исходной задачи.
    

    12.4. Код Шеннона { Фано
    237
    Используя эту задачу, несложно составить рекурсивную программу для отыскания длин кодовых слов. С каждым вызовом число букв бу- дет уменьшаться, пока мы не сведём задачу к случаю двух букв, когда оптимальный код состоит из слов 0 и 1. Затем можно найти и сами кодовые слова (согласно задаче
    12.2.3
    ). Но проще объединить эти дей- ствия и сразу искать кодовые слова: ведь замена числа 𝑛 на два числа
    𝑛 + 1 соответствует замене кодового слова 𝑃 на два слова 𝑃 0 и 𝑃 1 на единицу большей длины (и эта последняя замена сохраняет префикс- ность кода).
    Код, построенный таким методом, называется кодом Хаффмана.
    Мы доказали, что он имеет минимальную среднюю длину среди всех кодов (для данных частот букв). В следующей задаче оценивается чи- сло операций, необходимых для построения кода Хаффмана.
    12.3.6. Покажите, что можно обработать частоты 𝑝
    1
    , . . . , 𝑝
    𝑘
    , сде- лав 𝑂(𝑘 log 𝑘) операций, после чего 𝑖-е кодовое слово можно указать за время, пропорциональное его длине.
    [Указание. Заметим, что оценка времени довольно сильная: толь- ко на сортировку чисел 𝑝
    𝑖
    уже уходит 𝑂(𝑘 log 𝑘) действий. Поэтому,
    применяя предыдущую задачу, нужно использовать результаты сорти- ровки 𝑘 чисел при сортировке меньшего количества чисел. Это можно сделать с помощью очереди с приоритетами, вынимая два минималь- ных числа и добавляя их сумму за 𝑂(log 𝑘) действий. Это позволяет определить, какие две буквы надо соединять в одну на каждом шаге.
    Параллельно с соединением букв можно строить дерево кодов, проводя рёбра (помеченные 0 и 1) от соединённой буквы к каждой из её по- ловинок. При этом требуется 𝑂(1) действий на каждом шаге. После завершения построение прослеживать код любой буквы можно символ за символом.]
    
    12.4. Код Шеннона { Фано
    Мы видели, как можно построить оптимальный код (имеющий ми- нимальную среднюю длину) для данного набора частот. Однако эта конструкция не даёт никакой оценки для средней длины оптимального кода (как функции от частот 𝑝
    𝑖
    ). Следующие задачи указывает такую оценку (с абсолютной погрешностью не более 1).
    12.4.1. Покажите, что для любых положительных частот 𝑝
    1
    , . . . , 𝑝
    𝑘
    (в сумме равных единице) существует код средней длиной не более

    238 12. Оптимальное кодирование
    𝐻(𝑝
    1
    , . . . , 𝑝
    𝑘
    ) + 1, где функция 𝐻 (называемая энтропией Шеннона)
    определяется формулой
    𝐻(𝑝
    1
    , . . . , 𝑝
    𝑛
    ) = 𝑝
    1
    (− log
    2
    𝑝
    1
    ) + . . . + 𝑝
    𝑘
    (− log
    2
    𝑝
    𝑘
    )
    Решение. Если частоты 𝑝
    𝑖
    представляют собой целые (отрицатель- ные) степени двойки, то это утверждение почти очевидно. Положим
    𝑛
    𝑖
    = − log 𝑝
    𝑖
    (здесь и далее все логарифмы двоичные). Тогда 2

    𝑛
    𝑖
    = 𝑝
    𝑖
    и потому для чисел 𝑛
    𝑖
    выполнено неравенство Крафта { Макмиллана.
    По задаче
    12.2.3
    можно построить префиксный код с длинами кодовых слов 𝑛
    1
    , . . . , 𝑛
    𝑘
    , и средняя длина этого кода будет равна 𝐻(𝑝
    1
    , . . . , 𝑝
    𝑘
    )
    (и даже единицу добавлять не надо).
    Эта единица пригодится, если log 𝑝
    𝑖
    не целые. В этом случае надо взять наименьшее 𝑛
    𝑖
    , при котором 2

    𝑛
    𝑖
    6 𝑝
    𝑖
    . Для таких 𝑛
    𝑖
    выполняется неравенство Крафта { Макмиллана, и они больше − log 𝑝
    𝑖
    не более чем на единицу (потому и после усреднения ухудшение будет не более чем на единицу).
    
    Построенный на основе этой задачи код называется кодом Шенно- на { Фано. Это построение легко извлекается из решения задачи
    12.2.3
    :
    рассматривая числа 𝑛
    𝑖
    = −⌊log 𝑝
    𝑖

    (наименьшие целые числа, для ко- торых 2

    𝑛
    𝑖
    6 𝑝
    𝑖
    ) в порядке убывания, мы отводим для каждого из них кодовое слово и соответствующий участок отрезка [0, 1] слева на- право.
    При этом мы проигрываем в длине кода (по сравнению с оптималь- ным кодом) не более единицы: как мы сейчас увидим, средняя длина любого (в том числе и оптимального) кода не меньше 𝐻(𝑝
    1
    , . . . , 𝑝
    𝑘
    ).
    12.4.2. (Для знакомых с математическим анализом) Докажите, что
    (при данных положительных частотах, в сумме дающих единицу) сред- няя длина любого (однозначного) кода не меньше 𝐻(𝑝
    1
    , . . . , 𝑝
    𝑘
    ).
    Решение. Имея в виду неравенство Крафта { Макмиллана, мы дол- жны доказать такой факт: если
    2

    𝑛
    1
    + . . . 2

    𝑛
    𝑘
    6 1,
    то
    𝑝
    1
    𝑛
    1
    + . . . + 𝑝
    𝑘
    𝑛
    𝑘
    > 𝐻(𝑝
    1
    , . . . , 𝑝
    𝑘
    ).
    Это верно для любых 𝑛
    𝑖
    , не обязательно целых. Удобно перейти от 𝑛
    𝑖
    к величинам 𝑞
    𝑖
    = 2

    𝑛
    𝑖
    ; интересующее нас утверждение тогда гласит,
    что если 𝑝
    1
    , . . . , 𝑝
    𝑘
    и 𝑞
    1
    , . . . , 𝑞
    𝑘
    | два набора положительных чисел,

    12.4. Код Шеннона { Фано
    239
    и сумма чисел в каждом равна единице, то
    𝑝
    1
    (− log 𝑞
    1
    ) + . . . + 𝑝
    𝑘
    (− log 𝑞
    𝑘
    ) > 𝑝
    1
    (− log 𝑝
    1
    ) + . . . + 𝑝
    𝑘
    (− log 𝑝
    𝑘
    ).
    Другими словами, выражение
    𝑝
    1
    (− log 𝑞
    1
    ) + . . . + 𝑝
    𝑘
    (− log 𝑞
    𝑘
    )
    (рассматриваемое при фиксированных 𝑝
    𝑖
    как функция на множестве всех положительных 𝑞
    1
    , . . . , 𝑞
    𝑘
    , в сумме равных единице) достигает ми- нимума при 𝑞
    𝑖
    = 𝑝
    𝑖
    . Область определения этой функции есть внутрен- ность симплекса (треугольника при 𝑛 = 3, тетраэдра при 𝑛 = 4 и т. д.)
    и при приближении к границе одно из 𝑞
    𝑖
    становится малым, а его минус логарифм уходит в бесконечность. Значит, минимум функции достига- ется внутри области. В точке минимума градиент (−𝑝
    1
    /𝑞
    1
    , . . . , −𝑝
    𝑛
    /𝑞
    𝑛
    )
    должен быть перпендикулярен плоскости, на которой функция опре- делена (иначе сдвиг вдоль этой плоскости уменьшал бы функцию), то есть все 𝑝
    𝑖
    /𝑞
    𝑖
    равны. Поскольку ∑︀ 𝑝
    𝑖
    = ∑︀ 𝑞
    𝑖
    = 1, то это означает, что
    𝑝
    𝑖
    = 𝑞
    𝑖
    Другое объяснение: функция log выпукла вверх, поэтому для любых неотрицательных коэффициентов 𝛼
    𝑖
    , в сумме равных единице, и для любых точек 𝑥
    𝑖
    из области определения логарифма выполняется нера- венство log
    (︁∑︁ 𝛼
    𝑖
    𝑥
    𝑖
    )︁
    >
    ∑︁ 𝛼
    𝑖
    log 𝑥
    𝑖
    Остаётся положить 𝛼
    𝑖
    = 𝑝
    𝑖
    , 𝑥
    𝑖
    = 𝑞
    𝑖
    /𝑝
    𝑖
    ; в левой части будет логарифм единицы, то есть нуль, а ∑︀ 𝑝
    𝑖
    log(𝑞
    𝑖
    /𝑝
    𝑖
    ) есть как раз разность между левой и правой частями доказываемого неравенства.
    
    Велика ли экономия от использования кодов, описанных в этом раз- деле? Это, конечно, зависит от частот букв: если они все одинако- вые, то никакой экономии не будет. Легко заметить, что в русском языке разные буквы имеют разную частоту. Если, скажем, в текстах
    (TEX-файлах) этой книжки (на момент эксперимента) оставить толь- ко 33 строчные русские буквы от «а» до «я», а все остальные символы не учитывать, то самой частой буквой будет буква «о» (частота 0,105),
    а самой редкой | твёрдый знак (частота 0,00019). Значение энтропии
    Шеннона при этом будет равно 4,454 (сравните с 5 битами, необхо- димыми для кодирования 32 букв). Выигрыш не так велик. Он будет больше, если учитывать также и другие символы (прописные буквы,
    знаки препинания и др.), которые встречаются в тексте гораздо реже.
    Наконец, можно кодировать не буквы, а двухбуквенные комбинации или

    240 12. Оптимальное кодирование ещё что-нибудь. Именно так поступают популярные программы сжатия информации (типа zip), которые позволяют сократить многие тексты в полтора-два раза (а некоторые другие файлы данных | и в большее число раз).
    12.4.3. Компания M. утверждает, что её новая программа супер- сжатия файлов позволяет сжать любой файл длиной больше 100 000 бай- тов по крайней мере на 10% без потери информации (можно восстано- вить исходный файл по его сжатому варианту). Докажите, что она врёт.
    

    13. ПРЕДСТАВЛЕНИЕ
    МНОЖЕСТВ.
    ХЕШИРОВАНИЕ
    13.1. Хеширование с открытой адресацией
    В главе
    6
    было указано несколько представлений для множеств, эле- ментами которых являются целые числа произвольной величины. Одна- ко в любом из них хотя бы одна из операций проверки принадлежности,
    добавления и удаления элемента требовала количества действий, про- порционального числу элементов множества. На практике это бывает слишком много. Существуют способы, позволяющие получить для всех трёх упомянутых операций оценку 𝐶 log 𝑛. Один из таких способов мы рассмотрим в следующей главе. В этой главе мы разберём способ, кото- рые хотя и приводит к 𝐶𝑛 действиям в худшем случае, но зато «в сред- нем» требует значительно меньшего их числа. (Мы не будем уточнять слов «в среднем», хотя это и можно сделать.) Этот способ называется хешированием.
    Пусть нам необходимо представлять множества элементов типа T,
    причём число элементов в них заведомо меньше n. Выберем некото- рую функцию h, определённую на значениях типа T и принимающую значения 0 . . . n-1. Было бы хорошо, чтобы эта функция принимала на элементах будущего множества по возможности более разнообразные значения. (Худший случай | это когда её значения на всех элемен- тах хранимого множества одинаковы.) Эту функцию будем называть хеш-функцией, или, как ещё говорят, функцией расстановки.
    Введём два массива val: array [0..n-1] of T;
    used: array [0..n-1] of boolean;
    (мы позволяем себе писать n-1 в качестве границы в определении типа,

    242 13. Представление множеств. Хеширование хотя в паскале это не разрешается). В этих массивах будут храниться элементы множества: оно равно множеству всех val [i] для тех i, для которых used [i], причём все эти val [i] различны. По возможности мы будем хранить элемент t на месте h(t), считая это место «искон- ным» для элемента t. Однако может случиться так, что новый элемент,
    который мы хотим добавить, претендует на уже занятое место (для которого used истинно). В этом случае мы отыщем ближайшее справа свободное место и запишем элемент туда. («Справа» значит «в сторо- ну увеличения индексов»; дойдя до края, мы перескакиваем в начало.)
    По предположению, число элементов всегда меньше n, так что пустые места заведомо будут.
    Формально говоря, в любой момент должно соблюдаться такое тре- бование: для любого элемента множества участок справа от его искон- ного места до его фактического места полностью заполнен.
    Благодаря этому проверка принадлежности заданного элемента t осуществляется легко: встав на h(t), двигаемся направо, пока не дой- дём до пустого места или до элемента t. В первом случае элемент t отсутствует в множестве, во втором | присутствует. Если элемент отсутствует, то его можно добавить на найденное пустое место. Если присутствует, то можно его удалить (положив used = false).
    13.1.1. В предыдущем абзаце есть ошибка. Найдите её и исправьте.
    Решение. Дело в том, что при удалении требуемое свойство «отсут- ствия пустот» может нарушиться. Поэтому будем делать так. Создав дыру, будем двигаться направо, пока не натолкнёмся на элемент, сто- ящий не на исконном месте, или на ещё одно пустое место. Во втором случае на этом можно успокоиться. В первом случае посмотрим, не нужно ли найденный элемент поставить на место дыры. Если нет, то продолжаем поиск, если да, то затыкаем им старую дыру. При этом образуется новая дыра, с которой делаем всё то же самое.
    
    13.1.2. Напишите программы проверки принадлежности, добавле- ния и удаления.
    Решение.
    function принадлежит (t: T): boolean;
    var i: integer;
    begin i := h (t);
    while used [i] and (val [i] <> t) do begin i := (i + 1) mod n;
    end; {not used [i] or (val [i] = t)}

    13.1. Хеширование с открытой адресацией
    243
    принадлежит := used [i] and (val [i] = t);
    end;
    procedure добавить (t: T);
    var i: integer;
    begin i := h (t);
    while used [i] and (val [i] <> t) do begin i := (i + 1) mod n;
    end; {not used [i] or (val [i] = t)}
    if not used [i] then begin used [i] := true;
    val [i] := t;
    end;
    end;
    procedure исключить (t: T);
    var i, gap: integer;
    begin i := h (t);
    while used [i] and (val [i] <> t) do begin i := (i + 1) mod n;
    end; {not used [i] or (val [i] = t)}
    if used [i] and (val [i] = t) then begin used [i] := false;
    gap := i;
    i := (i + 1) mod n;
    {gap - дыра, которая может закрыться одним из i,i+1,...}
    while used [i] do begin if i = h (val[i]) then begin
    {на своём месте, ничего не делать}
    end else if dist(h(val[i]),i) < dist(gap,i) then begin
    {gap...h(val[i])...i, ничего не делать}
    end else begin used [gap] := true;
    val [gap] := val [i];
    used [i] := false;
    gap := i;
    end;
    i := (i + 1) mod n;
    end;
    end;
    end;
    Здесь dist (a,b) | измеренное по часовой стрелке (слева направо)

    244 13. Представление множеств. Хеширование расстояние от a до b, то есть dist (a,b) = (b - a + n) mod n.
    (Мы прибавили n, так как функция mod правильно работает при поло- жительном делимом.)
    
    13.1.3. Существует много вариантов хеширования. Один из них та- ков: обнаружив, что исконное место (обозначим его 𝑖) занято, будем ис- кать свободное не среди 𝑖 + 1, 𝑖 + 2, . . ., а среди 𝑟(𝑖), 𝑟(𝑟(𝑖)), 𝑟(𝑟(𝑟(𝑖))), . . .,

    1   ...   11   12   13   14   15   16   17   18   19


    написать администратору сайта