2009-09-14 3 views
2

У меня есть 64-битные значения, которые я хочу сжать, используя тот факт, что только часть где-то посередине содержит данные, а до и после этого - нули.Самый эффективный способ кодирования 2 позиций между 0 и 64?

Скажем, что фактические данные имеют длину 1 бит и дополняются n 0s спереди и m 0s в конце, так что n + l + m = 64. Вместо передачи/хранения 64 бит я могу передавать l бит плюс все Мне нужно кодировать положение данных в 64-битном интервале.

Например, я сохраняю l, m и биты данных, затем я бы восстановил исходный 64-битный шаблон, прочитав l, прочитав l бит данных, прочитав m и сдвинув данные m бит влево ,

Наименьшая накладная плата, которую я мог бы придумать, - это два раза по 6 бит для хранения двух из l, n и m (каждый может быть между 0 и 64). Можно ли уменьшить это число?

ответ

2

l может быть от 0 до 64, поэтому не отправляйте l, отправляйте n и m, так как они могут быть равны нулю и не нуждаются в доступе до 64 (они просто должны быть в состоянии добавить до 64).

L бит должен начинаться и заканчиваться 1, поэтому их не нужно передавать.

отправить 6 битов для п
отправить до 6 битов для м (смотри ниже)
высчитывает л = 64 - (п + т)
, если л = 0, то число равно 0, не отправлять все остальное
Если l = 1, номер 1 * 2^m, ничего не посылайте
, если l = 2, номер 3 * 2^m, ничего не посылайте
отправьте средний l - 2 бит.

Максимальные накладные расходы = 10 бит.

Снижение в битах для м, потому что
если п> 32, то вы знаете м < 32, так что нужно только 5 бит
если п> 48, то вы знаете м < 16, поэтому требуется только 4 бита
, если п> 56, то вы знаете м < 8, так что требуется только 3 бита
если п> 60, то вы знаете м < 4, так что требуется только 2 бита
, если п = 63, то вы знаете м < 2, так что только требуется 1 бит

+0

10 бит - это служебные данные ... значение не более l + 10 бит. –

+0

Правильно, я могу оставить 2 бита от полезной нагрузки, тоже, хорошо! И хороший момент для вывода битовой длины m из значения n. –

+0

Если вы решили всегда кодировать нуль при n = 63, m = 1, то все «>» в ​​приведенном выше может быть «> =», тем самым добавляя еще несколько экземпляров, где нужно отправить один бит. –

3

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

Однако, если распределение нулей в номерах искажено, вы можете получить лучшее сжатие в среднем с помощью кодов Хаффмана или аналогичной техники для представления счетчиков. Другая возможность заключается в использовании дельта-кодирования, если нулевое распределение сильно коррелировано от одного 64-битного значения к другому.

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

+0

В общем случае распределение нулей не перекошено, но исходные значения отображаются в больших группах, где ведущие нули одинаковы, а конечные нули очень похожи, поэтому дельта-кодирование будет работать хорошо. Быстро взглянув на коды Хэмминга, я не мог понять, как это сокращает кодовое слово, это код проверки ошибок и фактически добавляет (валидацию) информацию, не так ли? –

+0

Вы путаете Хэмминга и Хаффмана? – starblue

+0

@starblue: Да, я это сделал. Исправлено сейчас. Спасибо –

1

Ваше решение кажется довольно хорошим.
Huffman coding - это еще один способ сжать ваши значения, особенно если есть значения с большой частотой.

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

4

Ваш анализ звучит правильно для отдельных объектов. Но если вы передаете много таких значений вместе, общий алгоритм кодирования энтропии, такой как gzip, вероятно, будет лучше, так как он вполне может устранить строки нулей и также использовать избыточность данных.

+0

+1 для gzip, хотя это не сразу полезно для меня сейчас, я думаю, это хорошая вещь. –

0

Есть 64 возможных стартовых позиций n последовательности из них и длины последовательности l может быть уже не 64 - n. Так что есть

r = sum(n = 0..63, 64 - n) + 1 

последовательностей в общей сложности. Добавленный - для последовательности всех нулей. Выполнение некоторой математики дает следующее.

r = 64 * 64 - (63 * 64)/2 + 1 
    = 2081 

Представление 2081 возможных значений требует log2(2081) = 11.023 битов. Поэтому ваше предложение кодировать информацию с использованием двух нулевых разрядов 6, требующих 12 бит, является оптимальным (в предположении равных распределений всех возможных значений).

+0

Я понял вопрос как означающий, что часть данных в середине может содержать 1 и 0, а не так, чтобы часть данных была смежной. –

+0

Вы правы - я получил среднюю часть полностью неправильно. Спасибо что подметил это. –

+0

Сюда входит последовательность длины l = 0, начинающаяся с позиций n = 0..63. Вам нужно всего лишь закодировать один из них, поэтому есть только 2018 значений, для которых достаточно 11 бит. – Henrik

Смежные вопросы