*<tex>\mathtt{Involved}</tex> {{---}} список из номеров классов, содержащихся во множестве <tex>T'</tex>,
*<tex>\mathtt{Count}</tex> {{---}} целочисленный массив, где <tex>\mathtt{Count}[i]</tex> хранит количество состояний из класса <tex>i</tex>, которые содержатся в <tex>\mathtt{Inverse}</tex>,
*<tex>\mathtt{Reversed}</tex> {{---}} массив булеан, <tex>\mathtt{Reversed}[i] == </tex> ''true'', если требуется добавлять состояния из <tex>\mathtt{Inverse}</tex> в исходный класс <tex>i</tex>, а не в новый класс (<tex>\mathtt{Twin}[i]</tex>),
*<tex>\mathtt{Twin}</tex> {{---}} массив, хранящий в <tex>\mathtt{Twin}[i]</tex> номер нового класса, образовавшегося при разбиении класса <tex>i</tex>,
*<tex>\mathtt{Used}</tex> {{---}} массив булеан, <tex>\mathtt{Used}[r] == </tex> ''true'', если состояние <tex>r</tex> попало в <tex>\mathtt{Inverse}</tex>
<tex>\mathtt{findEquivalenceClasses}(Q,\ F,\ \delta)</tex>:
<tex>i = \mathtt{Class}[r]</tex>
'''if''' <tex>\mathtt{Count}[i] == 0</tex>
'''insert''' <tex>i</tex> '''ininto''' <tex>\mathtt{Involved}</tex>
<tex>\mathtt{Count}[i]++</tex>
<tex>\mathtt{Used}[r] = </tex> ''true''
'''for''' <tex> i \in \mathtt{Involved}</tex>
'''if''' <tex>\mathtt{Count}[i] < |\mathtt{P}[i]|</tex>
'''insert''' <tex>\{\}</tex> '''into''' <tex>\mathtt{P}</tex> <font color=darkgreen>//Создадим пустой класс в разбиении <tex>\mathtt{P}</tex></font>
<tex>\mathtt{Twin}[i]} = |\mathtt{P}|</tex> <font color=darkgreen>//Запишем в <tex>\mathtt{Twin[i]}</tex> индекс нового класса</font> '''if''' <tex>\mathtt{Count}[i] > |\mathtt{P}[i]|/2</tex> <tex>\mathtt{Reversed}[i] = </tex> ''true''
'''for''' <tex>q \in C</tex> '''and''' <tex>r \in \mathtt{Inv}[q][a]</tex>
<tex>i = \mathtt{Class}[r]</tex>
'''if''' <tex>j = \mathtt{Twin}[i] </tex> '''if''' <tex>j \neq 0</tex> '''ifremove''' <tex>r</tex> '''from''' <tex>\lnot \mathtt{ReversedP}[i]</tex> '''add''' <tex>\mathtt{move}(r,\ i,\ \mathtt{Twin}[i])</tex> '''to''' <tex>\mathtt{UsedP}[rj] = </tex> ''false''
'''for''' <tex> i \in \mathtt{Involved}</tex>
'''if''' <tex> j = \mathtt{Twin}[i] \neq 0 </tex> '''if''' <tex>j \mathtt{Reversed}[i]neq 0 </tex> '''forif''' <tex> r |\in mathtt{P}[j]| > |\mathtt{P}[i] |</tex> <font color=darkgreen>//Парный класс должен быть меньшего размера</font> '''if''' <tex>\lnot mathtt{swap}(\mathtt{UsedP}[ri],\ \mathtt{P}[j])</tex> <font color=darkgreen>//swap за O(1) - просто переставить указатели</font> '''for''' <tex>\mathtt{move}(r,\ i,\ in \mathtt{TwinP}[ij])</tex> <font color=darkgreen>//Обновляем номера классов для вершин, у которых они изменились</font> <tex>\mathtt{UsedClass}[r] = j</tex> ''false'' '''for''' <tex>c \in \Sigma</tex> '''push''' <tex>\langle \mathtt{Twin}[i]j, c \rangle</tex> '''to''' <tex>\mathtt{Queue}</tex>
<tex>\mathtt{Count}[i] = 0</tex>
<tex>\mathtt{Reversed}[i] = </tex> ''false''
<tex>\mathtt{Twin}[i] = 0</tex>
'''return''' <tex>\mathtt{P}</tex>
<tex>\mathtt{move}(r,\ i,\ j)</tex>:
'''remove''' <tex>r</tex> '''from''' <tex>\mathtt{P}[i]</tex>
'''add''' <tex>r</tex> '''to''' <tex>\mathtt{P}[j]</tex>
<tex>\mathtt{Class}[r] = j</tex>
Стоит отметить, что массивы <tex>\mathtt{Count},\ \mathtt{Twin},\ \mathtt{Used},\ \mathtt{Reversed}</tex> аллоцируются ровно один раз при инициализации алгоритма.
Когда мы вычислили массив <tex>\mathtt{Count}</tex>, мы смотрим, какая часть класса <tex>i</tex> больше и помечаем (<tex>\mathtt{Reversed}[i] = </tex> ''true''), когда больше часть, состоящая из состояний множества <tex>\mathtt{Inverse}</tex>. Далее, смотря на эту пометку, мы заполняем класс <tex>\mathtt{Twin}</tex> либо состояниями из <tex>\mathtt{Inverse}</tex>, либо всеми остальными. Благодаря такой стратегии, в новом классе <tex>\mathtt{Twin}[i]</tex> будет гарантировано меньше вершин, чем в <tex>i</tex>. Пары с этим подклассом потому и следует добавлять в очередь. Причем, Также стоит отметить, что собственно наличие/отсутствие пары в очереди можно не проверять. Если для некоторого <tex>c</tex> пара <tex>\langle i, c \rangle</tex> уже была в очереди, то мы добавим её "вторую половинку" <tex>\langle \mathtt{Twin}[i], c \rangle</tex>. Если её в очереди не было, то мы вольны сами выбирать, какой подкласс добавлять в очередь, и таким образом добавляем опять же <tex>\langle \mathtt{Twin}[i], c \rangle</tex>.Кроме того, вместо очереди можно использовать вообще произвольную струтуру, хранящую элементы, в том числе стэк, множество, т.к. порядок извлечения нам по сути не важен.
===Время работы===
'''insert''' <tex>\langle F,\ c \rangle</tex>, <tex>\langle Q \setminus F,\ c \rangle</tex> '''into''' <tex> \mathtt{Queue}</tex>
'''while''' <tex>\mathtt{Queue} \ne \varnothing</tex>
<tex>\langle C,\ a \rangle</tex> <tex>\leftarrow</tex> '''take any pop from''' <tex>\mathtt{Queue}</tex> <font color=darkgreen>//Взять любую пару из <tex>\mathtt{Queue}</tex>, не удаляя (!)</font>
<tex>\mathtt{Involved} = \{\}</tex>
'''for''' <tex>q \in C</tex> '''and''' <tex>r \in \mathtt{Inv}[q][a]</tex>
<tex>j = |\mathtt{P}|</tex> <font color=darkgreen>//Запишем в <tex>j</tex> индекс нового класса</font>
'''for''' <tex>r</tex> '''in''' <tex>\mathtt{Involved}[i]</tex>
'''remove''' <tex>r</tex> '''from''' <tex>\mathtt{P}[i]</tex> '''add''' <tex>r</tex> '''to''' <tex>\mathtt{P}[j]</tex> '''if''' <tex>|\mathtt{InvolvedP}[ij]| \leqslant > |\mathtt{P}[i]|</2tex> <font color=darkgreen>/tex/Парный класс должен быть меньшего размера</font> <tex>\mathtt{moveswap}(r,\ mathtt{P}[i],\ \mathtt{P}[j])</tex> <font color=darkgreen>//swap за O(1) - просто переставить указатели</font> '''elsefor'''<tex>r \in \mathtt{P}[j]</tex> <font color=darkgreen>//Обновляем номера классов для вершин, у которых они изменились</font> <tex>\mathtt{moveClass}([r,\ ] = j,\ i)</tex>
'''for''' <tex>c \in \Sigma</tex>
'''push''' <tex>\langle j, c \rangle</tex> '''into''' <tex>\mathtt{Queue}</tex>
'''remove''' <tex>\langle C,\ a \rangle</tex> '''from''' <tex> \mathtt{Queue}</tex>
'''return''' <tex>\mathtt{P}</tex>
<tex>\mathtt{move}(r,\ i,\ j)</tex>:
'''remove''' <tex>r</tex> '''from''' <tex>\mathtt{P}[i]</tex>
'''add''' <tex>r</tex> '''to''' <tex>\mathtt{P}[j]</tex>
<tex>\mathtt{Class}[r] = j</tex>
== См. также ==