Преобразование Барроуза-Уилера — различия между версиями
(→Доказательство корректности) |
(→Доказательство корректности) |
||
Строка 341: | Строка 341: | ||
:{| | :{| | ||
− | <tex> S_{p(i)}T \preceq S_{p(i + 1)}T,\ i = 0 .. N - 1\ \ \textbf{(1)}</tex> | + | <tex> S_{p(i)}T \preceq S_{p(i + 1)}T,\ i = 0, ..., N - 1\ \ \textbf{(1)}</tex> |
|} | |} | ||
− | Преобразование Барроуза-Уилера текста <tex>T</tex> есть текст <tex>B[0..N] = BW(T)</tex>, буквы которого заданы соотношением: | + | Преобразование Барроуза-Уилера текста <tex>T</tex> есть текст <tex>B[0 .. N] = BW(T)</tex>, буквы которого заданы соотношением: |
:{| | :{| | ||
Строка 353: | Строка 353: | ||
:{| | :{| | ||
− | <tex>B_{\sigma(i)} \preceq B_{\sigma(i + 1)}</tex>, при <tex>i = 0 .. N - 1\ \ \textbf{(3)}</tex>, | + | <tex>B_{\sigma(i)} \preceq B_{\sigma(i + 1)}</tex>, при <tex>i = 0, ..., N - 1\ \ \textbf{(3)}</tex>, |
|} | |} | ||
и в случае равенства <tex>B_{\sigma(i)}</tex> и <tex>B_{\sigma(i + 1)}</tex> выполнено {{---}} <tex>\sigma(i) < \sigma(i + 1)</tex>. Перестановка однозначно определяется текстом <tex>B</tex> и ее можно посчитать за <tex>O(N)</tex>, используя сортировку подсчетом. Рассмотрим перестановку <tex>\sigma</tex> как отображение <tex>\sigma : \{0, ..., N\} \to \{0, ..., N\}</tex>. Пусть <tex>\sigma^{k}</tex> копмозиция <tex>k</tex> отображений <tex>\sigma^{k} = \sigma^{k - 1} \circ \sigma</tex>, где <tex>\sigma^{1} = \sigma, \sigma^{0} \equiv i</tex>. | и в случае равенства <tex>B_{\sigma(i)}</tex> и <tex>B_{\sigma(i + 1)}</tex> выполнено {{---}} <tex>\sigma(i) < \sigma(i + 1)</tex>. Перестановка однозначно определяется текстом <tex>B</tex> и ее можно посчитать за <tex>O(N)</tex>, используя сортировку подсчетом. Рассмотрим перестановку <tex>\sigma</tex> как отображение <tex>\sigma : \{0, ..., N\} \to \{0, ..., N\}</tex>. Пусть <tex>\sigma^{k}</tex> копмозиция <tex>k</tex> отображений <tex>\sigma^{k} = \sigma^{k - 1} \circ \sigma</tex>, где <tex>\sigma^{1} = \sigma, \sigma^{0} \equiv i</tex>. | ||
+ | |||
+ | {{Теорема | ||
+ | |statement= | ||
+ | |||
+ | ''При всех <tex>m = 1, ..., N + 1</tex> верны утверждения, | ||
+ | <tex>B_{\sigma_{i}...B_{\sigma^{m}_{i} \preceq B_{\sigma_{i + 1}}...B_{\sigma^{m}_{i + 1}}</tex>, при <tex>i = 0, ..., N - 1\ \ \textbf{(4)}</tex>'' | ||
+ | |||
+ | |proof= | ||
+ | |||
+ | |||
+ | |||
+ | }} | ||
{{Теорема | {{Теорема |
Версия 02:23, 24 октября 2013
Содержание
Определение
Преобразование Барроуза — Уилера — алгоритм, используемый для предварительной обработки данных перед сжатием, разработанный для улучшения эффективности последующего кодирования. Преобразование Барроуза — Уилера меняет порядок символов во входной строке таким образом, что повторяющиеся подстроки образуют на выходе идущие подряд последовательности одинаковых символов.
Описание алгоритма
Преобразование выполняется в три этапа.
- Cоставляется таблица всех циклических сдвигов входной строки.
- Производится лексикографическая (в алфавитном порядке) сортирова строк таблицы.
- В качестве выходной строки выбрается последний столбец таблицы преобразования и номер строки, совпадающей с исходной.
Пример работы алгоритма
Пусть нам дана исходная строка
"ABACABA".Трансформация | |||
---|---|---|---|
Вход | Все Перестановки |
Сортировка Строк |
Выход |
ABACABA |
ABACABA BACABAA ACABAAB CABAABA ABAABAC BAABACA AABACAB |
AABACAB ABAABAC ABACABA ACABAAB BAABACA BACABAA CABAABA |
BCABAAA |
Результат можно записать так:
("BCABAAA", 3), где 3 — это номер исходной строки в отсортированной матрице, так как он нужен для обратного преобразования.
Следует заметить, что иногда в исходной строке приводится, так называемый, символ конца строки $, который в преобразовании будет считаться последним (максимальным) символом, тогда сохранение номера исходной строки не требуется.
Пусть нам дана исходная строка "ABACABA$".
Трансформация | |||
---|---|---|---|
Вход | Все Перестановки |
Сортировка Строк |
Выход |
ABACABA$ |
ABACABA$ BACABA$A ACABA$AB CABA$ABA ABA$ABAC BA$ABACA A$ABACAB $ABACABA |
ABACABA$ ABA$ABAC ACABA$AB A$ABACAB BACABA$A BA$ABACA CABA$ABA $ABACABA |
$CBBAAAA |
При аналогичном вышеприведённом преобразовании та строчка в матрице, которая будет заканчиваться на символ конца строки и будет исходной: ("ABACABA$"). Тогда результат можно записать так:
"$CBBAAAA".Обратное преобразование
Наивный алгоритм
Пусть нам дано:
("BCABAAA", 3). Тогда выпишем в столбик нашу преобразованную последовательность символов "BCABAAA". Запишем её как последний столбик предыдущей матрицы (при прямом преобразовании Барроуза — Уилера), при этом все предыдущие столбцы оставляем пустыми. Далее построчно отсортируем матрицу, затем в предыдущий столбец запишем "BCABAAA". Опять построчно отсортируем матрицу. Продолжая таким образом, можно восстановить полный список всех циклических перестановок строки, которую нам надо найти. Выстроив полный отсортированный список перестановок, выберем строку с номером, который нам был изначально дан. В итоге мы получим искомую строку. Алгоритм обратного преобразования описан в таблице ниже:Обратное преобразование | |||||||
---|---|---|---|---|---|---|---|
Вход | |||||||
BCABAAA | |||||||
Добавление 1 | Сортировка 1 | Добавление 2 | Сортировка 2 | Добавление 3 | Сортировка 3 | Добавление 4 | |
B C A B A A A |
A A A A B B C |
BA CA AA BA AB AB AC |
AA AB AB AC BA BA CA |
BAA CAB AAB BAC ABA ABA ACA |
AAB ABA ABA ACA BAA BAC CAB |
BAAB CABA AABA BACA ABAA ABAC ACAB | |
Сортировка 4 | Добавление 5 | Сортировка 5 | Добавление 6 | Сортировка 6 | Добавление 7 | Сортировка 7 | |
AABA ABAA ABAC ACAB BAAB BACA CABA |
BAABA CABAA AABAC BACAB ABAAB ABACA ACABA |
AABAC ABAAB ABACA ACABA BAABA BACAB CABAA |
BAABAC CABAAB AABACA BACABA ABAABA ABACAB ACABAA |
AABACA ABAABA ABACAB ACABAA BAABAC BACABA CABAAB |
BAABACA CABAABA AABACAB BACABAA ABAABAC ABACABA ACABAAB |
AABACAB ABAABAC ABACABA ACABAAB BAABACA BACABAA CABAABA | |
Результат | |||||||
ABACABA |
Следует также заметить, что если нам было бы дано
"$CBBAAAA", то мы также получили бы нашу исходную строку, только с символом конца строки $ на конце: ABACABA$.Как несложно посчитать сложность данного алгоритма
, также он требует памяти.Оптимизация
Однако, данный алгоритм можно оптимизировать. Заметим, что при каждом проявлении неизвестного столбца выполнялись одни и те же действия. Мы приписывали новый столбец и сортировали имеющиеся данные. На каждом шагу мы к строке, которая находилась на
-ом месте приписываем в начало -ый элемент столбца входных данных. Пусть изначально мы знаем каким по порядку является приписанный нами в начало символ (то есть каким по порядку в столбце). И конечно же мы знаем исходя из предыдущего шага какое место занимала наша строка без этого первого символа ( -ое). Тогда несложно заметить, что при выполнении такой операции строка с номером всегда будет перемещаться на позицию с номером .0 | а | р | 9 | |
1 | а | д | 7 | |
2 | а | a | 0 | |
3 | а | к | 8 | |
4 | а | р | 10 | |
5 | б | a | 1 | |
6 | б | a | 2 | |
7 | д | a | 3 | |
8 | к | a | 4 | |
9 | р | б | 5 | |
10 | р | б | 6 |
Здесь слева это отсортированный данный столбец, чтобы мы знали какое место в лексикографическом порядке занимает приписываемый нами символ среди всех элементов данного нам изначально столбца. Справа - изначально данный столбец и соответствующее ему число. Поскольку мы в нашем алгоритме новый столбец приписываем в начало, то мы из состояния
(левый столбец) переходим в состояние (правый). Для того, чтобы восстановить строку, нам необходимо от последней такой цифры по пути из в восстановить строку.
Сложность оптимизированного алгоритмаДанный алгоритм работает за действий и требует памяти. Однако, если размер алфавита не очень большой, то для выяснения первого столбца матрицы можно использовать сортировку подсчетом, в этом случае алгоритм работает за действий и требует памяти, где — размер алфавита.Псевдокод оптимизированного алгоритмаПусть — количество символов во входной строке, — количество символов в алфавите, — номер исходной строки в матрице перестановок, — входящая строка, — массив для сортировки подсчетом, — вектор обратного преобразования, — номер данной нам строки в таблице.// Cчитаем частоты символов for i = 0 .. M count[i] = 0 for i = 0 .. N count[s[i]]++ // Упорядочиваем символы, чтобы получить первый столбец исходной матрицы // count[i] указывает на первую позицию символа i в первом столбце sum = 0 for i = 0 .. M sum = sum + count[i] count[i] = sum - count[i] // Cоздаем вектор обратного преобразования for i = 0 .. N t[count[s[i]]] = i count[s[i]]++ // И восстанавливаем исходный текст j = t[x] for i = 0 .. N print(s[j]) j = t[j] Доказательство корректностиПусть текст состоит из символов, занумерованных с нуля: . Буквы принадлежат некоторому алфавиту . Лексикографический порядок (строгий) на строках из алфавита будем обозначать . Обозначим через циклический сдвиг текста на символов влево:Существует перестановка чисел , которая удовлетворяет условию:Преобразование Барроуза-Уилера текста есть текст , буквы которого заданы соотношением:Пусть — перестановка чисел , удовлетворяющая условию:и в случае равенства и выполнено — . Перестановка однозначно определяется текстом и ее можно посчитать за , используя сортировку подсчетом. Рассмотрим перестановку как отображение . Пусть копмозиция отображений , где .
Дополнительно
Ссылки |