<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=84.54.248.47&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=84.54.248.47&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/84.54.248.47"/>
		<updated>2026-06-13T03:26:05Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=43662</id>
		<title>Оптимальный префиксный код с длиной кодового слова не более L бит</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D0%BF%D1%80%D0%B5%D1%84%D0%B8%D0%BA%D1%81%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4_%D1%81_%D0%B4%D0%BB%D0%B8%D0%BD%D0%BE%D0%B9_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2%D0%BE%D0%B3%D0%BE_%D1%81%D0%BB%D0%BE%D0%B2%D0%B0_%D0%BD%D0%B5_%D0%B1%D0%BE%D0%BB%D0%B5%D0%B5_L_%D0%B1%D0%B8%D1%82&amp;diff=43662"/>
				<updated>2015-01-08T18:21:21Z</updated>
		
		<summary type="html">&lt;p&gt;84.54.248.47: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Оптимальный префиксный код с длиной кодового слова не более L бит'''  — это [[Задача_об_оптимальном_префиксном_коде_с_сохранением_порядка._Монотонность_точки_разреза | префиксный код]] код, в котором длина каждого кодового слова не должна превышать заданной константы. Здесь будет приведен алгоритм, решающий эту задачу за время &amp;lt;tex&amp;gt; O(nL) &amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — максимальная длина кодового слова, &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита, c помощью сведения задачи к [[Задача_о_рюкзаке | задаче о рюкзаке]].&lt;br /&gt;
&lt;br /&gt;
==Пример.==&lt;br /&gt;
Данный алгоритм бывает полезен, когда нам нужно ограничить максимальную длину кодового слова, а при использовании алгоритма Хаффмана самому редко встречающемуся символу соответствует слишком длинное кодовое слово. Например, пусть дан алфавит из 5 символов &amp;lt;tex&amp;gt;A=\{A,B,C, C, D\}&amp;lt;/tex&amp;gt;, а частоты символов являются степенями двойки: &amp;lt;tex&amp;gt;P=\{1,2,4, 8, 16\}&amp;lt;/tex&amp;gt;. Тогда классический код Хоффмана будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Код&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || 1111&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || 1110&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 4 || 110&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| D || 8 || 10&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| E || 16 || 0&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
Самое длинное кодовое слово здесь имеет длину &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt;. Пусть мы хотим, чтобы слова в нашем коде были не длиннее трех бит. Тогда алгоритм, который будет описан ниже, генерирует такой код:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Код&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| A || 1 || 000&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| B || 2 || 001&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| C || 4 || 010&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| D || 8 || 011&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| E || 16 || 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Важно заметить следующий факт. В худшем случае все кодовые слова будут иметь длину &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; бит. Тогда мы можем закодировать &amp;lt;tex&amp;gt; 2^L &amp;lt;/tex&amp;gt; символов. Таким образом, нельзя получить описанный выше код, если &amp;lt;tex&amp;gt; n &amp;gt; 2^L &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Сведение задачи о рюкзаке к генерации оптимального префиксного кода с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова, а &amp;lt;tex&amp;gt;P=\{p_{1},p_{2},...,p_{n}\}&amp;lt;/tex&amp;gt; — частоты символов алфавита. Алгоритм генерации кода будет следующим:&lt;br /&gt;
&lt;br /&gt;
# Отсортируем символы алфавита в порядке возрастания их частот.&lt;br /&gt;
# Для каждого символа создадим &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; предметов ценностью  &amp;lt;tex&amp;gt;2^{-1}\dots2^{-L}&amp;lt;/tex&amp;gt;, каждый из которых имеет вес &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# С помощью задачи о рюкзаке выберем набор предметов суммарной ценностью &amp;lt;tex&amp;gt;n - 1&amp;lt;/tex&amp;gt; (&amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; — размер алфавита) с минимальным суммарным весом. &lt;br /&gt;
# Посчитаем массив &amp;lt;tex&amp;gt;H=\{h_{1},h_{2},...,h_{n}\}&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — количество предметов ценностью &amp;lt;tex&amp;gt;p_{i}&amp;lt;/tex&amp;gt;, которые попали в наш набор.&lt;br /&gt;
&lt;br /&gt;
При этом &amp;lt;tex&amp;gt;h_{i}&amp;lt;/tex&amp;gt; — это длина кодового слова для &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-го символа.Зная длины кодовых слов, легко восстановить и сам код.&lt;br /&gt;
&lt;br /&gt;
Из последнего утверждения и шага 2 легко заметить, что длина кодового слова, сгенерированного приведенным алгоритмом, действительно не превысит &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Оптимальность же кода следует из оптимальности решения задачи о рюкзаке. Действительно, частота символа - это вес предеметов, соответствующих ему. Значит, чем чаще символ встречается в тексте, тем реже он будет попадать в наш рюкзак (будет выгоднее брать предметы аналогичной ценности, но меньшего веса, соответствующие более редким символам), а значит, его код будет короче.&lt;br /&gt;
&lt;br /&gt;
== Восстановление ответа. ==&lt;br /&gt;
# Отсортируем все символы по возрастанию длины кодового слова, которое им соответствует, а при равенстве длин — в алфавитном порядке.&lt;br /&gt;
# Первому символу сопоставим код, состоящий из нулей, соответствующей длины.&lt;br /&gt;
# Каждому следующему символу сопоставим следующее двоичное число. При этом если его длина меньше необходимой, то допишем нули справа.&lt;br /&gt;
&lt;br /&gt;
Заметим, что при генерации каждого следующего кодового слова, в качестве его префикса выступает последовательность, лексикографически большая, чем предыдущее кодовое слово (т.к. мы берем следующее двоичное число), а значит ни для каких двух кодовых слов одно не может быть префиксом другого. Т.е. код, сгенерированный таким образом является префиксным.&lt;br /&gt;
&lt;br /&gt;
== Пример работы алгоритма генерации оптимального префиксного кода с длиной кодового слова не более L бит ==&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из трех различных символов, &amp;lt;tex&amp;gt;P=\{1,2,3\}&amp;lt;/tex&amp;gt; — соответствующий ему набор частот. Пусть &amp;lt;tex&amp;gt;L = 2&amp;lt;/tex&amp;gt; — ограничение на длину кодового слова. &lt;br /&gt;
&lt;br /&gt;
Сначала создадим необходимый набор предметов;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Символ || Частота || Предметы&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt; (2^{-1}, 1),  (2^{-2}, 1) &amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;(2^{-1}, 2), (2^{-2}, 2)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|- align = &amp;quot;center&amp;quot;&lt;br /&gt;
| &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt; || &amp;lt;tex&amp;gt; (2^{-1}, 3), (2^{-2}, 3)&amp;lt;/tex&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Решим задачу о рюкзаке для заданного набора и выберем предметы суммарной ценностью &amp;lt;tex&amp;gt; n - 1 = 2 &amp;lt;/tex&amp;gt; с минимальным суммарным весом.  В нашем случае в оптимальный набор попадут следующие предметы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;(2^{-1}, 1), (2^{-1}, 2), (2^{-1}, 3), (2^{-2}, 1), (2^{-2}, 2) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Посчитаем массив &amp;lt;tex&amp;gt; H &amp;lt;/tex&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Итак, мы получили длины кодовых слов для символов. Осталось восстановить ответ.&lt;br /&gt;
&lt;br /&gt;
== Пример восстановления ответа. ==&lt;br /&gt;
&lt;br /&gt;
Итак, у нас есть &amp;lt;tex&amp;gt;A=\{A,B,C\}&amp;lt;/tex&amp;gt; — алфавит из &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; различных символов, а также &amp;lt;tex&amp;gt;H=\{2,2,1\}&amp;lt;/tex&amp;gt; — соответсвующие длины кодовых слов. Отсортируем символы в соответсвии с этими длинами.&lt;br /&gt;
&lt;br /&gt;
Сопоставим первому символу код, состоящий из 1 нуля:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; C = 0 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число. Т.к. длина кода увеличилась на один, то припишем справа ноль:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; B = 10 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сопоставим следующему символу следующее двоичное число.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt; A = 11 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
*[[Алгоритм_Хаффмана | Алгоритм Хаффмана]]&lt;br /&gt;
*[[Алгоритм_Ху-Таккера | Алгоритм Ху-Таккера]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Package-merge_algorithm Wikipedia - Package-merge algorithm]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Canonical_Huffman_code Wikipedia - Canonical Huffman code]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы сжатия ]]&lt;/div&gt;</summary>
		<author><name>84.54.248.47</name></author>	</entry>

	</feed>