Минимизация ДКА, алгоритм Хопкрофта (сложность O(n log n)) — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
Строка 12: Строка 12:
 
Первый класс состоит из состояния <tex>A</tex>, а второй из эквивалентных состояний <tex>B</tex> и <tex>C</tex>.
 
Первый класс состоит из состояния <tex>A</tex>, а второй из эквивалентных состояний <tex>B</tex> и <tex>C</tex>.
 
= Алгоритм =
 
= Алгоритм =
Алгоритм итеративно строит разбиение множества состояний следующим образом.
+
Итеративно строим разбиение множества состояний следующим образом.
 
# Первоначальное разбиение множества состояний {{---}} класс допускающих состояний и класс недопускающих состояний.
 
# Первоначальное разбиение множества состояний {{---}} класс допускающих состояний и класс недопускающих состояний.
# Алгоритм помещает оба эти класса в очередь.
+
# Меньший из них помещается в очередь.
 
# Из очереди извлекается класс, далее именуемый как сплиттер.
 
# Из очереди извлекается класс, далее именуемый как сплиттер.
 
# Перебираются все символы из алфавита <tex>\Sigma</tex>, где <tex>c</tex> {{---}} текущий символ.
 
# Перебираются все символы из алфавита <tex>\Sigma</tex>, где <tex>c</tex> {{---}} текущий символ.
Строка 27: Строка 27:
 
<tex>P</tex> {{---}} разбиение множества состояний ДКА.
 
<tex>P</tex> {{---}} разбиение множества состояний ДКА.
 
<tex>R</tex> {{---}} класс состояний ДКА.
 
<tex>R</tex> {{---}} класс состояний ДКА.
   <tex>W \leftarrow \{ F, Q \setminus F \}</tex>
+
   if <tex> |F| \le |Q \setminus F|</tex>
 +
      <tex>W</tex>.push(<tex>F</tex>)
 +
    else
 +
      <tex>W</tex>.push(<tex>Q \setminus F</tex>)
 
   <tex>P \leftarrow \{ F, Q \setminus F \}</tex>
 
   <tex>P \leftarrow \{ F, Q \setminus F \}</tex>
 
   while not <tex>W</tex>.isEmpty()  
 
   while not <tex>W</tex>.isEmpty()  
Строка 37: Строка 40:
 
         if <tex> |R_1| \ne 0</tex> and <tex>|R_2| \ne 0</tex>
 
         if <tex> |R_1| \ne 0</tex> and <tex>|R_2| \ne 0</tex>
 
           replace <tex>R</tex> in <tex>P</tex> with <tex>R_1</tex> and <tex>R_2</tex>
 
           replace <tex>R</tex> in <tex>P</tex> with <tex>R_1</tex> and <tex>R_2</tex>
            if <tex> |R_1| \le |R_2|</tex>
+
          if <tex>R</tex> in <tex>W</tex>
               <tex>W</tex>.push(<tex>R_1</tex>)
+
               replace <tex>R</tex> in <tex>W</tex> with <tex>R_1</tex> and <tex>R_2</tex>
 
             else
 
             else
               <tex>W</tex>.push(<tex>R_2</tex>)
+
               if <tex> |R_1| \le |R_2|</tex>
 +
                  <tex>W</tex>.push(<tex>R_1</tex>)
 +
                else
 +
                  <tex>W</tex>.push(<tex>R_2</tex>)
  
 
==Время работы алгоритма==
 
==Время работы алгоритма==

Версия 23:57, 13 февраля 2012

Постановка задачи

Пусть дан автомат, распознающий определенный язык. Требуется найти эквивалентный автомат с наименьшим количеством состояний.

Минимизация ДКА

Понятие эквивалентности состояний позволяет объединить состояния в классы следующим образом.

  1. Все состояния в классе эквивалентны.
  2. Любые два состояния, выбранные из разных класов, неэквивалентны.

Таким образом, основная идея минимизации ДКА состоит в разбиении множества состояний на классы эквивалентности.

Пример минимизации ДКА

Automaton1.pngAutomaton2.png

Первый класс состоит из состояния [math]A[/math], а второй из эквивалентных состояний [math]B[/math] и [math]C[/math].

Алгоритм

Итеративно строим разбиение множества состояний следующим образом.

  1. Первоначальное разбиение множества состояний — класс допускающих состояний и класс недопускающих состояний.
  2. Меньший из них помещается в очередь.
  3. Из очереди извлекается класс, далее именуемый как сплиттер.
  4. Перебираются все символы из алфавита [math]\Sigma[/math], где [math]c[/math] — текущий символ.
  5. Все классы текущего разбиения разбиваются на 2 подкласса (один из которых может быть пустым). Первый состоит из состояний, которые по символу [math]c[/math] переходят в сплиттер, а второй из всех оставшихся.
  6. Те классы, которые разбились на два непустых подкласса, заменяются этими подклассами в разбиении, а также меньший из двух подклассов добавляется в очередь.
  7. Пока очередь не пуста, алгоритм выполняет п.3 – п.6.

Псевдокод

[math]Q[/math] — множество состояний ДКА. [math]F[/math] — множество терминальных состояний. [math]W[/math] — очередь. [math]P[/math] — разбиение множества состояний ДКА. [math]R[/math] — класс состояний ДКА.

 if [math] |F| \le |Q \setminus F|[/math]
     [math]W[/math].push([math]F[/math])
   else
     [math]W[/math].push([math]Q \setminus F[/math])
 [math]P \leftarrow \{ F, Q \setminus F \}[/math]
 while not [math]W[/math].isEmpty() 
   [math]W[/math].pop([math]S[/math])
   for all [math]a \in \Sigma[/math]
     for all [math]R[/math] in [math]P[/math] 
       [math]R_1 = R \cap \delta^{-1} (S, a) [/math]
       [math]R_2 = R \setminus R_1[/math]
       if [math] |R_1| \ne 0[/math] and [math]|R_2| \ne 0[/math]
         replace [math]R[/math] in [math]P[/math] with [math]R_1[/math] and [math]R_2[/math]
         if [math]R[/math] in [math]W[/math]
             replace [math]R[/math] in [math]W[/math] with [math]R_1[/math] and [math]R_2[/math]
           else
             if [math] |R_1| \le |R_2|[/math]
                 [math]W[/math].push([math]R_1[/math])
               else
                 [math]W[/math].push([math]R_2[/math])

Время работы алгоритма

Благодаря системе добавления классов состояний в очередь, каждое ребро будет рассмотрено не более чем [math]\log{n}[/math] раз. А так как ребер у нас порядка [math] |\Sigma| * n [/math] то получаем [math] O(n\log{n})[/math]

Литература

  • Хопкрофт Д., Мотвани Р., Ульман Д. Введение в теорию автоматов, языков и вычислений, 2-е изд. : Пер. с англ. — М.: Издательский дом «Вильямс», 2002. — С. 177 — ISBN 5-8459-0261-4 (рус.)
  • J. E. Hopcroft. An n log n algorithm for minimizing states in a finite automaton. Technical Report CS-71-190, Stanford University, January 1971.