Изменения

Перейти к: навигация, поиск

Алгоритм Хопкрофта

823 байта добавлено, 13:02, 8 декабря 2013
Модификация
Чтобы эффективно находить множество <tex>Inverse</tex>, построим массив <tex>Inv</tex>, который для состояния <tex>r</tex> и символа <tex>a</tex> в <tex>Inv[r][a]</tex> хранит множество состояний, из которых существует переход в <tex>r</tex> по символу <tex>a</tex>. Так как наш алгоритм не меняет изначальный автомат, то массив <tex>Inv</tex> можно построить перед началом основной части алгоритма, что займет <tex>O(|\Sigma| |Q|)</tex> времени.
Теперь научимся за <tex>O(|Inverse|)</tex> обрабатывать множество <tex>T'</tex> и разбивать классы. Для этого нам понадобится следующая структура:*<tex>Involved</tex> {{---}} список из номеров классов, содержащихся во множестве <tex>T'</tex>;*<tex>Size</tex> {{---}} целочисленный массив, где <tex>Size[i]</tex> хранит количество состояний из класса <tex>i</tex>, которые содержатся в <tex>Inverse</tex>;*<tex>Twin</tex> {{---}} массив, хранящий в <tex>Twin[i]</tex> номер нового класса, образовавшегося при разбиении класса <tex>i</tex>.  Для быстрой проверки, находится ли пара <tex>(C,a)</tex> в очереди <tex>S</tex>, будем использовать массив <tex>InListInQueue</tex> размера <tex>|Q| \times |\Sigma|</tex>, где <tex>InListInQueue[C][a] = true</tex>, если пара <tex>(C,a)</tex> содержится в очереди. Так как при разбиении очередного класса <tex>R</tex> на подклассы <tex>R_1</tex> и <tex>R_2</tex> мы в действительности создаем лишь один новый класс, то замена класса <tex>R</tex> в очереди на подклассы, образовавшиеся при разбиении, сводится лишь к взаимодействию с массивом <tex>InListInQueue</tex>. В итоге работа с очередью на каждой итерации требует <tex>O(1)</tex> времени.
===Время работы===
403
правки

Навигация