Алгоритм Кока-Янгера-Касами, модификация для произвольной грамматики — различия между версиями
Gaporf (обсуждение | вклад) (→Алгоритм для произвольной грамматики) |
Gaporf (обсуждение | вклад) (→Оценка сложности) |
||
Строка 61: | Строка 61: | ||
Обозначим <tex>M = \max\limits_{A \rightarrow \alpha}\left|\alpha\right|</tex> — максимальную длину правой части правила. | Обозначим <tex>M = \max\limits_{A \rightarrow \alpha}\left|\alpha\right|</tex> — максимальную длину правой части правила. | ||
− | Обработки правил вида <tex>A \rightarrow w[i]</tex>, <tex>A \rightarrow \varepsilon</tex> и нахождение <tex>h\left[A \rightarrow \alpha, i, i, 0\right]</tex> выполняются за <tex>O(n \cdot |\Gamma|)</tex>. | + | Обработки правил вида <tex>A \rightarrow w[i]</tex>, <tex>A \rightarrow \varepsilon</tex> и нахождение <tex>h\left[A \rightarrow \alpha, i, i, 0\right] \ </tex> выполняются за <tex>O(n \cdot |\Gamma|)</tex>. |
− | Время одного перехода вспомогательной динамики <tex>O(n)</tex>, суммарное число состояний <tex>O(n^2 \cdot |\Gamma| \cdot M)</tex>. Отсюда расчёт вспомогательной динамики занимает <tex>O \left( n^3 \cdot |\Gamma| \cdot M \right)</tex> времени, базовая динамика находится, как <tex>O \left( n^2 \cdot |\Gamma| \right)</tex>. Итоговая временная сложность алгоритма равна <tex>O \left( n^3 \cdot |\Gamma| \cdot M \right)</tex>. Алгоритму требуется <tex>O(n^2 \cdot |\Gamma| \cdot M)</tex> памяти. | + | Время одного перехода вспомогательной динамики <tex>O(n)</tex>, суммарное число состояний <tex>O(n^2 \cdot |\Gamma| \cdot M)</tex>. Отсюда расчёт вспомогательной динамики занимает <tex>O \left( n^3 \cdot |\Gamma| \cdot M \right) \ </tex> времени, базовая динамика находится, как <tex>O \left( n^2 \cdot |\Gamma| \right)</tex>. Итоговая временная сложность алгоритма равна <tex>O \left( n^3 \cdot |\Gamma| \cdot M \right)</tex>. Алгоритму требуется <tex>O(n^2 \cdot |\Gamma| \cdot M) \ </tex> памяти. |
== См. также == | == См. также == |
Версия 18:26, 14 мая 2019
Задача: |
Пусть дана контекстно-свободная грамматика и слово . Требуется выяснить, выводится ли это слово в данной грамматике. |
Базовая версия данного алгоритма работает только для грамматик в нормальной форме Хомского. Модифицируем алгоритм для работы на произвольных контекстно-свободных грамматиках. Модификация алгоритма сильно проще в написании, чем приведение к нормальной форме Хомского, поэтому часто используют её, не смотря на то, что время работы у нее больше.
Алгоритм для произвольной грамматики
Будем решать задачу динамическим программированием. Введём динамику базовой версии алгоритма.
, аналогичноТакже введём вспомогательный четырехмерный массив
тогда и только тогда, когда из префикса длины правой части данного правила можно вывести .Рассмотрим все тройки
, где — константа и , и такое, что .- База динамики:
- , если в грамматике присутствует правило , иначе ;
- , если в грамматике присутствует правило , иначе ;
- .
- Переход:
- Пусть значения для всех нетерминалов, пар и уже вычислены, поэтому вспомогательная динамика: . То есть, подстроку можно вывести из префикса длины правой части данного правила, если из префикса длины правой части данного правила можно вывести , а подстрока выводится из -го символа правой части правила. Это вычисление может обратится к , но на результат это не повлияет, так как в данный момент .
- Но если — терминал, то подстроку можно вывести из префикса длины правой части данного правила, если из префикса длины правой части данного правила можно вывести , а подстрока выводится, если .
- Базовая динамика выражается так: . То есть, подстроку можно вывести из нетерминала , если из длины правой части данного правила можно вывести .
- Завершение:
- После окончания работы ответ содержится в ячейке , где .
Псевдокод
CYK_Modified(S, Г): // S — строка длины n, Г — КС-грамматика for i = 1..n for Rj -> alpha // перебор состояний if( A -> w[i] in Г) a[A, i, i+1] = true // если в грамматике Г присутствует правило A -> w[i] else a[A, i, i+1] = false if( A -> eps in Г) a[A, i, i] = true // если в грамматике Г присутствует правило A -> eps else a[A, i, i] = false h[A->alpha, i, i, 0] = true for m = 1..n for i = 1..n j = i+m for k = 1..M for Rj -> alpha // перебор состояний h[A->alpha, i, j+1, k] = OR( for r = i..j+1) (h[A->alpha, i, r, k-1] & a[alpha[k],r,j+1]) for i = 1..n for j = 1..n for Rj -> alpha a[A, i, j] = OR( for A->alpha) h[A->alpha, i, j, |alpha|] // где |alpha| — размер правой части правила return a[S, 1, n]
Оценка сложности
Обозначим
— максимальную длину правой части правила.Обработки правил вида
, и нахождение выполняются за .Время одного перехода вспомогательной динамики
, суммарное число состояний . Отсюда расчёт вспомогательной динамики занимает времени, базовая динамика находится, как . Итоговая временная сложность алгоритма равна . Алгоритму требуется памяти.