- •Элементарные алгоритмы для работы с графами
- •Работа алгоритма[править | править вики-текст]
- •Неформальное описание[править | править вики-текст]
- •Формальное описание[править | править вики-текст]
- •Алгоритм поиска в глубину[править | править вики-текст]
- •Нерекурсивные варианты[править | править вики-текст]
- •Общая идея
- •[Править]Пошаговое представление
- •[Править]Реализация
- •[Править]Время работы
- •[Править]Цвета вершин
- •Топологическая сортировка и сильно связные компоненты
- •↑ Пример ориентированного неотсортированного графа, к которому применима топологическая сортировка
- •Пример работы алгоритма[править | править вики-текст]
- •Алгоритмы[править | править вики-текст]
- •Минимальные остовные деревья (мst)
- •Введение
- •Постановка задачи
- •Кратчайшие пути
- •Давайте придумаем что-нибудь простое
- •А если я педант?
- •Задача о максимальном потоке
- •[Править]Определение потока
- •[Править]Пример
- •Увеличивающие пути. Теорема Бержа
- •Алгоритм Эдмондса. Сжатие цветков
- •Эффективная реализация
- •Оптимизация: предварительное построение паросочетания
- •Случай двудольного графа
- •Дальнейшая оптимизация
- •[Править]Реализация
- •[Править]Оценка производительности
- •[Править]Пример несходящегося алгоритма
- •[Править]Оценка быстродействия
- •[Править]Литература
- •Максимальные паросочетания[править | править вики-текст]
- •Описание алгоритма Необходимые определения
- •Теорема Бержа
- •Алгоритм Куна
- •Время работы
- •Реализация
- •Улучшенная реализация
- •[Править]Постановка задачи
- •[Править]Решение
- •[Править]Псевдокод
- •Префиксы и суффиксы строки
- •Прямые переходы
- •[Править]Суффиксные ссылки
- •Основные определения и описание структуры[править | править вики-текст]
- •Свойства суффиксных деревьев[править | править вики-текст]
- •Требования суффиксного дерева к памяти[править | править вики-текст]
- •[Править]Недостатки
- •Метод хеширования
- •[Править]Алгоритм
- •[Править]Псевдокод
- •[Править]Время работы
- •[Править]Надёжность
- •Автоматные модели в программировании
- •[Править]Переходы между состояниями [править]Прямые переходы
- •[Править]Суффиксные ссылки
- •[Править]Псевдокод
- •[Править]Пример использования
- •[Править]Псевдокод
- •[Править]Пример
- •[Править]Время работы
- •[Править]Эффективный алгоритм
- •[Править]Псевдокод
- •[Править]Время работы
- •[Править]Построение префикс-функции по z-функции [править]Постановка задачи
- •[Править]Описание алгоритма
- •Приближенные алгоритмы решения np-трудных задач
Префиксы и суффиксы строки
Строка X называется префиксом строки S, если строка S представима как XY. Строка Y называется суффиксом строки S. В листинге 9.6. расположена программа, которая содержит две процедуры. Одна процедура по заданной строке выводит все префиксы этой строки, причем каждый префикс выводится с отдельной строки выходного файла. Вторая процедура выводит все суффиксы строки. В процедурах используется стандартная функция copy (s,n,i),которая возвращает подстроку строки s, начиная с символа номер n, состоящую из i символов.
Прямые переходы
Пусть
в нашем автомате пока одно состояние
—
.
Пройдем по образцу, добавляя для каждого
его символа новое состояние и переход
в него из предыдущего состояния по этому
символу. Последнее состояние объявим
допускающим. Таким образом, каждому
состоянию теперь соответствует ровно
один префикс образца. Пронумеруем их
длинами соответствующих префиксов с
увеличением на единицу.
[Править]Суффиксные ссылки
Теперь
нужно расставить остальные переходы.
В итоговом автомате при переходе в
состояние
префикс
образца —
—
должен быть максимальным его префиксом,
равным суффиксу текста до последнего
просмотренного символа, включительно.
Переходы, осуществляющие перемещение
в такие префиксы, называют суффиксными
ссылками.
В
качестве базы построения суффиксных
ссылок проведем из
по
всем символам алфавита, кроме первого
символа образца, ссылки в
:
длина максимального текущего суффикса
текста, равного префиксу образца,
увеличивается максимум на один и только
в том случае, когда очередные их символы
совпадают. Пусть построены все переходы
из состояний, номер которых меньше
некоторого
.
Тогда для того, чтобы определить
направление ссылки из состояния
по
символу
,
нужно найти длину наибольшего префикса
образца, из состояния которого по
ведет
прямой переход (если таких префиксов
нет, значит, символ прежде не встречался
в образце — нужно перейти в
).Префикс-функция,
взятая многократно от
символа
образца, позволяет перебрать все префиксы
образца, равные суффиксу его
первых
символов.
Таким образом,
,
где справа описан прямой переход либо
переход из
.
Так как все переходы из первых
состояний
уже построены,
соответствует
нужному состоянию.
Если
забыть про разницу в построении прямых
переходов и суффиксных ссылок, можно
заметить, что переходы
решают
поставленную задачу нахождения
максимального суффикса текста, равного
префиксу образца.
Основные определения и описание структуры[править | править вики-текст]
—
непустое
конечное множество символов,
называемое алфавитом. Последовательность
символов (возможно, пустая) из алфавита
обозначается буквами r, s и t.
представляет
собой перевёрнутую строку. Отдельные
символы обозначаются буквами x, y или
z.
—
пустая строка. Символами из алфавита
являются буквы a,
b, ….
Пока размер алфавита принимается
постоянным. |t| обозначает
длину строки t.
—
все строки длины m,
и
.
Префикс w строки t —
строка такая, что wv
= t для
некоторой (возможно, пустой) строки v.
Префикс называется собственным,
если |v|
0.
Суффикс w строки t — строка такая, что vw = t для некоторой (возможно, пустой) строки v. Суффикс называется собственным, если |v| 0. Например, для строки «substring» подстрока «sub» является собственным префиксом, «ring» — собственным суффиксом.
Подстрока w строки t называется правым
ветвлением,
если t может
быть представлена как
и
для
некоторых строк
и
,
а также букв x
y. Левое
ветвление определяется
аналогично. Например, для «eabceeabcd»
подстрока «abc» является правым ветвлением,
так как в обоих её вхождениях в t справа
от неё стоят различные символы, зато та
же подстрока не является левым ветвлением,
потому что слева от неё в обоих вхождениях
стоит одинаковый символ «e».
-дерево T —
корневое дерево с
рёбрами, помеченными последовательностями
из
.
Для каждого символа a из
алфавита каждый узел в дереве Tимеет
не более одного ребра, метка которого
начинается c символа a.
Ребро от t до s с
меткой v мы
будем обозначать
.
Пусть k —
узел
-дерева T,
тогда path(k) — строка, которая представляет
собой конкатенацию всех
меток рёбер от корня до k.
Мы назовем
местоположением w,
для которого path(
)
= w.
Так
как каждая ветвь уникальна, если path(t)
= w,
мы можем обозначить узел t за
.
Поддерево узла
обозначается
.
Слова,
которые представлены в
-дереве T,
задаются множеством, которое обозначается
words(T).
Слово w входит
во множество words(T)
тогда и только тогда, когда существует
строка v (возможно,
пустая) такая, что
—
узел дерева T.
Если
строка w входит
в words(T), w
= uv,
—
узел дерева T,
пару
будем
называть ссылочной
парой w по
отношению к дереву T.
Если u —
наидлиннейший префикс такой, что
—
ссылочная пара, мы будем называть
канонической
ссылочной парой.
Тогда мы будем писать
.
Местоположение
называется
явным, если |v| =
0, и неявным в противном случае.
-дерево T, в котором каждое ребро помечено одиночным символом, называется атомарным (для него каждое местоположение является явным). -дерево T, в котором каждый узел является либо корнем, либо листом или узлом ветвления, называется компактным.
Атомарное
-дерево
также называют
(луч).
Атомарное и компактное
-дерево
однозначно определены словами, которые
они содержат.
Суффиксное дерево для строки t — это -дерево такое, что words(T) = {w| w — подслово t}. Для строки t атомарное суффиксное дерево обозначается ast(t), компактное суффиксное дерево обозначается cst(t).
Обратное префиксное дерево строки t — это суффиксное дерево для строки .
Вложенный суффикс — суффикс, который входит в строку t где-нибудь ещё. Наидлиннейший вложенный суффикс называется активным суффиксомстроки t.
