Преобразование Берроуза-Уилера без символа EOF

Мне нужно выполнить известное преобразование Берроуза-Уилера за линейное время. Я нашел решение с сортировкой по суффиксу и символом EOF, но добавление EOF меняет преобразование. Например: рассмотрим строку bcababa и два поворота

  • s1 = abababc
  • s2 = ababcab

ясно, что s1 ‹ s2. Теперь с символом EOF:

  • s1 = абаба#bc
  • s2 = аба#bcab

и теперь s2 ‹ s1. И результирующая трансформация будет другой. Как я могу выполнить BWT без EOF?


person user8078    schedule 10.05.2012    source источник


Ответы (3)


Вы можете выполнить преобразование в линейном времени и пространстве без символа EOF, вычислив массив суффиксов строки, объединенной с самой собой. Затем переберите массив суффиксов. Если текущее значение массива суффиксов меньше n, добавьте в выходной массив последний символ вращения, начиная с позиции, обозначенной текущим значением в массиве суффиксов. Однако этот подход приведет к немного другому результату преобразования BWT, поскольку повороты строк не сортируются, как если бы присутствовал символ EOF.

Более подробное описание можно найти здесь: http://www.quora.com/Algorithms/How-I-can-optimize-burrows-wheeler-transform-and-inverse-transform-to-work-в-O-n-времени-O-n-пространстве

person John Kurlak    schedule 21.12.2012
comment
Является ли использование символа EOF эквивалентным строке, объединенной с самим методом? Вывод, который я получаю, не кажется идентичным. Используя символ EOF, \0, который должен быть меньше, чем все остальные символы, я получаю ptr: 13, string: "CTAAAACACGAGA\0GATGCAGGTATTTTATGTTAGTGATGCATTTTATGGCTCCCCGAGCATATC" Используя метод конкатенации ввода, я получаю, ptr: 12, str: "TAAAACACGAGACGATGCGGATATTTTATGTTAGTGATGCATTTTATGGCTCCCCGAGCATATC" Даже если мы проигнорируем терминатор NUL, вывод все равно будет другим. - person DSnet; 24.11.2015
comment
@DSnet Какую строку ввода вы использовали? AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTCTCTGAC? - person John Kurlak; 24.11.2015
comment
@DSnet... Хорошо, я могу воспроизвести ваши результаты. Я проверю позже, если у меня будет время. Спасибо! - person John Kurlak; 24.11.2015
comment
Это правильная строка, спасибо за это. Я пытаюсь написать кодировщик bzip2, используя SAIS. В настоящее время с трюком с дублированной входной строкой я, кажется, могу генерировать действительные файлы bzip2. Однако замедление из-за необходимости обработки 2n фактических входных данных вызывает сожаление. - person DSnet; 25.11.2015
comment
@DSnet Да ... мой подход определенно неверен. Проблема в том, что повороты строк должны быть отсортированы таким образом, чтобы символ EOF был лексикографически меньше, чем другие символы. Мой подход без символа EOF не учитывает это при сортировке суффиксов, поэтому порядок сортировки неверен. Это приводит к тому, что он производит неправильный вывод. С тех пор я обновил свой ответ Quora. Мне интересно, если вы просто пишете кодировщик bzip2, зачем вам нужно создавать BWT без символа EOF? Почему бы просто не использовать первый подход, который я предлагаю? - person John Kurlak; 25.11.2015
comment
@DSnet Вам также может быть интересно: rd.springer.com /глава/10.1007%2F978-3-642-03784-9_9 - person John Kurlak; 25.11.2015

Вам нужно иметь символ EOF в строке для работы BWT, потому что в противном случае вы не сможете выполнить обратное преобразование, чтобы вернуть исходную строку. Без EOF обе строки «ba» и «ab» имеют одинаковую преобразованную версию («ba»). С EOF преобразования отличаются

ab        ba

a b |     a | b
b | a     b a |
| a b     | b a

то есть ab преобразуется в «|ab», а ba в «b|a».

EOF необходим для BWT, потому что он отмечает точку, в которой начинается символьный цикл.

Re: делать это без символа EOF, согласно Википедии,

Поскольку любое вращение входной строки приведет к одной и той же преобразованной строке, BWT нельзя инвертировать без добавления маркера EOF к входным данным или добавления к выходным данным информации, такой как индекс, который позволяет идентифицировать входная строка из класса всех ее вращений.

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

Биективное преобразование вычисляется путем разложения входных данных на невозрастающую последовательность слов Линдона; такая факторизация существует по теореме Чена – Фокса – Линдона и может быть найдена за линейное время. Затем алгоритм сортирует все повороты всех этих слов; как и в обычном преобразовании Берроуза-Уилера, это дает отсортированную последовательность из n строк. Затем преобразованная строка получается путем выбора последнего символа каждой из этих строк в этом отсортированном списке.

person Antti Huima    schedule 10.05.2012
comment
Я бы решил проблему с символом EOF. Если бы у меня был студент, который решил бы проблему без символа EOF, потому что он / она мог бы найти решение только без него, я бы подвел этого студента. - person Antti Huima; 10.05.2012
comment
проверка выполняется автоматической системой, если я использую EOF, у меня будет неверный ответ. - person user8078; 10.05.2012
comment
Хм интересно :) тогда вам просто нужно выполнить это без EOF. Однако я с подозрением отношусь к требованию линейного времени, если это домашнее задание/упражнение/вопрос интервью, потому что даже простая сортировка не является операцией линейного времени. - person Antti Huima; 10.05.2012
comment
@antti.huima Вы можете сделать это в линейном времени и пространстве, если вы работаете с массивом суффиксов строки, объединенной с самой собой. Смотрите мой ответ для более подробной информации. - person John Kurlak; 21.12.2012
comment
Вы не правы. Практические реализации BWT не включают сторожевой элемент явно в выходные данные. Вместо этого индекс исходной строки передается вместе с выводом для декодирования (если только вы не используете биективную версию, которая медленнее и гораздо менее известна). Таким образом, вы можете выполнить обратное преобразование ввода, закодированного без часового, вам просто нужен этот исходный индекс строки. - person kvark; 26.02.2014

Я знаю, что эта тема довольно старая, но у меня была такая же проблема, и я нашел следующее решение:

  • Найдите лексикографическое минимальное вращение строки и сохраните смещение (необходимое для реверсирования) (я использую факторизацию Лайдона)
  • Используйте обычные алгоритмы bwt для повернутой строки (это дает правильный результат, потому что все алгоритмы предполагают, что за строкой следует лексикографически минимальный char)
  • Чтобы изменить: unbwt, используя, например. поиск в обратном направлении, начиная с индекса 0, и запись соответствующего символа в сохраненное смещение
person Christoph Diegelmann    schedule 18.07.2015