Алгоритм Кока-Янгера-Касами разбора грамматики в НФХ — различия между версиями
Kabanov (обсуждение | вклад) м (→Асимптотика) |
Kabanov (обсуждение | вклад) |
||
Строка 6: | Строка 6: | ||
== Алгоритм == | == Алгоритм == | ||
'''Алгоритм Кока-Янгера-Касами''' (''Cocke — Younger — Kasami algorithm'', '''CYK - алгоритм''') - универсальный алгоритм, позволяющий по слову узнать, выводимо ли оно в заданной КС-грамматике в нормальной форме Хомского. | '''Алгоритм Кока-Янгера-Касами''' (''Cocke — Younger — Kasami algorithm'', '''CYK - алгоритм''') - универсальный алгоритм, позволяющий по слову узнать, выводимо ли оно в заданной КС-грамматике в нормальной форме Хомского. | ||
− | Будем решать задачу [[Динамическое_программирование|динамическим программированием]]. Заведем трехмерный массив d, состоящий из логических значений, и <tex>d[A][i][j] = true</tex> тогда и только тогда, когда из нетерминала <tex>A</tex> правилами грамматики можно вывести подстроку <tex>w[i | + | Будем решать задачу [[Динамическое_программирование|динамическим программированием]]. Заведем трехмерный массив d, состоящий из логических значений, и <tex>d[A][i][j] = true</tex> тогда и только тогда, когда из нетерминала <tex>A</tex> правилами грамматики можно вывести подстроку <tex>w[i \dots j]</tex>. |
Рассмотрим все пары <tex>\lbrace \langle j, i \rangle | j-i=m \rbrace</tex>, где <tex>m</tex> - константа и <tex>m < n</tex>. | Рассмотрим все пары <tex>\lbrace \langle j, i \rangle | j-i=m \rbrace</tex>, где <tex>m</tex> - константа и <tex>m < n</tex>. | ||
Строка 24: | Строка 24: | ||
=== Завершение === | === Завершение === | ||
− | + | После окончания работы значение <tex>d[S][1][n]</tex> содержит ответ на вопрос, выводима ли данная строка в данной грамматике. | |
== Модификации == | == Модификации == | ||
− | |||
− | + | === Количество способ вывести слово === | |
+ | Если массив будет хранить целые числа, а формулу заменить на <tex>d[A][i][j] = \sum\limits_{A \rightarrow BC}\sum\limits_{k = i}^{j-1} d[B][i][k] \cdot d[C][k + 1][j]</tex>, то <tex>d[A][i][j]</tex> - количество способов получить подстроку <tex>w[i \dots j]</tex> из нетерминала <tex>A</tex>. | ||
+ | |||
+ | === Минимальная стоимость вывода слова === | ||
+ | Пусть <tex>P(A \rightarrow BC)</tex> - стоимость вывода по правилу <tex>A \rightarrow BC</tex>. Тогда, если использовать формулу <tex>d[A][i][j] = \min\limits_{A \rightarrow BC} \min\limits_{k = i}^{j-1} ( d[B][i][k] + d[C][k + 1][j] + P(A \rightarrow BC) )</tex>, то <tex>d[A][i][j]</tex> - минимальная стоимость вывода подстроки <tex>w[i \dots j]</tex> из нетерминала <tex>A</tex>. | ||
Таким образом, задача о выводе в КС-грамматике в нормальной форме Хомского является обобщением задачи динамического программирования на подотрезке. | Таким образом, задача о выводе в КС-грамматике в нормальной форме Хомского является обобщением задачи динамического программирования на подотрезке. | ||
Строка 39: | Строка 42: | ||
'''for''' i = 1 ... n | '''for''' i = 1 ... n | ||
'''for''' (A <tex>\rightarrow</tex> w[i] <tex>\in</tex> <tex>\Gamma</tex>) | '''for''' (A <tex>\rightarrow</tex> w[i] <tex>\in</tex> <tex>\Gamma</tex>) | ||
− | d[A][i][i] = true | + | d[A][i][i] = ''true'' |
'''for''' m = 1 .. n - 1 | '''for''' m = 1 .. n - 1 | ||
'''for''' i = 1 .. n - m | '''for''' i = 1 .. n - m | ||
Строка 51: | Строка 54: | ||
Обработка правил вида <tex>A \rightarrow w[i]</tex> в шаге 1 выполняется за <tex>O(n \cdot |\Gamma|)</tex>. | Обработка правил вида <tex>A \rightarrow w[i]</tex> в шаге 1 выполняется за <tex>O(n \cdot |\Gamma|)</tex>. | ||
− | Проход по всем подстрокам выполняется за <tex>O(n^2)</tex>. В обработке подстроки присутствует цикл по всем правилам вывода и по всем разбиениям на две подстроки, следовательно обработка работает за <tex>O(n \cdot |\Gamma|)</tex>. В итоге получаем конечную сложность <tex>O(n^3 \cdot |\Gamma|)</tex>. | + | Проход по всем подстрокам в шаге 2 выполняется за <tex>O(n^2)</tex>. В обработке одной подстроки присутствует цикл по всем правилам вывода и по всем разбиениям на две подстроки, следовательно обработка работает за <tex>O(n \cdot |\Gamma|)</tex>. В итоге получаем конечную сложность <tex>O(n^3 \cdot |\Gamma|)</tex>. |
Следовательно, общее время работы алгоритма - <tex>O(n^3 \cdot |\Gamma|)</tex>. Кроме того, алгоритму требуется память (на массив <tex>d</tex>) объемом <tex>O(n^2 \cdot |N|)</tex>, где <tex>|N|</tex> - количество [[Формальные_грамматики#Определения|нетерминалов]] грамматики. | Следовательно, общее время работы алгоритма - <tex>O(n^3 \cdot |\Gamma|)</tex>. Кроме того, алгоритму требуется память (на массив <tex>d</tex>) объемом <tex>O(n^2 \cdot |N|)</tex>, где <tex>|N|</tex> - количество [[Формальные_грамматики#Определения|нетерминалов]] грамматики. |
Версия 23:32, 4 ноября 2014
Задача: |
Пусть дана контекстно-свободная грамматика грамматика в нормальной форме Хомского и слово . Требуется выяснить, выводится ли это слово в данной грамматике. |
Содержание
Алгоритм
Алгоритм Кока-Янгера-Касами (Cocke — Younger — Kasami algorithm, CYK - алгоритм) - универсальный алгоритм, позволяющий по слову узнать, выводимо ли оно в заданной КС-грамматике в нормальной форме Хомского. Будем решать задачу динамическим программированием. Заведем трехмерный массив d, состоящий из логических значений, и тогда и только тогда, когда из нетерминала правилами грамматики можно вывести подстроку .
Рассмотрим все пары
, где - константа и .Шаг 1. База
. В таком случае .
Инициализируем массив для всех нетерминалов, из которых выводится какой-либо символ строки
. В таком случае:- , если в грамматике присутствует правило . Иначе .
Шаг 2. Переход
.
Значения для всех нетерминалов и пар
уже вычислены, поэтому . То есть, подстроку можно вывести из нетерминала , если существует продукция вида и такое , что подстрока выводима из , а подстрока - из .Завершение
После окончания работы значение
содержит ответ на вопрос, выводима ли данная строка в данной грамматике.Модификации
Количество способ вывести слово
Если массив будет хранить целые числа, а формулу заменить на
, то - количество способов получить подстроку из нетерминала .Минимальная стоимость вывода слова
Пусть
- стоимость вывода по правилу . Тогда, если использовать формулу , то - минимальная стоимость вывода подстроки из нетерминала .Таким образом, задача о выводе в КС-грамматике в нормальной форме Хомского является обобщением задачи динамического программирования на подотрезке.
Псевдокод
boolean CYK(char[] w, list, int S) int n = length(w) boolean d[ ][n][n] for i = 1 ... n for (A w[i] ) d[A][i][i] = true for m = 1 .. n - 1 for i = 1 .. n - m int j = i + m for (A BC ) for k = i .. j - 1 d[A][i][j] = d[A][i][j] or d[B][i][k] and d[C][k + 1][j] return d[S][1][n]
Асимптотика
Обработка правил вида
в шаге 1 выполняется за .Проход по всем подстрокам в шаге 2 выполняется за
. В обработке одной подстроки присутствует цикл по всем правилам вывода и по всем разбиениям на две подстроки, следовательно обработка работает за . В итоге получаем конечную сложность .Следовательно, общее время работы алгоритма - нетерминалов грамматики.
. Кроме того, алгоритму требуется память (на массив ) объемом , где - количество