Test GR: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Rogoda (dyskusja | edycje)
Rogoda (dyskusja | edycje)
Linia 168: Linia 168:
Nowo obliczona relacja <math>\overline \rho_i</math> albo podzieli jedną lub kilka klas abstrakcji relacji <math>\overline \rho_{i-1}</math>, albo będzie identyczna z relacją <math>\overline \rho_{i-1}</math>. Jeśli zajdzie ta druga sytuacja, to znaczy, że dla każdego <math>j>i</math> w oczywisty sposób spełniona jest równość <math>\overline \rho_j=\overline \rho_i</math>, czyli ciąg relacji ustabilizuje się. W tym momencie algorytm kończy swoje działanie i klasy abstrakcji relacji <math>\overline \rho_i</math> będą reprezentować stany automatu minimalnego.
Nowo obliczona relacja <math>\overline \rho_i</math> albo podzieli jedną lub kilka klas abstrakcji relacji <math>\overline \rho_{i-1}</math>, albo będzie identyczna z relacją <math>\overline \rho_{i-1}</math>. Jeśli zajdzie ta druga sytuacja, to znaczy, że dla każdego <math>j>i</math> w oczywisty sposób spełniona jest równość <math>\overline \rho_j=\overline \rho_i</math>, czyli ciąg relacji ustabilizuje się. W tym momencie algorytm kończy swoje działanie i klasy abstrakcji relacji <math>\overline \rho_i</math> będą reprezentować stany automatu minimalnego.


{{algorytm|MinHopcroft - algorytm Hopcrofta minimalizacji automatu|algorytm Hopcrofta minimalizacji automatu|
{{algorytm|Minimalizuj2 - algorytm minimalizacji automatu wykorzystujący stabilizujący się ciąg relacji|algorytm minimalizacji automatu wykorzystujący stabilizujący się ciąg relacji|
   1  Wejście: <math>\mathcal{A}=(S, A, f, s_0, T)</math> - automat taki, że <math>L=L(\mathcal{A})</math>
   1  Wejście: <math>\mathcal {A} = (S, A, f, s_0, T)</math> - automat taki, że <math>L = L(\mathcal{A})</math>
   2  Wyjście: <math>P</math> - podział zbioru <math>S</math> przez prawą kongruencję automatową
   2  Wyjście: automat minimalny <math>\mathcal{A}' = (S',A',f', s_0',
   3  <math>P \leftarrow \{T, S \backslash T\}</math>;           <math>\triangleright</math><math>P</math> jest zbiorem rozłącznych podzbiorów <math>S</math>
T')</math> dla <math>\mathcal{A}</math>
   4  '''if''' <math>|T|<|S \backslash T|</math> '''for'''
   3  <math>\overline \rho_1 \leftarrow \approx_ \mathcal{A}</math>;
   5   '''for''' '''each '''<math>a \in A</math> '''do'''  
   4  <math>i \leftarrow 1</math>;
   5 '''repeat'''  
   6      '''włóż'''<math>(\mathcal{L}, (T, a))</math>;   
   6      '''włóż'''<math>(\mathcal{L}, (T, a))</math>;   
   7    '''end''' '''for'''
   7    '''end''' '''for'''
Linia 198: Linia 199:
   27        '''else'''
   27        '''else'''
   28          '''włóż'''<math>(\mathcal{L},(X_2,b))</math>;  
   28          '''włóż'''<math>(\mathcal{L},(X_2,b))</math>;  
   29         '''end''' '''if'''
   29  '''return'''
  30      '''end''' '''if'''
 
  31    '''end''' '''for'''
  32  '''end''' '''for'''
  33 '''end''' '''while'''
  34  '''return'''
}}
}}



Wersja z 13:47, 16 sie 2006

W tym wykładzie podamy algorytmy konstrukcji automatu minimalnego i twierdzenia dowodzące ich poprawności.

Algorytmy konstrukcji automatu minimalnego

Dla języka rozpoznawanego L konstrukcję automatu minimalnego można rozpocząć, startując z opisu języka danego na przykład przez wyrażenie regularne lub też jakiegoś automatu rozpoznającego ten język. W niniejszym wykładzie przedstawimy algorytmy konstrukcji automatu minimalnego obejmujące oba wspomniane punkty startu. Jako pierwszy, nawiązując do rezulatów przedstawionych w poprzednim wykładzie, prezentujemy algorytm, dla którego punktem wyjścia jest język L. Prezentację poprzedzimy wprowadzeniem pewnej operacji na słowach zwanej pochodną J.Brzozowskiego.

Definicja 1.1.

Niech LA* będzie dowolnym językiem, a uA* dowolnym słowem. Pochodną Brzozowskiego (residuum) z języka L względem słowa u nazywamy język

u1L={wA*:uwL}.

Podczas obliczeń pochodnych Brzozowskiego (residuów języka L) można wykorzystać poniższe równości.

Niech L1,L2A* będą dowolnymi językami, aA dowolną literą, a u,vA* dowolnymi słowami. Prawdziwe są następujące równości:

Parser nie mógł rozpoznać (nieznana funkcja „\nonumber”): {\displaystyle \begin{array}{rll}\nonumber u^{-1}(L_1 \cup L_2) & = & u^{-1}L_1 \cup u^{-1}L_2, \\ \nonumber u^{-1}(L_1 \backslash L_2) & = & u^{-1}L_1 \backslash u^{-1}L_2, \\ \nonumber u^{-1}(L_1 \cap L_2) & = & u^{-1}L_1 \cap u^{-1}L_2, \\ \nonumber a^{-1}(L_1L_2) & = & (a^{-1}L_1)L_2 \mbox{, jeśli } 1 \notin L_1, \\ \nonumber a^{-1}(L_1L_2) & = & (a^{-1}L_1)L_2 \cup a^{-1}L_2 \mbox{, jeśli } 1 \in L_1, \\ \nonumber a^{-1}L^* & = & (a^{-1}L)L^*, \\ \nonumber v^{-1}(u^{-1}L) & = & (uv)^{-1}L. \end{array}}

Przykład 1.1.

Obliczmy wszystkie pochodne dla języka L=a+b+. Okazuje się, że są tylko cztery różne pochodne liczone względem a, b, ab i słowa pustego 1. Mianowicie:
a1L=a*b+,
b1L=,
ab1L=b*,
11L=L.
Dla wszystkich innych słów otrzymujemy uzyskane powyżej języki, co wynika z własności pochodnych (patrz wyżej wypisane równości) i z następujacych obliczeń:
n(an)1L=a*b+,
n(bn)1L=,
n(abn)1L=b*.

Zauważmy również, nawiązując raz jeszcze do rezulatów przedstawionych w poprzednim wykładzie, że prawdziwa jest następująca równoważność wiążąca wprowadzone pojęcie pochodnej Brzozowskiego z prawą kongruencją syntaktyczną:

uPrLvu1L=v1L.

Rozpisując z definicji lewą stronę tej równoważności, otrzymujemy, iż dla dowolnego słowa zA* słowo uzL wtedy i tylko wtedy, gdy vzL. A to równoważnie oznacza (znów z definicji), że u1L=v1L.

Z uzasadnionej równoważności oraz twierdzenia 3.4 o prawej kongruencji syntaktycznej z poprzedniego wykładu wnioskujemy równoważność rozpoznawalności języka L i skończonej ilości różnych pochodnych Brzozowskiego tego języka.

Pierwszy z przedstawianych algorytmów będzie konstruował automat minimalny, wyznaczając prawą kongruencję automatową poprzez zastosowanie metody pochodnych Brzozowskiego. Metoda ta umożliwia przeprowadzanie odpowiednich obliczeń bezpośrednio na wyrażeniach regularnych. Ogólny opis algorytmu jest następujący. Stany konstruowanego automatu minimalnego etykietowane są zbiorami odpowiadającymi pewnym językom. Mając dany język L, ustanawiamy stan początkowy automatu jako L, wpisujemy go na listę i obliczamy a1L dla każdej litery aA. Jeśli wśród obliczonych wartości znajduje się język niewystępujący na liście, dodajemy go do listy. Obliczenia pochodnych Brzozowskiego wykonujemy, dopóki będziemy uzyskiwać nowe języki (nowe stany). Funkcja przejść konstruowanego automatu minimalnego zdefiniowana jest następująco:

f(X,a)=a1X,

gdzie

X

jest pewnym językiem z listy

.

Obliczone języki określają stany automatu minimalnego.

Uwaga [Dla zainteresowanych]

Obliczone języki określające stany automatu minimalnego to elementy monoidu syntaktycznego języka L.

Automatem minimalnym dla automatu 𝒜=(S,A,f,s0,T) będzie zatem automat

𝒜L=(SL,A,fL,s0L,TL),

gdzie:

  • SL={u1L: uA*},
  • s0L=L,
  • TL={u1L: uL},
  • fL(u1L,a)=a1(u1L)=(ua)1L.

Jeśli zdefiniujmy odwzorowanie ν:SSL, kładąc:

ν(s)=u1L, gdzie s=f(s0,u),

to można dowieść, że ν jest dobrze określone, jest epimorfizmem oraz ν(s0)=s0L - porównaj twierdzenie 3.1 z wykładu 4. Prawdą jest też, iż sT wtedy i tylko wtedy, gdy ν(s)TL oraz że następujący diagram komutuje:

Parser nie mógł rozpoznać (nieznana funkcja „\beginCD”): {\displaystyle \beginCD s @>{a}>> s' @. \ \ \ \ \mbox{ w } \mathcal{A} \\ @V{\nu}VV @V{\nu}VV \\ u^{-1}L @>{a}>> (ua)^{-1}L @. \ \ \ \ \mbox{ w } \mathcal{A}_L. \endCD }

Formalny zapis algorytmu przedstawiony jest poniżej.

Algorytm Minimalizuj1 - algorytm minimalizacji wykorzystujący pochodne Brzozowskiego


 1  Wejście: 𝒜=(S,A,f,s0,T) - automat taki, że L=L(𝒜)
 2  Wyjście: automat minimalny 𝒜=(SL,A,fL,sL,TL) dla 𝒜SL{L};
 3  SL{L}
 4  włóż(,L);
 5  while  do 
 6    M zdejmij();   
 7    for each aA do 
 8      Na1M;
 9      if NSL= then
 10       SLSL{N};
 11       włóż(,N);
 12     end if
 13    end for
 14  end  while  
 15  for each MSL do
 16    for each aA do
 17      fL(M,a)a1M;
 18    end for
 19  end for
 20  sLL;
 21  TL{u1L: uL};
 22  return 𝒜;


Funkcja zdejmij(), występująca w linii 6., zdejmuje z kolejki pierwszy element i zwraca go jako swoją wartość. Procedura włóż(,L), występująca w liniach 4. oraz 11., wstawia na koniec kolejki element L.

Przykład 1.2.

Dla języka L=a+b+ z przykładu 1.1 w wyniku działania powyższego algorytmu otrzymamy czterostanowy automat 𝒜L=(SL,A,f,L,T), gdzie
SL={L,a*b+,,b*},
a funkcja przejść zadana jest grafem:

RYSUNEK ja-lekcja5-w-rys1

Prezentowane poniżej twierdzenie uzasadnia kolejny algorytm konstrukcji automatu minimalnego. Tym razem punktem wyjścia jest dowolny automat rozpoznający język L.

Uwaga [Dla zainteresowanych]

Algorytm oblicza również monoid syntaktyczny języka L.

Analogicznie do konstrukcji relacji ρi, przedstawionej w wykładzie 4, możemy określić ciąg odpowiednich relacji na zbiorze stanów dowolnego automatu rozpoznającego język L. Relacje te służą do efektywnego określenia automatu minimalnego, równoważnego zadanemu.

Twierdzenie 1.1.

Niech 𝒜=(S,A,f,s0,T) będzie dowolnym automatem i niech L=L(𝒜). Przez 𝒜S×S oznaczmy relację równoważności zawierającą dwie klasy równoważności T i ST. Przez ρi dla i oznaczmy zstępujący ciąg relacji określony następująco:

ρ1=𝒜, a dla i=2,... przyjmijmy

ρi={(s,t)S×S:aA{1}f(s,a)ρi1f(t,a)}..

Wtedy ρi jest największą prawą kongruencją automatową zawartą w relacji ρ1=𝒜 i automat minimalny ma postać

𝒜L=(S/ρi,A,f*,[s0],T/ρi).

Dowód tego twierdzenia przebiega analogicznie do dowodu twierdzenia 3.3 z wykładu 4.

Algorytm działajacy w oparciu o powyższe twierdzenie na podstawie zadanego automatu A=(S,A,f,s0,T), konstruuje efektywnie automat minimalny dla 𝒜, obliczając ciąg relacji ρ1. Proces konstrukcji przebiega w sposób iteracyjny. Zaczynamy od zdefiniowania relacji Parser nie mógł rozpoznać (nieznana funkcja „\mathacal”): {\displaystyle \approx _\mathacal {A}} , która posiada tylko dwie klasy abstrakcji: do pierwszej z nich należą wszystkie stany końcowe, a do drugiej - wszystkie pozostałe stany. Tak więc

s,tS s𝒜t(sTtT)(sSTtST).

Definiujemy pierwszą z relacji ρ, czyli relację ρ1 jako równą 𝒜, a następnie, dla każdej obliczonej już relacji ρi1, obliczamy relację ρi w następujący sposób:

s1ρis2(s1ρi1s2)(aA f(s1,a)ρi1f(s2,a)).

Nowo obliczona relacja ρi albo podzieli jedną lub kilka klas abstrakcji relacji ρi1, albo będzie identyczna z relacją ρi1. Jeśli zajdzie ta druga sytuacja, to znaczy, że dla każdego j>i w oczywisty sposób spełniona jest równość ρj=ρi, czyli ciąg relacji ustabilizuje się. W tym momencie algorytm kończy swoje działanie i klasy abstrakcji relacji ρi będą reprezentować stany automatu minimalnego.

Algorytm Minimalizuj2 - algorytm minimalizacji automatu wykorzystujący stabilizujący się ciąg relacji


 1  Wejście: 𝒜=(S,A,f,s0,T) - automat taki, że L=L(𝒜)
 2  Wyjście: automat minimalny 𝒜=(S,A,f,s0,T) dla 𝒜
 3  ρ1𝒜;
 4  i1;
 5  repeat 
 6      włóż(,(T,a));   
 7    end for
 8  else 
 9    for each aA do
 10     włóż (,(ST,a));   
 11   end for
 12  end if
 13  while  do
 14   (Y,a) zdejmij ();
 15   Parser nie mógł rozpoznać (nieznana funkcja „\slash”): {\displaystyle \mathcal{X} \leftarrow \{X \in P:\ |X \slash \rho^a_Y| = 2\}}
;
 16   for each X𝒳 do 
 17     for each bA do
 18       Parser nie mógł rozpoznać (nieznana funkcja „\slash”): {\displaystyle \{X_1, X_2\} \leftarrow X \slash \rho^a_Y}
;       Parser nie mógł rozpoznać (nieznana funkcja „\slash”): {\displaystyle X \slash \rho^a_Y}
 zawiera dwie klasy abstrakcji
 19       P(PX)X1X2;
 20       if (X,b) then
 21         (X,b);             zdejmij z  dokładnie parę (X,b) 
 22         włóż(,(X1,b));
 23         włóż(,(X2,b));
 24       else  
 25         if |X1|<|X2| then
 26           włóż(,(X1,b));
 27         else
 28           włóż(,(X2,b)); 
 29  return



{{cwiczenie|[Uzupelnij]||

Zminimalizujemy automat </math>{A}=(S,A,f,s_0,T)Parser nie mógł rozpoznać (błąd składni): {\displaystyle , dla którego\\ } S= s_{0},s_{1},s_{2},s_{3},s_{4},s_5 , A=a,b,

T=s_1, s_{2},s_{4} Parser nie mógł rozpoznać (błąd składni): {\displaystyle , a funkcja przejść określona jest przy pomocy grafu.\\ RYSUNEK ja-lekcja5-w-rys2\\ Konstruujemy ciąg relacji } {}_iParser nie mógł rozpoznać (błąd składni): {\displaystyle . Na początku } {}_1

dzieli

SParser nie mógł rozpoznać (błąd składni): {\displaystyle na dwie klasy abstrakcji; pierwsza zawiera stany końcowe, a druga -- wszystkie pozostałe, czyli uzyskujemy dwa zbiory } s_1,s_2,s_4

oraz

s_0, s_3, s_5

.Obliczmy

{}_2Parser nie mógł rozpoznać (błąd składni): {\displaystyle (pierwszy przebieg pętli w liniach 5.-20. algorytmu). Aby dwa elementy (stany) } s

i

tParser nie mógł rozpoznać (błąd składni): {\displaystyle były ze sobą w relacji } {}_2Parser nie mógł rozpoznać (błąd składni): {\displaystyle muszą być ze sobą w relacji } {}_1Parser nie mógł rozpoznać (błąd składni): {\displaystyle oraz musi zachodzić } a A f(s, a) {}_1 f(t,a).

Parser nie mógł rozpoznać (błąd składni): {\displaystyle Czyli kolejna, nowa relacja może ewentualnie podzielić już istniejące zbiory zdefiniowane przez poprzednią relację. Nie może więc zajść taka sytuacja, że w jednej klasie abstrakcji relacji } {}_{i+1}Parser nie mógł rozpoznać (błąd składni): {\displaystyle znajdą się elementy z różnych klas abstrakcji relacji } {}_iParser nie mógł rozpoznać (błąd składni): {\displaystyle . Rozważmy najpierw zbiór } s_1, s_2, s_4Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Oczywiście każde dwa stany z tego zbioru są ze sobą w relacji } {}_1Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Zauważmy, że } f(s_2, a)=f(s_4,a)=s_2,f(s_2,b)=f(s_4,b)=s_4Parser nie mógł rozpoznać (błąd składni): {\displaystyle , więc } s_2 {}_2 s_4(bos_2 {}_1 s_2orazs_4 {}_1 s_4Parser nie mógł rozpoznać (błąd składni): {\displaystyle ). Ponieważ } f(s_1,b)=s_5if(s_2,b)=s_4Parser nie mógł rozpoznać (błąd składni): {\displaystyle , a wiemy, że } s_5niejestwrelacji{}_1zs_4,zatemstanys_1is_2Parser nie mógł rozpoznać (błąd składni): {\displaystyle nie mogą być ze sobą w relacji } {}_2Parser nie mógł rozpoznać (błąd składni): {\displaystyle , a to oznacza, że także stany } s_1is_4Parser nie mógł rozpoznać (błąd składni): {\displaystyle nie mogą być ze sobą w relacji } {}_2Parser nie mógł rozpoznać (błąd składni): {\displaystyle . W analogiczny sposób można sprawdzić, że relacja } {}_2niepodzielizbiorus_0, s_3, s_5Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Ostatecznie, po pierwszym wykonaniu pętli algorytmu minimalizacji obliczyliśmy relację } {}_2Parser nie mógł rozpoznać (błąd składni): {\displaystyle , która dzieli } SParser nie mógł rozpoznać (błąd składni): {\displaystyle na następujące podzbiory: }

s_1, s_2, s_4, s_0, s_3, s_5.

Wkolejnymkrokuobliczamy{}_3Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Zbiór } s_1Parser nie mógł rozpoznać (błąd składni): {\displaystyle oczywiście nie może być już podzielony na mniejsze podzbiory. Łatwo zauważyć, że } {}_3Parser nie mógł rozpoznać (błąd składni): {\displaystyle nie podzieli także zbioru } s_2,

s_4Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Rozważmy teraz zbiór } s_0, s_3, s_5.Mamyf(s_3, a)=f(s_5, a)orazf(s_3, b)=s_3,f(s_5, b)=s_5Parser nie mógł rozpoznać (błąd składni): {\displaystyle i wiadomo, że } s_3 {}_2

s_5,zatems_3is_5Parser nie mógł rozpoznać (błąd składni): {\displaystyle będą ze sobą w relacji } {}_3Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Ponieważ } f(s_0, a)=s_2if(s_3, a)=s_1,ales_2is_1Parser nie mógł rozpoznać (błąd składni): {\displaystyle nie są ze sobą w relacji } {}_2Parser nie mógł rozpoznać (błąd składni): {\displaystyle , zatem nie mogą być także ze sobą w relacji } {}_3.Relacja{}_3Parser nie mógł rozpoznać (błąd składni): {\displaystyle dzieli więc zbiór } s_0, s_3, s_5nazbiorys_0orazs_3, s_5Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Podział zbioru } SParser nie mógł rozpoznać (błąd składni): {\displaystyle przez relację } {}_3Parser nie mógł rozpoznać (błąd składni): {\displaystyle wygląda więc następująco: }

s_0, s_1, s_2, s_4, s_3, s_5.

Relacja{}_4Parser nie mógł rozpoznać (błąd składni): {\displaystyle nie podzieli już ani zbioru } s_2,

s_4,anizbiorus_3, s_5Parser nie mógł rozpoznać (błąd składni): {\displaystyle , więc uzyskujemy równość } {_4}={}_3Parser nie mógł rozpoznać (błąd składni): {\displaystyle i ponieważ ciąg relacji się ustabilizował, algorytm kończy działanie. Podsumowując, mamy:  ; } {} _{1}:s_1, s_{2},s_{4}, s_{0},s_{3},s_5, ;{} _{2}:s_{1},s_2,s_{4}, s_{0},s_{3},s_5,;{} _{3}:s_{1},s_2,s_{4}, s_{0},s_{3},s_5.{} _{3}={} _{4}Parser nie mógł rozpoznać (błąd składni): {\displaystyle i równoważny minimalny automat } {A}_L=(S,f^*,s_0,T)ma4Parser nie mógł rozpoznać (błąd składni): {\displaystyle stany. \\ } q_0=s_{0}, q_1=s_{1}, q_2 = s_2,s_{4}, q_3

=s_{3},s_5,T=q_1 ,q_2Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Jak łatwo zauważyć jest to automat z przykładu 3.1 zamieszczonego w wykładzie 4. RYSUNEK ja-lekcja5-w-rys3 }} Jednym z najczęściej stosowanych algorytmów automatu minimalnego jest algorytm, który buduje "tabelkę" na podstawie której określa się automat minimalny. Poprawność tego algorytmu również uzasadnia twierdzenie [[##twrho|Uzupelnic twrho|]]. W algorytmie tym wyznaczać będziemy tzw. stany rozróżnialne. Algorytm działa w czasie } O(|A|n^2),gdzie|A|Parser nie mógł rozpoznać (błąd składni): {\displaystyle jest mocą alfabetu, a } nParser nie mógł rozpoznać (błąd składni): {\displaystyle -- liczbą stanów automatu wejściowego, czyli podlegajacego minimalizacji. Złożoność pamięciowa jest również } O(|A|n^2)Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Prezentowany algorytm nosi nazwę algorytmu Hopcrofta-Ullmana. Znana w literaturze jest pewna zmodyfikowana wersja tego algorytmu. Jest to algorytm Aho-Sethiego-Ullmana, który ma tę samą złożoność czasową, ale lepszą złożoność pamięciową - } O(|A|n)Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Natomiast w ramach ćwiczeń prezentujemy jeszcze jeden algorytm, znany jako algorytm minimalizacji Hopcrofta. Czas działania tego algorytmu wynosi } O(n n)Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Niech będzie relacją zdefiniowaną przez funkcję przejść automatu w następujący sposób: }

p q w A^* (f(p,w) T f(q,w) T).

Parser nie mógł rozpoznać (nieznana funkcja „\begindefin”): {\displaystyle \begindefin Stany } piqParser nie mógł rozpoznać (błąd składni): {\displaystyle są równoważne, jeśli } p qParser nie mógł rozpoznać (nieznana funkcja „\enddefin”): {\displaystyle . \enddefin Jeśli stany nie są równoważne, to będziemy mówić, że są rozróżnialne. Zadaniem algorytmu jest wyznaczenie stanów równoważnych, celem ich utożsamienia ze sobą. Algorytm musi zdecydować, dla każdej pary stanów } (p,q)Parser nie mógł rozpoznać (błąd składni): {\displaystyle , czy są one rozróżnialne. Jeśli pod koniec działania algorytmu okaże się, że nie stwierdziliśmy rozróżnialności tych stanów, to znaczy, że są one równoważne; następuje ich utożsamienie, czyli "połączenie" ich w jeden stan. Gdy takiego połączenia dokonamy dla wszystkich par stanów, wobec których nie stwierdziliśmy ich rozróżnialności, powstanie automat o minimalnej liczbie stanów. W praktyce algorytm nie wyznacza stanów równoważnych, ale stany rozróżnialne, gdyż jest to po prostu łatwiejsze. Po wyznaczeniu wszystkich par stanów rozróżnialnych pozostałe pary stanowić będą stany równoważne. W algorytmie wykorzystywać będziemy tablicę list } {L}[p,q]Parser nie mógł rozpoznać (błąd składni): {\displaystyle , po jednej liście dla każdej pary stanów. Funkcja } initialize({L}[p,q])Parser nie mógł rozpoznać (błąd składni): {\displaystyle inicjalizuje listę pustą, funkcja } zdejmij({L}[p,q])Parser nie mógł rozpoznać (błąd składni): {\displaystyle zdejmuje jeden z elementów, natomiast funkcja } włóż({L}[p,q],x)Parser nie mógł rozpoznać (błąd składni): {\displaystyle wkłada element } xParser nie mógł rozpoznać (błąd składni): {\displaystyle na listę } {L}[p,q].Funkcjaempty({L}[p,q])Parser nie mógł rozpoznać (błąd składni): {\displaystyle zwraca wartość } truegdylistajestpusta,orazfalseParser nie mógł rozpoznać (błąd składni): {\displaystyle w przeciwnym wypadku. Zwróćmy uwagę, że elementami każdej z list } {L}[p,q]Parser nie mógł rozpoznać (błąd składni): {\displaystyle są pary stanów } (s,t) S SParser nie mógł rozpoznać (nieznana funkcja „\newpage”): {\displaystyle . \newpage \beginalgorithm \caption{\textsc{Minimalizuj3} -- algorytm minimalizacji wykorzystujący relację } \beginalgorithmic [1] \STATE Wejście: } {A}=(S, A, f, s_0, T)Parser nie mógł rozpoznać (nieznana funkcja „\STATE”): {\displaystyle -- automat \STATE Wyjście: } {A}'=(S', A, f', s_0', T')Parser nie mógł rozpoznać (błąd składni): {\displaystyle -- automat minimalny taki, że } L({A}')=L({A})Parser nie mógł rozpoznać (nieznana funkcja „\FOR”): {\displaystyle . \FOR{\textbf{each} } p TParser nie mógł rozpoznać (nieznana funkcja „\FOR”): {\displaystyle } \FOR{\textbf{each} } q S TParser nie mógł rozpoznać (nieznana funkcja „\STATE”): {\displaystyle } \STATE \textbf{zaznaczone}} [p,q] 1Parser nie mógł rozpoznać (nieznana funkcja „\STATE”): {\displaystyle ; \STATE \textbf{initialize}(} {L}[p,q]Parser nie mógł rozpoznać (nieznana funkcja „\ENDFOR”): {\displaystyle ) \ENDFOR \ENDFOR \FOR{} each(p,q) (T T) ((S T)

(S T))Parser nie mógł rozpoznać (nieznana funkcja „\STATE”): {\displaystyle } \STATE \textbf{zaznaczone}} [p,q] 0Parser nie mógł rozpoznać (nieznana funkcja „\ENDFOR”): {\displaystyle ; \ENDFOR \FOR{} each (p,q) (T T) ((S T) (S T))Parser nie mógł rozpoznać (nieznana funkcja „\STATE”): {\displaystyle } \STATE flag\textbf{false} \FOR{\textbf{each } } a AParser nie mógł rozpoznać (nieznana funkcja „\IF”): {\displaystyle } \IF{ \textbf{zaznaczone}} [f(p,a),f(q,a)]=1Parser nie mógł rozpoznać (nieznana funkcja „\STATE”): {\displaystyle } \STATE flag\textbf{true}; \ENDIF \ENDFOR \IF{flag=\textbf{true}} \STATE \textsc{Oznacz}} (p,q)Parser nie mógł rozpoznać (nieznana funkcja „\hfill”): {\displaystyle ;\hfill para } (f(p,a),f(q,a))Parser nie mógł rozpoznać (błąd składni): {\displaystyle była oznaczona dla pewnego } aParser nie mógł rozpoznać (nieznana funkcja „\ELSE”): {\displaystyle ; \ELSE \FOR{\textbf{each } } a AParser nie mógł rozpoznać (nieznana funkcja „\IF”): {\displaystyle } \IF{} f(p,a) f(q,a)Parser nie mógł rozpoznać (nieznana funkcja „\STATE”): {\displaystyle } \STATE \textbf{włóż}} ({L}[p,q],(f(p,a),f(q,a)))Parser nie mógł rozpoznać (nieznana funkcja „\ENDIF”): {\displaystyle ; \ENDIF \ENDFOR \ENDIF \ENDFOR \STATE } S' S _Parser nie mógł rozpoznać (nieznana funkcja „\hfill”): {\displaystyle ;\hfill relacja jest dopełnieniem tabeli } zaznaczoneParser nie mógł rozpoznać (nieznana funkcja „\FOR”): {\displaystyle \FOR{\textbf{each} } [s]_{ } S _Parser nie mógł rozpoznać (nieznana funkcja „\FOR”): {\displaystyle } \FOR{\textbf{each} } a AParser nie mógł rozpoznać (nieznana funkcja „\STATE”): {\displaystyle } \STATE } f'([s]_{},a) [f(s,a)]_{}Parser nie mógł rozpoznać (nieznana funkcja „\ENDFOR”): {\displaystyle ; \ENDFOR \ENDFOR \STATE } s_0' [s_0]_{}Parser nie mógł rozpoznać (nieznana funkcja „\STATE”): {\displaystyle ; \STATE } T' [t]_{}:t TParser nie mógł rozpoznać (nieznana funkcja „\RETURN”): {\displaystyle ; \RETURN } {A}'=(S', A, f', s_0', T')Parser nie mógł rozpoznać (nieznana funkcja „\endalgorithmic”): {\displaystyle ; \endalgorithmic \endalgorithm Występujaca w algorytmie procedura \textsc{Oznacz} opisana jest poniżej. \beginalgorithm \beginalgorithmic [1] \STATE \textbf{procedure} \textsc{Oznacz}} (p,q S)Parser nie mógł rozpoznać (nieznana funkcja „\IF”): {\displaystyle \IF{\textbf{zaznaczone}} [p,q]=1Parser nie mógł rozpoznać (nieznana funkcja „\STATE”): {\displaystyle } \STATE{ \textbf{return}} \ENDIF \STATE{\textbf{zaznaczone}} [p,q] 1Parser nie mógł rozpoznać (nieznana funkcja „\WHILE”): {\displaystyle } \WHILE{\textbf{not empty}} ({L}[p,q])Parser nie mógł rozpoznać (nieznana funkcja „\STATE”): {\displaystyle } \STATE{\textsc{Oznacz}(\textbf{zdejmij}} ({L}[p,q])Parser nie mógł rozpoznać (nieznana funkcja „\ENDWHILE”): {\displaystyle )} \ENDWHILE \STATE \textbf{end procedure} \endalgorithmic \endalgorithm Działanie algorytmu łatwo przedstawić na tabelce, która złożona jest z kwadratów -- pól, odpowiadających parom stanów automatu. Fakt znalezienia przez algorytm pary stanów rozróżnialnych zaznaczamy symbolem "x" w polu tabelki odpowiadającym tej parze, co wykorzystamy w przykładzie. {{cwiczenie|[Uzupelnij]|| Zminimalizujemy automat przedstawiony na rysunku [[##ja-lekcja5-w-rys4|Uzupelnic ja-lekcja5-w-rys4|]], używając algorytmu \textsc{Minimalizuj3}. RYSUNEK ja-lekcja5-w-rys4 Proces działania algorytmu i konstrukcji tabelki przedstawiony jest na poniższej animacji }} TUTAJ ANIMACJA. Opis animacji znajduje się w pliku ja-lekcja5-w-anim1.pdf. Wygląd ekranu animacji znajduje się w pliku ja-lekcja5-w-anim1.jpg.\\ Wypełniona tabelka po zakończeniu działania algorytmu przedstawiona jest na rysunku [[##ja-lekcja5-w-rys5|Uzupelnic ja-lekcja5-w-rys5|]]. RYSUNEK ja-lekcja5-w-rys5. Z tabelki odczytujemy, że stanami równoważnymi są stany } s_1, s_5,stanys_2, s_8orazstanys_4, s_6Parser nie mógł rozpoznać (błąd składni): {\displaystyle . Automat minimalny przedstawiony jest na rysunku [[##ja-lekcja5-w-rys6|Uzupelnic ja-lekcja5-w-rys6|]]. RYSUNEK ja-lekcja5-w-rys6.}