Sunteți pe pagina 1din 14

MATERIALE ptr.

TEMELE 1, 2

Implementari ale algoritmilor prezentati ^n cele patru capitole


var

n:stari;
{numarul de stari}
m:litera;
{cardinalul alfabetului de intrare}
q0:stari;
{starea initiala a automatului}
delta:automat;
{functia de tranzitie}
finale:array[stari] of boolean;
{finale[s]=true <=> starea s este finala}

procedure citirea_datelor;
var k,j:integer;
begin
writeln('Dati nr. starilor <=',nmax);
readln(n);
writeln('Dati cardinalul alfabetului <=',mmax);
readln(m);
writeln('Dati matricea de tranzitie ');
for j:=1 to n do
for k:=1 to m do begin
write('delta[',j,',',k,']=');
readln(delta[j,k]);
end;
writeln('Dati starea initiala');
readln(q0);
end;
procedure accesibile;
var coada:array[stari] of stari;
{structura de date pentru parcurgerea bfs a automatului}
cap,spate:integer;
{primul, respectiv ultimul element din coada}
este :array[stari] of boolean;
{este[s]=true <=> starea s este in coada}
stare_curenta:stari;
{starea curenta a automatului}
j:integer;
{variabila de lucru}
begin
for j:=1 to n do este[j]:=false;
este[q0]:=true;
cap:=1;

193

Implementari ale algoritmilor prezentati ^n cele patru capitole

194

coada[cap]:=q0;
spate:=1;
repeat
for j:=1 to m do
if not este[delta[coada[cap],j]] then begin
este[delta[cap,j]] :=true;
inc(spate);
coada[spate]:=delta[coada[cap],j]
end;
inc(cap)
until cap>spate;
dec(cap);
writeln('starile accesibile din ',q0,' sunt');
for j:=1 to cap do write(coada[j],' ' );
writeln;
readln
end;
begin {programul principal}
citirea_datelor;
accesibile
end.

Problema P2:
Avem la intrare un automat nit determinist si furnizam la iesire un automat
nit determinist minimal echivalent. Detalii au fost precizate ^n Algoritmul (ALG2),
pagina 57, sau puteti gasi ^n [1, 7].
program reducerea_unui_automat_la_un_automat_minimal;
uses crt;
const nmax=20;
mmax=20;
type stari
litera
automat

=1..nmax;
=1..mmax;
=array [stari,litera] of stari;

var n
:stari;
{numarul de stari}
m
:litera;
{cardinalul alfabetului de intrare}
q0
:stari;

Implementari ale algoritmilor prezentati ^n cele patru capitole


{starea initiala}
delta :automat;
{functia de tranzitie}
finale:array [stari] of boolean;
{finale[s]=true <=> starea s este finala}
procedure citirea_datelor;
var i,j:integer;
{variabile de lucru}
begin
writeln('dati numarul de stari ale primului automat');
readln(n);
writeln('dati cardinalul alfabetului (fara lambda)');
readln(m);
writeln('dati matricea de tranzitie');
for i:=1 to n do
for j:=1 to m do begin
write('delta[',i,',',j,']='); {delta=Alt+235}
readln(delta[i,j])
end;
writeln('dati starea initiala');
readln(q0);
writeln('dati starile finale, 0 la terminare');
for i:=1 to n do finale[i]:=false;
repeat
readln(i);
if i<>0 then finale[i]:=true
until i=0
end;
procedure reducere;
type lista_perechi=^element;
element=record
unu,doi:stari;
urm:lista_perechi
end;
perechi=record
valoare:boolean;
lista :lista_perechi
end;
var pereche :array [stari,stari] of perechi;
p,q
:stari;
{variabile de lucru}

195

Implementari ale algoritmilor prezentati ^n cele patru capitole


a
:litera;
exista :boolean;
nprim
:integer;
{numarul de stari ale celui de-al doilea automat}
clasa
:array [stari] of stari;
{clasa[p]=q <=> clasa lui p este q}
i
:integer;
{variabila de lucru}
procedure marcheaza(p,q:stari);
type cuplu=record
unu,doi:stari
end;
var coada
:array [stari] of cuplu;
cap,spate:integer;
{primul, respectiv ultimul element al cozii}
pointer :lista_perechi;
temp
:cuplu;
este
:boolean;
{este=true <=> variabila este in coada}
i
:integer;
{variabila de lucru}
begin
{facem marcarea perechilor din lista lui (p,q)}
spate:=0;
pointer:=pereche[p,q].lista;
while pointer<>nil do begin
inc(spate);
coada[spate].unu:=pointer^.unu;
coada[spate].doi:=pointer^.doi;
pointer:=pointer^.urm
end;
cap:=1;
while cap<=spate do begin
temp.unu:=coada[spate].unu;
temp.doi:=coada[spate].doi;
pereche[temp.unu,temp.doi].valoare:=true;
{punem toti vecinii lui (temp.unu,temp.doi) in coada}
pointer:=pereche[temp.unu,temp.doi].lista;
while pointer<>nil do begin
este:=false;
i:=1;
while not este and (i<=spate) do

196

Implementari ale algoritmilor prezentati ^n cele patru capitole

197

if (pointer^.unu=coada[i].unu) and (pointer^.doi=coada[i].doi)


then
este:=true
else
inc(i);
if not este then begin
inc(spate);
coada[spate].unu:=pointer^.unu;
coada[spate].doi:=pointer^.doi;
pointer:=pointer^.urm
end
end;
inc(cap)
end
end; {de la procedure marcheaza}
procedure adauga(p,q,p1,q1:stari);
var pointer1:lista_perechi;
begin
new(pointer1);
if q<p then begin
pointer1^.unu:=p;
pointer1^.doi:=q
end
else begin
pointer1^.unu:=q;
pointer1^.doi:=p
end;
pointer1^.urm:=pereche[p1,q1].lista;
pereche[p1,q1].lista:=pointer1;
end; {de la procedure adauga}
begin
{initializarea matricii totale la false}
for p:=1 to n do
for q:=1 to n do begin
pereche[p,q].valoare:=false;
pereche[p,q].lista:=nil
end;
{listele (p,q) sunt vide}
{si marcam (p,q) cu p in F, q in Q-F}
for p:=2 to n do
for q:=1 to p-1 do begin
pereche[p,q].lista:=nil;
if (finale[p] and finale[q]) or

Implementari ale algoritmilor prezentati ^n cele patru capitole


(not finale[p] and not finale[q]) then
pereche[p,q].valoare:=false
else
pereche[p,q].valoare:=true;
end;
{incepe iteratia}
for p:=2 to n do
for q:=1 to p-1 do
if (finale[p] and finale[q]) or
(not finale[p] and not finale[q]) then begin
exista:=false;
a:=1;
while (a<=m) and not exista do
if pereche[delta[p,a],delta[q,a]].valoare or
pereche[delta[q,a],delta[p,a]].valoare then begin
exista:=true;
{se marcheaza (p,q)}
pereche[p,q].valoare:=true;
{urmeaza marcarea perechilor din lista lui (p,q) si
din listele marcate la acest pas}
marcheaza(p,q)
end
else inc(a);
if not exista then
for a:=1 to m do
if (delta[p,a]<>delta[q,a]) and
((delta[p,a]<>p) or (delta[q,a]<>q)) and
((delta[p,a]<>q) or (delta[q,a]<>p)) then
adauga(p,q,delta[p,a],delta[q,a])
end;
{urmeaza procedura de scriere a automatului minimal}
nprim:=1;
clasa[1]:=1;
for p:=2 to n do begin
q:=1;
exista:=false;
{exista=true <=> exista un element 0}
while (q<=p-1) and not exista do
if not pereche[p,q].valoare then
exista:=true
else
inc(q);
if not exista then begin
inc(nprim);
clasa[p]:=p
end

198

Implementari ale algoritmilor prezentati ^n cele patru capitole


else clasa[p]:=q
end; {de la for p:=2 to n ...}
writeln('automatul minimal are ',nprim,' stari');
i:=0;
for p:=1 to n do
if clasa[p]=p then begin
inc(i);
write('clasa[',i,']: ');
for q:=1 to n do
if clasa[q]=p then write(q,' ');
writeln(' (din primul automat) ');
end;
writeln('alfabetul este acelasi');
writeln('matricea de tranzitie este ');
write('Q\A|');
{A=Sigma=Alt+228}
for i:=1 to m do write(i,' ');
writeln;
write('----');
{-=Alt+196}
for i:=1 to m do write('--'); {-=Alt+196}
writeln;
i:=0;
for p:=1 to n do
if p=clasa[p] then begin
inc(i);
write(' ',i,'|');
for a:=1 to m do
write(clasa[delta[p,a]],' ');
writeln
end;
write('----');
{-=Alt+196}
for i:=1 to m do write('--'); {-=Alt+196}
writeln;
writeln('starea initiala este (aceeasi): ',q0);
write('starile finale sunt: ');
for p:=1 to n do
if (clasa[p]=p) and finale[p] then
write(p,' ');
writeln;
readln
end; {de la procedure reducere}
begin {programul principal}
citirea_datelor;
reducere;

199

54

Constructia automatului minimal

2.4 Constructia automatului minimal


Relativ la acceptarea unui limbaj regulat trebuie sa gasim un automat c^at mai simplu
care sa-l accepte, adica sa nu aiba stari ^n care nu ajungem niciodata sau sa aiba prea
multe stari. ^In acest sens, exista notiunea de automat minimal. Formal, acest lucru
se exprima prin urmatoarele trei de nitii:

De nitia 2.4.1 Fie A = (S; ; ; s ; F ) un automat nit determinist. Starea s se


numeste accesibila daca 9 w 2  astfel ^nc^at (s ; w) = s: O stare se numeste
inaccesibila daca nu este accesibila.
0

De nitia 2.4.2 Automatul nit determinist A este minimal daca nu exista un alt
automat nit determinist A0 cu mai putine stari dec^at A astfel ^nc^at L(A) = L(A0 ):
De nitia 2.4.3 Fie A un automat nit determinist. Spunem ca A este redus daca
nu are stari inaccesibile.
Asadar, e urmatoarele doua probleme:

Problema (P1):

Intrare: A = (S; ; ; s ; F ) un automat nit determinist;


Iesire: S 0  S multimea starilor accesibile.
0

Problema (P2):




Intrare: A = (S; ; ; s ; F ) un automat nit determinist;


Iesire: A0 = (S 0 ; ; 0 ; s0 ; F 0 ) un automat minimal echivalent cu A:
!

Din De nitiile 2.4.1 si 2.4.2 rezulta usor urmatoarele observatii:

Problema determinarii starilor accesibile este echivalenta cu problema determinarii componentei conexe corespunzatoare starii initiale ^ntr-un graf orientat. De fapt, pentru rezolvarea acestei probleme, nu conteaza daca arcele sunt
etichetate sau nu;

Relativ la problema a doua, automatul minimal nu este unic. Se spune ca


este unic p^ana la un izomor sm. Formal, automatele A1 si A2 (Ai =
(Si ; ; 1 ; s0i ; Fi ); i = 1; 2) sunt izomorfe daca exista o bijectie (permutare,
renumerotare) h : S1 ! S2 astfel ^nc^at:

{ h( (s; i)) = (h(s); i);


{ s = h(s );
{ F = h(F ):
1

02
2

8 s 2 S ; i 2 ;
1

01

Trecem acum la rezolvarea problemei (P1). Formal, vom construi inductiv niste
multimi de stari accesibile, p^ana nu mai gasim nici o stare noua.
(1)

= fs g
j = j [ ( j ; );
0

+1

56

Constructia automatului minimal

a) s 2 n ; rezulta din pasul inductiv ca s este accesibila;


b) s 2 ( n ; ); ^nseamna ca 9  2 n ; i 2  astfel ^nc^at s = (; i): Dar  2 n ;
de unde, conform ipotezei inductive, avem ca  este accesibila, adica 9 p 2  astfel
^nc^at  = (s ; p): Deci s = (; i) = ((s ; p); i) = (s ; p i) = (s ; q):
Cu aceasta, demonstratia corectitudinii si nititudinii relatiei (1) (privita ca un
algoritm) a luat sf^arsit.
Procedeul (1) se poate exprima folosind scrierea ^n pseudocod.
0

Algoritmul (ALG1):
begin
i := 0;
:= fs g;
repeat
i := i + 1;
i := i [ ( i ; )
until ( i = i ) or ( i = S );
a seaza('Starile accesibile=', i );
a seaza('Starile inaccesibile=',S
i );
end
Pentru implementare, multimile i se pot reprezenta folosind, ca structura de date, o
stiva sau o coada. ^In primul caz, algoritmul urmeaza o strategie \depth rst search"
(dfs), iar ^n al doilea \breadth rst search" (bfs). Pentru amanunte, cititorii pot
consulta [1].
0

^In continuare, vom vorbi despre solutia celei de-a doua probleme, adica despre automatul minimal. Am vazut ca problema determinarii automatului minimal folosind
relatia L este cel putin NP hard, deoarece relatia L foloseste ^n de nitia sa
multimea  ; care este in nita. ^In cele ce urmeaza, vom de ni relatia  de nita
peste multimea de stari (care este nita), si care va conduce la un algoritm polinomial pentru deducerea automatului minimal.

De nitia 2.4.4 Fie A = (S; ; ; s ; F ) un automat nit determinist. Starile


s ; s 2 S se numesc inseparabile ^n raport cu F (notatie s  s ) daca
F ((s ; p)) = F ((s ; p)); 8 p 2  :
0

De nitia 2.4.5 Fie A = (S; ; ; s ; F ) un automat nit determinist si e s ; s 2 S


k
arbitrare. Spunem ca s  s daca F ( (s ; p)) = F ( (s ; p)); 8 p 2  ; jpj  k:



!

Se observa ca  =

1 k
T
k=0

:

Urmatoarele doua rezultate sunt importante ^n demonstrarea corectitudinii si nititudinii algoritmului pe care^l vom prezenta (pentru demonstratia lor, puteti consulta
[7, 9, 10, 11]).

57

Constructia automatului minimal

Lema 2.4.1 Fie A = (S; ; ; s0; F ) un automat nit determinist, si e s1 ; s2


arbitrare. Atunci pentru orice k  1 are loc
s

k s () s k s
1

Teorema 2.4.1 Daca automatul nit


n
s  s () s  s :



1

 (s ; i); 8 i 2 :
determinist A are jS j = n

si (s1 ; i)

2S

stari, atunci

Daca automatul A satisface relatia S= = S; atunci A este minimal.

Formal, automatul minimal este A = (S=; ;  ; [s ] ; F=): Astfel, pentru dek


ducerea sa, calculam clasele de echivalenta pentru  :
0

Algoritmul (ALG2):
begin
= fF; S F g;
i := 0;
repeat
i := i + 1;
i
calculeaza  (folosind Lema 2.4.1)
i i
until (=  ) or (i = n 2);
end
Complexitatea timp (una grosiera) a algoritmului precedent este de O(n m); unde
n = jS j; m = jj; deoarece bucla \repeat ... until " se executa de cel mult O(n) ori,
k
iar constructia lui  necesita O(n  m): Pentru implementare, puteti consulta Anexa
A sau [1]. Varianta implementata acolo este ^mbunatatita, av^and O(n  m) operatii.
0

Exercitiul 2.4.1 Fie automatul


A = (fs ; s ; s ; s ; s ; s ; s ; s g; f0; 1g; ; s ; fs ; s ; s ; s g)

 - 

q


>
6 ~







N
U
K


 -

U









0

cu dat prin graful de tranzitie:

0; 1

58

Constructia automatului minimal

a) sa se deduca starile accesibile (si cele inaccesibile);


b) sa se calculeze clasele de echivalenta ale relatiei ;
c) sa se construiasca automatul minimal echivalent cu A;
d) care este L(A) ?

Solutie a) Conform cu Algoritmul (ALG1) deducem:


= fs g;
= fs ; s ; s g;
= fs ; s ; s ; s ; s ; s g;
= fs ; s ; s ; s ; s ; s ; s g;
= ;
Asadar, spunem ca S 0 = fs ; s ; s ; s ; s ; s ; s g este multimea starilor accesibile.
Deci S S 0 = fs g este multimea starilor inaccesibile. Astfel, eliminam starea s :
Se obtine automatul A0 = (fs ; :::; s g; ; 0 ; s ; fs ; s ; s g) si 0 (s; i) = (s; i); 8 s 2
S fs g; i 2 : Pentru simplitate, vom nota 0 tot cu :
b) Calculam ; ; :::; apoi facem intersectia lor pentru a a a relatia : Pentru
relatia , clasele sale de echivalenta sunt date de multimile F; S F; deoarece s 
s () F ((s ; )) = F ((s ; )) () F (s ) = F (s ); adica s ; s 2 F sau
s ; s 2 S F: Astfel, clasele de echivalenta pentru relatia  sunt:
0

fs ; s ; s g; fs ; s ; s ; s g
3

Pentru calculul claselor de echivalenta ale relatiei ; trebuie sa partitionam


multimile calculate la relatia  : Pentru aceasta, vom folosi Lema 2.4.1. Luam prima
clasa de echivalenta a relatiei  : Sa vedem daca fs ; s ; s g 2 : Trebuie sa luam
orice doua perechi de stari fs ; s g; fs ; s g; fs ; s g si sa veri cam daca ram^an ^n
 : Distingem C = 3 cazuri:
1

2
3

Cazul I.1: e perechea fs3 ; s4 g; avem fs3 ; s4 g 2 si (s3 ; 0) = s5 si (s4 ; 0) = s5 ;
0

respectiv (s ; 1) = s si (s ; 1) = s : Dar s  s si s  s , deoarece relatiile


k ; 8 k 2 N sunt re exive. Folosind Lema 2.4.1, rezulta ca fs ; s g 2;
0

Cazul I.2: pentru perechea fs3 ; s5 g; avem fs3 ; s5 g

2

si (s ; 0) = s si
(s ; 0) = s ; respectiv (s ; 1) = s si (s ; 1) = s : Dar s  s si s  s ,
deci fs ; s g 2;
5

Cazul I.3: pentru perechea fs4 ; s5 g se poate proceda la fel sau, mai elegant,
k

folosim proprietatile de simetrie si tranzitivitate a relatiilor ; 8 k 2 N: Astfel


din s  s ; folosind simetria, rezulta s  s ; si apoi, folosind s  s ; rezulta,
din tranzitivitate, ca s  s :
1

59

Constructia automatului minimal

Concluzia este deci ca fs ; s ; s g 2 :


Trecem acum la cea de-a doua clasa de echivalenta fs ; s ; s ; s g: De data aceasta
distingem C = 6 cazuri.
1

2
4

Cazul II.1: pentru perechea fs0 ; s1 g; avem fs0 ; s1 g

2

si (s ; 0) = s si
(s ; 0) = s ; respectiv (s ; 1) = s si (s ; 1) = s : Dar s  s si s  s ,
deci fs ; s g 2;
1

Cazul II.2: pentru perechea fs0 ; s2 g; avem fs0 ; s2 g

2 si (s ; 0)
(s ; 0) = s : Nu mai continuam deoarece s 
6 s : Deci fs ; s g 62;

= s si

Cazul II.3: pentru perechea fs0 ; s6 g; avem fs0 ; s6 g

2

si (s ; 0) = s si
(s ; 0) = s ; respectiv (s ; 1) = s si (s ; 1) = s : Dar s  s si s  s ,
deci fs ; s g 2;
6

Cazul II.4: pentru perechea fs1 ; s2 g: Putem proceda ca p^ana acum, sau folosim

simetria si tranzitivitatea relatiei  : Astfel, presupunem prin reducere la absurd, ca fs ; s g 2 : Utiliz^and cazul II.1, rezulta ca fs ; s g 2; ceea ce este
o contradictie cu cazul II.2. Asadar, fs ; s g 62;
0

Cazul II.5: pentru perechea fs1 ; s6 g: Din cazurile II.1 si II.3, rezulta fs1 ; s6 g 2;

Cazul II.6: pentru perechea fs2 ; s6 g: Din cazurile II.4 si II.5, rezulta fs2 ; s6 g 62;

Deci clasa fs ; s ; s ; s g se partitioneaza ^n doua subclase: fs ; s ; s g si fs g.


^In concluzie, din cazurile I si II, obtinem clasele de echivalenta pentru relatia :
0

fs ; s ; s g; fs g; fs ; s ; s g:

Este vorba de o optimizare a procedeului de mai sus. Pentru cazul I, respectiv II, sunt
su ciente doar 2; respectiv 3 subcazuri, fata de cele dezbatute 3; respectiv 6: ^In general,
k
daca o clasa de echivalenta a relatiei  are n elemente, atunci sunt su ciente n 1
n
(
n
1)
subcazuri, ^n loc de Cn2 = 2 : Acest lucru rezulta imediat din proprietatile relatiei

k (re exivitate, simetrie, tranzitivitate).

Data multimea S = fs1 ; s2 ; :::; sn g de stari


arbitrare, se pot alege drept subcazuri perechile de stari fsi ; si+1 g; 8 i = 1; n 1:

Continuam acum cu calculul relatiei  : Conform cu clasele de echivalenta obtinute


pentru relatia ; deducem ca trebuie sa partitionam clasele fs ; s ; s g si fs ; s ; s g:
Clasa fs g apartine relatiei ; deoarece nu se mai poate partitiona si nici nu se poate
reuni cu alta clasa, datorita Lemei 2.4.1.
2




60

Constructia automatului minimal

Rezulta o alta ^mbunatatire a Algoritmului (ALG2) si anume ca se partitioneaza


k
doar acele multimi S 0 2; pentru care jS 0 j  2:

Cazul I: Ne referim acum la clasa fs3 ; s4 ; s5 g: Analog cu cazul I pentru relatia

; obtinem fs ; s ; s g 2 :
1

Cazul II: ^In ceea ce priveste clasa fs0 ; s1 ; s6 g; ^n mod asemanator cu cazul II de

la relatia ; deducem urmatoarele clase pentru :


1

fs ; s g; fs g:
0

^In mod analog, se calculeaza  si se observa ca = : Conform Teoremei 2.4.1 si
Lemei 2.4.1, rezulta ca relatia  are urmatoarele clase de echivalenta:
3

fs ; s g; fs g; fs g; fs ; s ; s g:
0

c) Conform De nitiei 2.4.3 si punctelor a) si b) de mai sus, rezulta ca automatul
minimal echivalent cu A este A0 = (f[s ]; [s ]; [s ]; [s ]g; f0; 1g; 0; [s ]; [s ]); unde 0
este dat prin urmatorul graf de tranzitie:
R 
1
[s ]
- [s ]
0










[s ]



?
s

3

[s ]

0; 1

0; 1
Legatura dintre starile lui A0 si cele ale lui A este imediata:

[s ] = fs ; s g; [s ] = fs g; [s ] = fs g; [s ] = fs ; s ; s g:
0

d) Este mai simplu de dedus si demonstrat care este limbajul acceptat de A
folosind automatul minimal echivalent cu A; deoarece are mai putine stari. Asadar
L(A) = L(A0 ) = fp=p 2 [s ] 0 0 g = f(01)1f1; 0g ; (01) 00f1; 0g g = f(01)(1 +
00)f1; 0g g:
! Exercitiul 2.4.1 re ecta un exemplu de automat minimal care are doar jumatate




A ;s

din numarul de stari ale automatului initial.

S-ar putea să vă placă și