Documente Academic
Documente Profesional
Documente Cultură
Sortare i cutare
5.1 Metoda de sortare prin generare i testare
Utiliznd structura de control a limbajului Prolog, se poate realiza foarte simplu
sortarea unei secvene de elemente, folosind metoda generare i testare. Aceast
metod de rezolvare a problemelor, utilizat n inteligena artificial, dar puin
potrivit pentru o sortare, are la baz urmtoarea idee: o component generatoare
construiete soluii candidate i o a doua component, componenta de testare,
verific fiecare soluie candidat pentru a vedea dac este sau nu o soluie a
problemei. n acest fel, se pot obine fie toate soluiile problemei, fie una singur.
Aceast metod poate fi exprimat succint n Prolog astfel:
gaseste(Solutie) :genereaza(Solutie),
testeaza(Solutie).
Metoda este n general ineficient, chiar n cazul problemelor tipice de
inteligen artificial care necesit un proces de cutare a soluiei. Metoda este
extrem de ineficient n cazul rezolvrii problemelor de sortare, pentru care exist
algoritmi eficieni de rezolvare. Cu toate acestea, se prezint n continuare soluia
de sortare n ordine cresctoare a unei liste de ntregi prin metoda generare i
testare ca exerciiu Prolog.
% sortare(+Lista, -ListaSortata) - sortare prin metoda generare si testare
sortare(Lista, ListaSortata) :permut(Lista, ListaSortata), ordonata(ListaSortata).
% permut(+Lista, -PermutareLista)
permut([], []).
permut(Lista, [Prim | Rest]) :- elim(Prim, Lista, L), permut(L, Rest).
% elim(+Element, +Lista, -ListaMinusElement)
elim(Elem, [Elem | Rest], Rest).
elim(Elem, [Prim | Rest], [Prim | L]) :- elim(Elem, Rest, L).
88
CAPITOLUL 5
SORTARE I CUTARE
89
90
CAPITOLUL 5
% scindeaza(+Element, +Lista, -ListaInf, -ListaSup) % imparte Lista n ListaInf (cu elemente inferioare lui Element)
% si ListaSup (cu elemente superioare lui Element)
% in functie de relatia rel(X, Y)
scindeaza(Elem, [], [], []).
scindeaza(Elem, [Prim | Rest], [Prim | L1], L2) :not(rel(Elem, Prim)), !, scindeaza(Elem, Rest, L1, L2).
scindeaza(Elem, [Prim | Rest], L1, [Prim | L2]) :rel(Elem, Prim), scindeaza(Elem, Rest, L1, L2).
S testm acum implementrile metodelor de sortare prezentate i s
comparm rezultatele lor cu rezultatul produs de predicatul sort, care este
predefinit n SWI-Prolog:
% testarea metodelor de sortare
test(F) :L = [2, 2, 4, 6, 9, 8, 1, 3, 5, 7, 0], P =.. [F, L, S], call(P), write(P), nl.
test :- test(isort1), test(isort2), test(quicksort), test(sort).
Testarea va decurge astfel:
?- test.
isort1([2,2,4,6,9,8,1,3,5,7,0], [0,1,2,2,3,4,5,6,7,8,9])
isort2([2,2,4,6,9,8,1,3,5,7,0], [0,1,2,2,3,4,5,6,7,8,9])
quicksort([2,2,4,6,9,8,1,3,5,7,0], [0,1,2,2,3,4,5,6,7,8,9])
sort([2,2,4,6,9,8,1,3,5,7,0], [0,1,2,2,3,4,5,6,7,8,9])
SORTARE I CUTARE
91
rsd(SubarboreStang),
rsd(SubarboreDrept).
Dac se consider cazul arborilor binari de cutare (cu chei ntregi), se pot
defini trei predicate: caut(Cheie, Arbore), de cutare a unei chei n arbore, care
reuete dac cheia este n arbore i eueaz n caz contrar;
inser(Cheie, Arbore, ArboreRez), de inserare a unei chei n arbore, cu
argumentele Cheie i Arbore instaniate i argumentul ArboreRez sintetizat de
program; i elim(Cheie, Arbore, ArboreRez), care terge o cheie dintr-un arbore.
% caut(+Cheie, +Arbore) - reuseste daca Cheie este in
% arborele binar de cautare Arbore, esueaza in caz contrar
caut(Cheie, arb(Cheie, _ , _ )) :- !.
caut(Cheie, arb(Radacina, ArbStg, _)) :Cheie < Radacina, caut(Cheie, ArbStg).
caut(Cheie, arb(Radacina, _ , ArbDr)) :Cheie > Radacina, caut(Cheie, ArbDr).
Prima clauz a predicatului caut reuete dac cheia este n arbore. Pentru a
impiedica o posibil resatisfacere, deci gsirea unei alte apariii a cheii de cutare
n arbore, s-a introdus n acest caz predicatul cut. Dac se dorete, de exemplu,
afiarea tuturor apariiilor cheii de cutare n arbore, se va elimina acest cut i
predicatul caut va avea attea soluii cte apariii ale cheii de cutare exist n
arbore.
% inser(+Cheie, +Arbore, -ArboreRez) - insereaza Cheie in
% arborele binar de cautare Arbore si produce ArboreRez
inser(Cheie, nil, arb(Cheie, nil, nil)).
inser(Cheie, arb(Cheie, ArbStg, ArbDr), arb(Cheie, ArbStg, ArbDr)):-!.
inser(Cheie, arb(Radacina, ArbStg, ArbDr),
arb(Radacina, ArbStg1, ArbDr)) :Cheie < Radacina, !, inser(Cheie, ArbStg, ArbStg1).
inser(Cheie, arb(Radacina, ArbStg, ArbDr),
arb(Radacina, ArbStg, ArbDr1)) :Cheie > Radacina, inser(Cheie, ArbDr, ArbDr1).
Predicatul de inserare a unei chei ntr-un arbore de cutare, inser, utilizeaz
n definiie un cut verde pentru creterea eficienei. Se poate elimina condiia
Cheie > Radacina, din cea de a treia regul a predicatului inser, caz n care
predicatul cut se transform ntr-un cut rou. Programul Prolog urmtor folosete
definiiile predicatelor caut i inser pentru a implementa mai multe operaii de
prelucrare a arborilor binari de cutare.
Eliminarea unei chei dintr-un arbore binar de cutare se face dup
algoritmul standard:
92
CAPITOLUL 5
SORTARE I CUTARE
93
94
CAPITOLUL 5
SORTARE I CUTARE
95