Sunteți pe pagina 1din 457

InteligenŃă Artificială. Tehnici.

1. INTRODUCERE ÎN BAZELE INTELIGENłEI ARTIFICIALE


1.1.Definirea domeniului inteligentei artificiale.
În general notiunea de inteligenŃă este legată de capacitatea umană de a genera
idei de a descoperi cauzele unor fenomene ca şi de capacitatea de abstractizare. Nu există
o definiŃie unică pentru inteligenŃă. DicŃionarul Webester defineşte inteligenŃa astfel :
inteligenŃa este capacitatea de a înŃelege noul şi de a face faŃă unor situaŃii
neprevăzute.
În prezent cea mai comună definiŃie acceptată este următoarea :
inteligenŃa reprezintă capacitatea de a percepe, înŃelege şi a învăŃa în cadrul unor
situaŃii noi.
Creierul uman este înzestrat cu un potenŃial enorm de percepŃie, înŃelegere şi
învăŃare. Dacă această capacitate poate fi duplicată într-un sistem de calcul, calculatorul va
putea fi considerat ca inteligent în raport cu definiŃia dată inteligenŃei artificiale.
Termenul de IA (InteligenŃă Artificială ) a fost utilizat pentru prima dată în 1960 în
cadrul unui articol scris de către Minsky intitulat "Paşii către o inteligenŃă artificială" în care
se prezentau în premieră, modalităŃii de rezolvare simbolică a problemelor de analiză
matematică pe un calculator. Termenul care s-a introdus cu acestă ocazie a suscitat
numeroase discuŃii datorită implicaŃiilor pe care le ridică :
- ce este inteligenŃa;
- este acesta o caracteristică umană;
- pot fi maşinile inteligente;
- se poate vorbi de o inteligenŃă artificială;
- programele produse prin IA sunt inteligente

Toate aceste întrebări au generat polemici numeroase care nu au condus nici până
în prezent la o opinie comună în acest domeniu. Din acest motiv, evoluŃia domeniului va fi
ilustrată de diversele definiŃii care s-au acceptat pentru IA de-a lungul timpului şi până în
prezent.

1) 1975 - IA este domeniul care se ocupă cu studiul conceptelor care permit ca maşinile
să fie inteligente
2) 1981 - IA este un domeniu al informaticii care îşi propune crearea unor sisteme
inteligente de calcul care să posede acele caracteristici care sunt asociate în general cu
inteligenŃa în domeniul uman: raŃionament, capacitate de învăŃare, de rezolvare şi de
comunicare.
Plecându-se de la constatarea ca există probleme care nu dispun de un algoritm de
calcul sau algoritmul este prea complicat, s-a luat în considerare că acestea fac obiectul IA,
în prezent fiind acceptată următoarea definŃie pentru IA.

1
InteligenŃă Artificială. Tehnici.

3) 1990 - IA este un domeniu al informaticii care începe acolo unde informatica clasică
se opreşte, destinat rezolvării problemelor pentru care nu există un algoritm de calcul sau
pentru care algoritmii sunt prea complicaŃi pentru a fi rezolvaŃi în maniera clasică.
IA prezintă un punct de vedere diferit faŃa de cel clasic în rezolvarea unei probleme.
Clasic se manipulează informaŃii numerice care sunt prelucrate în contextul unor algoritmi.
Din punct de vedere al IA se manipulează cunoştinŃe utilizate în cadrul unor strategii.

Clasic
enunŃ ---> algoritm de calcul --->rezultat

InteligenŃă Artificială
problema ---> (informaŃii / cunoştinŃe + strategie de rezolvare.) --->concluzie

1.2. InteligenŃă, cunoaştere, raŃionament


În dicŃionarul limbii engleze inteligenŃa este definită de capacitatea de a inŃelege noul şi
capacitatea de a face faŃă unor situaŃii neprevăzute.
DefiniŃie: InteligenŃa este capacitatea de a percepe, înŃelege şi învăŃa în contextele unor
situaŃii noi.
Aceste caracteristici impun prezenŃa a două componente, capacitate de cunoaştere şi de
a raŃiona (de a efectua deducŃii logice).
Cunoaşterea este fenomenul prin care se face un transfer de informaŃii de la obiect la
observator. În cursul acestui transfer sunt recepŃionate numai caracteristicile esenŃiale.
Deci cunoaşterea nu are un caracter enciclopedic, având loc o abstractizare şi o filtrare a
informaŃiei recepŃionate.
Structural cunoaşterea este formată din piese de cunoastere ( numite entităti ) prin care
sunt reprezentate diversele caracteristici ale fenomenului observat. Pentru construirea unei
piese de cunoaştere se utilizează doua noŃiuni:
a) concepte (rezultatele unui proces de abstractizare prin care se deduc acele
carateristici ce permit încadrarea obiectului intr-o anumită clasă).
b) instante (caracteristici individuale care aparŃin unui obiect).
DeducŃiile logice (raŃionamentul) reprezintă un lanŃ de judecăŃi a căror obiectiv este
obŃinerea unor noi adevăruri. Prin judecată se înŃelege o propoziŃie simplă prin care se
afirmă sau se neagă ceva şi care întotdeauna prezintă valoarea adevărat. JudecăŃile pot fi
de tip:
predicŃie, dacă oferă un raport între un obiect şi o însuşire a acestuia şi de tip
relaŃie dacă reflectă un raport între două sau mai multe obiecte.

2
InteligenŃă Artificială. Tehnici.

De exemplu :
Premise InferenŃă Concluzii
Socrate este un om.
Orice om este muritor --------------------------------------> Socrate este muritor.

Într-un raŃionament un set de judecăŃi numite premise, sunt legate de o alta judecată
numită concluzie printr-un proces care poartă denumirea de inferenŃă. Procesul deductiv
este ilustrat de exemplul de mai sus.

1.3. Predicate şi clauze Horn. Modul de functionare a


maşinii de inferenŃă.
Deoarece este greu de relevat componentele interne a unei propoziŃii astfel încât
acestea să poată fi luate în considerare de maşina ce efectuează deducŃii logice, a devenit
necesară definirea unui limbaj specializat în care urmează a fi descrise premisele. La
construirea limbajului se utilizează patru mulŃimi:
a)-constante {a,b,c}
b)-simboluri funcŃionale {f,g,h,...}
fiecare caracterizat de un numar de argumente
c)-simboluri relaŃionale {P,Q,R,...}
fiecare caracterizat de un numar de argumente
d)- o multime infinita de variabile {x, y,z,x1,y1,...}
Cu aceste mulŃimi se construiesc termenii limbajului:
1.-orice constantă sau variabilă este un termen;
2.- dacă t1,…..tn sunt termeni, atunci orice simbol funcŃional de n argumente
de forma f(t1,…..tn) este un termen;
3.-o propoziŃie simplă (denumirea este de formulă atomică) este definită de
un simbol relaŃional de n argumente în care argumentele sunt termeni de
forma P(t1,…..tn).
Exemplu:
considerăm constantele Ana, Dan, Radu;
simbolurile funcŃionale Mama, Tata;
simbolurile relaŃionale Este_copilul_lui, Este_frate_cu.
Următoarele construcŃii sunt termeni având interpretările:
Mama(Ana) - mama Anei
Tata(Mama(x)) - tatal mamei lui x
Următoarele construcŃii sunt propoziŃii simple:
Este_copilul_lui(x, Mama(x)) - x este copilul mamei sale
3
InteligenŃă Artificială. Tehnici.

Este_copilul_lui(Dan, Mama(Ana)) - Dan este copilul mamei Anei


Este_frate_cu(Tata(Dan), Tata(Radu)) - tatal lui Dan este frate cu
tatal lui Radu
Este_copilul(Mama(x), x) - mama lui x este propriul său copil
Aceste propoziŃii pot fi sau nu adevarate, funcŃie de interpretarea pe care o atribuim
constantelor, simbolurilor funcŃionale şi simbolurilor relaŃionale întâlnite. Luând în
considerare ca interpretarea pentru simbolurile funcŃionale şi relaŃionale este sugerat de
numele lor, atunci primele trei propoziŃii vor fi adevărate întotdeauna iar ultima falsă. Se
observă că sintaxa limbajului este insuficientă pentru a obŃine noi adevăruri. Din acest
motiv limbajul se completează cu operatorii relaŃionali
sau (V), şi (Λ), nu (), implică (--->)
la care se adaugă cuantificatorii oricare ar fi (∀) şi exista (∃). Cu aceştia se
construiesc propoziŃiile limbajului astfel:
a)- orice propoziŃie simplă (formula atomica) este o propoziŃie
b)-dacă A,B sunt propoziŃii simple atunci (A V B), (A Λ B), (A --> B)
sunt propoziŃii
c)-dacă A este o propoziŃie simplă sau o propoziŃie a limbajului
atunci construcŃiile (∀x)A şi (∃ x)A sunt propoziŃii ale limbajului.
Utilizand sintaxa acestui limbaj pot fi descrise multe probleme practice. De exemplu,
propoziŃiile cu care am inceput in acest paragraph pot fi descrise astfel:
1. Om (Socrate)
2. ∀ x (Om(x) --> Muritor (x))
3. Muritor (Socrate)
RelaŃiile de familie dintre membrii unei comunităŃi ar putea fi descrise prin formule de
tipul:
1.-( ∀ x)( ∀ y)( ∀ z)(Este_copilul_lui(x,y) Λ (Este_copilul_lui(y,z))-->
Este_bunicul_lui(x,z)
2.-( ∀ x)( ∀ y)( ∀ z)(Este_copilul_lui(x,Tata(y)))-->
(Este_frate_cu(x,y)) V (Este_sora_cu(x,y))
3 ( ∀ x) ( ∃ y) Este_mama_lui(y,x)
Generalizând, propoziŃiile şi relaŃiile care apar in cadrul unui limbaj natural pot fi
descrise prin clause de forma:

( ∀ x1)……( ∀ xn) A1 Λ …………….. Λ Am ---> B1 V ………V Bk

unde Ai şi Bi sunt formule atomice iar n, m şi k pot fi eventual 0. Pentru cazul in care k = 1
clauzele poartă denumirea de clause Horn

4
InteligenŃă Artificială. Tehnici.

Problema care ne interesează in acest moment este aceea de a vedea in ce măsura


utilizand acest mod de reprezentare a propoziŃiilor şi frazelor în limbajul natural pot fi
obŃinute noi adevăruri
Sa reluam exemplul discutat anterior in care avem doua premise
1. Om(Socrate)
2. ( ∀ x) (Om(x)-->Muritor(x))
consecinta logica care rezulta este aceea ca:
Muritor(Socrate)

Intrebarea este cum se procedează astfel incat sa obŃinem consecinŃa logica de mai sus?
Formalizand problema care ne interesează, (cea a verificării deductibilităŃii pe un set de
axiome), se obŃine:
avand doua formule A şi B, este B o consecinŃă logică a lui A?
Considerăm un sistem de clause Horn format din:
- o multime de formule atomice: A1 ,…………, Am denumite axiome
- o multime de reguli, care sunt clause Horn
- o concluzie care este tot o formula atomica.
Variabilele care apar in axiome şi reguli se vor citi cu “oricare” iar cele din concluzie cu
“exista”. De exemplu pentru cele doua premise de mai sus
Om(Socrate) “Socrate este om”
(∀ x) (Om(x) -->Muritor(x)) “Oricine este x, dacăeste om atunci x este muritor”
iar o concluzie de tipul :
Muritor(x) se citeste ca o intrebare: exista x, astfel incat x sa fie muritor?
Algoritmul de verificare a deductibilităŃii este implementat într-un mecanism de inferenŃă
care stă la baza efectuarii deducŃiilor logice pe un set de axiome descrise prin clause Horn,
aspect care permite construirea unor limbaje special dedicate modelarii modului in care
gandesc oamenii. Din cele discutate se observa ca:
- mecanismul de inferenŃă va trebui să dispună de două componente: una de
căutare prin care partea stângă a unei reguli apare ca un şablon ce se
suprapune peste setul de premise.
- Când şablonul se potriveşte intră în funcŃiune cea de a doua componentă care
unifică variabilele din şablon cu cele din setul de premise (x primeşte valoarea lui
Socrate). Introducând valoarea în membrul drept se obŃine un adevar nou:
Muritor(Socrate).

Exercitii
1. Clauzele Horn utilizate pentru descrierea cunoştinŃelor contin variabile. Care este
semnificatia acestui concept?
2. Dati definitia: Inteligentei Umane şi a Inteligentei Artificiale

5
InteligenŃă Artificială. Tehnici.

2. ELEMENTE DE BAZĂ A LIMBAJULUI PROLOG

Prolog ( Programming in logic ) este un limbaj descriptiv în care problema este


definită printr-un set de propoziŃii. Prolog dispune de o maşină de inferenŃă care efectuează
deducŃii logice pe seturi de propoziŃii. Din acest punct de vedere limbajul se comporta ca un
sistem expert care dispune de o maşina de inferenŃă predefinita. Aceasta actioneaza
asupra unei baze de cunoştinŃe care este definite de utilizator şi furnizeaza solutiile in
conformitate cu întrebările puse. In acest scop limbajul dispune de o interfata utilizator prin
care se definesc cunoştinŃele (introducere, modificare, stergere) cat şi de o interfat prin
care se prezinta rezultatele rationametului la care este atasat un sistem care permite modul
in care s-a efectuat rationamentul. Structura sistemului expert de tip Prolog este de forrma:

Reprezentare

Intrari MEMORIE Date de activare BAZA DE


DE LUCRU CUNOSTINTE
(date de caz) Fapte dinamice Reguli Fapte

Date Actiuni
(Concluzii)

Iesiri MOTOR DE Reguli selectate Selectie reguli


INFERENTA si fapte
(Raspunsuri)

Control

1.1. Structura unui program Prolog


Baza de cunoştinŃe ( ceea ce se cunoaşte despre problema in cauză) este descrisă
utilizand clause Horn. Setul de clauze este format din axiome (fapte), dacă se specifică
caracteristici ale obiectului şi din reguli dacă se definesc relaŃii care leaga doua sau mai
multe clause care au una sau mai multe elemente comune. Fiecare clauză se termină cu
punct .
De exemplu o relaŃie care in limbaj natural este reprezentată printr-o propozitie de forma:
Ion este tatal lui Dan
Apare utilizan clause Horn sub forma:
este_tatal_lui(ion,dan).
O proprietate, care in limbaj natural este de asemena definită printr-o propozitie de forma:
6
InteligenŃă Artificială. Tehnici.

Cerul este albastru.


Apare descrisa in baza de cunoştinŃe sub forma:
este_albastru(cerul).
O regula care in limbaj natural apare sub forma:
Lui Dan ii place culoarea albastra dacălui Ion ii place culoarea albastra.
Scrisa cu clause Horn prezintăaspectul:
Ii_place_lui(dan,albastru) if
Ii_place_lui(ion,albastru).
Toate aceste informaŃii sunt structurate intr-o baza de cunoştinŃe care prezintă următoarele
sectiuni:
domains

predicates

clauses

fiecare dintre acestea avand un rol de structurare a informaŃiei care urmeaza sa fie supusa
procesului de inferenŃă.
Astfel sintaxa axiomelor şi regulilor apare descrisa in sectiunea predicates, axiomele
(propoziŃii simple) şi regulie (fraze) sunt descries in sectiunea clauses. Sectiunea domains
este destinată specificarii structurii de date utilizatăla domeniloor la care apartin
componentele structurilor utilizate. Se respecta următoarele restrictii:
- numele componentelor elementare ale propoziŃiilor trebuie sa inceapă cu o literă
mică care poate fi urmată de oricate combinatii de caractere alfanumerice sau
semen de tip underline “_”
- numele predicatelor pot fi combinatii de litere, cifre sau caractere de subliniere;
- o propozite sau fraza scrisa in topica Horn se termina obligatoriu cu punct.
- semnul --> este definit prin dacă (if). Acesta se poate reprezenta şi prin simbolul :-

2.2. Domenii standard.


Dacă predicatele definesc tipul relaŃiei care are loc in cadrul unei propoziŃii sau fraze,
domeniul va specifica aria in care are loc relaŃia (mai exact structura şi apartenenta la o
anumita structura standard sau utilizator a componentelor pe care le leaga relaŃia in acuza).

Domeniile standard acceptate sunt:


-integer defineste domeniul numerelor intregi de la ±216-1
-real defineste domeniul numerelor reale de la ±1E±203
7
InteligenŃă Artificială. Tehnici.

-string defineste o secventa de caractere scrisa între ghilimele


duble (" " ) ex.: "Socrate este un om"
-symbol corespunde numelor simbolice, fiind definit prin şiruri de
caractere (ex.: Socrate_este_om)
-char defineşte caractere delimitate de ' ': (ex.: 'a' ,'1' )

2.3. Interogarea unei baze de cunoştinŃe


Pentru a vedea modul in care se descriu un set de informaŃii in limbaj natural in
contextual unei baze de cunoştinŃe cu structura mentiona in paragraful anterior vom pleca
de la un exemplu de forma:

Exemplu: ConstruiŃi o bază de cunoştinŃe care să definească informaŃiile:


Dan are vîrstă de 7 ani.
Ana are vîrstă de 9 ani.
Radu are varsta de 9 ani.
Ion are varsta de 10 ani.

Modul de transpunere a acestor propoziŃii simple intr-o baza de cunoştinŃe Prolog care sa
poată fi ulterior explorată de o maşina de inferenŃă (care apartine limbajului in cauza) este:
domains
nume=symbol
virsta=integer
predicates
are_vârsta_de(nume, virsta)
clauses
are_vârsta_de(dan, 7).
are_vârsta_de(ana, 9).
are_vârsta_de(radu, 9).
are_vârsta_de(ion, 10).

Se observa ca baza de cunoştinŃe este formată numai din axiome fara a fi prezente relaŃii
intre acestea. Inspectarea bazei de cunoştinŃe presupune punerea de întrebări prin care se
doreste obtinerea de informaŃii relative la faptele relatate de propoziŃii. Întrebările se pun
dupa lansarea masinii de inferenŃă din Prolog in momentul aparitiei mesajului Goal (Tinta)
prin care maşina atentioneaza utilizatorul ca asteapta punerea unei întrebări. Tipul
intrebării care se pune, depinde de structura bazei de cunoştinŃe, fiind prezente
următoarele variante:

8
InteligenŃă Artificială. Tehnici.

2.3.2. Intrebări simple


O întrebare simplă este definită de un predicat de forma :
predicat(<variabila1>, <variabila2>, ……<variabila n>)

In care predicat este in general predicatul propozitiei simple care se pune, iar variabila o
componenta a propozitiei.
În general aceste intrebări se pot încadra în următoarele trei mari categorii:
1.-se verifică prezenŃa unui obiect în baza de cunoştinŃe
Exemplu: este prezentă o persoană cu numele Radu şi vârsta 9 ani?
? are_vârsta_de(radu,9)
yes
2.-se caută în bază obiectele care prezintă o anumită proprietate
Exemplu: care sunt persoanele cu vârsta de 9 ani?
? are_vârsta_de(Pers,9)
Pers=ana
Pers=radu
2 solutions
3.-de confirmare a prezenŃei unei proprietăŃi în baza de cunoştinŃe
(sau a unui obiect)
Exemplu: există cineva cu vârsta de 10 ani?
? are_vârsta_de( _ ,10)
yes
ObservaŃii:
1.-variabilele încep cu o literă mare şi în momentul realizării unei potriviri în
baza de cunoştinŃe realizată de maşina de inferenŃă, valoarea va reprezenta o soluŃie a
problemei
2.-valorile care nu interesează, traduse prin cineva, orice, ceva sunt
reprezentate de caracterul _ pe poziŃia variabilei în cauză, avand semnificaŃia de variabilă
anonimă

2.3.3. Întrebari compuse.


Sunt de forma:
predicat_1(<variabila1>, <variabila2>, ……<variabila n>) and
predicat_2(<variabila1>, <variabila2>, ……<variabila n>) and

predicat_n(<variabila1>, <variabila2>, …<variabila n>) and e1 end e2 and ….e n.

unde:
- variabila i defineste o componenta a întrebării, care in acest caz prezintă topica
unei fraze;

9
InteligenŃă Artificială. Tehnici.

- predicat I defineste predicatul unei propoziŃii din frază, dacăsunt mai multe
propoziŃii acestea sunt despartite prin şi (în loc de and se poate pune , ) urmate
opŃional de expresii relaŃionale între variabile (ek >,<,<>,=,>=,<=).

Pentru exemplul dat putem avea următoarele întrebări:


a)-care sunt persoanele a căror vârsta este mai mică de 10 ani şi strict mai
mare decât 7?
? are_vârsta_de(P,V), V>7, V<10
P=ana V=9
P=radu V=9
2 solutions
b)-care sunt perechile de persoane care au vârsta de 9 ani?
? are_vârsta_de(P1,9), are_vârsta_de(P2,9), P1<>P2
P1=ana P2=radu
P1=radu P2=ana
2 solutions
ObservaŃie: în cazul în care se omite P1<>P2 se obŃin patru soluŃii de forma
P1=ana P2=ana
P1=ana P2=radu
P1=radu P2=ana
P1=radu P2=radu
4 solutions

2.3.4. Reprezentarea regulilor.


Pâna în prezent, baza de cunoştinŃe a fost formată numai din axiome care specificau
vârsta unei persoane. Se presupune ca se doreşte completarea bazei cu relaŃii de tip:
X este mai mare decit Y (X şi Y se referă la vârsta)
In acest caz baza de cunoştinŃe va primi următoarea forma

domains
nume=symbol
virsta=integer
predicates
are_vârsta_de(nume, vârsta)
este_mai_mare(nume, nume)
clauses
are_vârsta_de(dan, 7).
are_vârsta_de(ana, 9).
are_vârsta_de(radu, 9).
are_vârsta_de(ion, 10).
este_mai_mare(P1, P2) if
are_vârsta_de(P1, V1),
are_vârsta_de(P2, V2),
V1>V2.

Pot apare variante de intrebări:


a)este ca varsta Ana mai mare decat Dan?
? este_mai_mare(ana, radu)
no
10
InteligenŃă Artificială. Tehnici.

b)-care sunt persoanele care sunt mai mari decât Dan?


? este_mai_mare(dan, X)
X=ana
1 solution
c) Exista cineva mai mare ca varsta decat Ana?
?-este_mai_mare(_, ana)
yes

2.4. Introducerea operatorului sau


Intr-o baza de cunostinŃe pot exista una sau mai multe reguli. Aceste se vor scrie
intotdeauna dupa axiome. In cazul in care relaŃia dintre axiome impune utilizarea a una sau
mai multe reguli aceste se pot scrie explicit sau o alta alternativa posibila este aceea de a
utiliza operatorul logic sau. Acesta va lega alternativele posibile, fiecare alternativa
reprezentand o regula.
De exemplu:
ConstruiŃi o bază de cunoştinŃe care să definească marimea şi culoarea unor
animale.
domains
animal=symbol
predicates
este_mare(animal) este_mic(animal)
este_maro(animal) este_gri(animal)
este_negru(animal) este_negru(animal)
are_culoare_inchisa(animal)
clauses
este_mare(elefant). este_mare(urs). este_mic(pisica).
este_maro(urs). este_gri(elefant). este_negru(pisica).
are_culoare_inchisa(x) if
este_maro(x);
este_negru(x).
ObservaŃie:
1. predicatele care descriu structura propoziŃiilor şi frazelor pot fi scrise pe acelasi
rând cu observaŃia ca este necesara delimitarea prin cel putin un carater spaŃiu;
2. similar axiomele pot fi scrise doua sau mai multe pe acelaşi rând.

Regula de construire a unor structuri cu operatorul logic sau poate fi enuntată de


forma:
În cazul în care sunt prezente predicate cu acelaşi nume şi în reguli succesive atunci
acestea pot fi acumulate într-una singură clausă separându-le prin sau (se mai poate utiliza
caracterul ;). Modul de construire:
a)- P:-Q. şi P:-R.
se înlocuieşte cu P:-Q;R.
b)- P:-X,Y,Z şi P:-W.
se înlocuieşte cu P:-X,Y,Z;W.

11
InteligenŃă Artificială. Tehnici.

2.5. Functionarea maşinii de inferenŃă Prolog.


O intrebare este pusă în Prolog printr-un set de propoziŃii sau fraze formate dintr-
unul sau mai multe predicate urmate de una sau mai multe expresii (relaŃii ). Fiecare
predicat reprezintă o întrebare (o problemă parŃială) care trebuie rezolvată. Modul de
rezolvare adoptat de maşina de inferenŃă implementeaza principiul de efectuare a
deductiilor logice prezentat intr-un capitol anterior. Acest mecanism se reduce la o operaŃie
de cautare (backtracking) şi potrivire (unificare) care actioneaza in etape succesive. In
literatura de specialitate aceast mecansim de inspectie (inferenŃă) a unor cunoştinŃe dintr-o
baza de cunoştinŃe poartă denumirea globala de backtracking.

Backtracking reprezintă mecanismul de căutare în baza de cunoştinŃe –


defineste modul in care functioneaza maşina de inferenŃă prolog.

Mecanismul acŃionează iniŃial pe setul de axiome, după care trece pe setul de reguli.
Mecanismul presupune două componente:
- o componentă de căutare prin potrivire (unificare) dintre un predicat prezent în
definiŃia probleme şi o clauză.
- O componenta de cautare dupa potrivire in contextual restrictiilor introduce de
potrivirea gasita.

Procesul de unificare constă în asocierea (matching) unei întrebări (goal) cu o


anumită clauză, cu scopul de a găsi o soluŃie la întrebare.
Deoarece insa ca pentru un set de clauze date şi pentru o singură întrebare pot
exista mai multe clauze care se pot asocia acelei întrebări rezulta implicit ca se pot găsi
mai multe soluŃii pentru aceeaşi întrebare. Căutarea soluŃiilor alternative este posibilă
datorită procesului de backtracking pe care il initiaza maşina de inferenŃă in momentul
punerii unei întrebări.
Cele doua mecanisme se vor discuta in continuare.

1. Unificarea
Cum unificarea se defineşte ca fiind procesul de asociere între o întrebare şi o
clauză, trebuie precizat ce înseamnă procesul de asociere.

Procesul de potrivire in momentul realizarii acestuia intre corpul întrebării şi o


axioma sau regula poarta denumirea de unificare.

1.1.unificarea (matching)
Termenul de unificare se poate folosi cu diverse semnificaŃii, de exemplu: unificarea
unei întrebări cu o clauză, unificarea unei variabile cu o constantă, unificarea a două
12
InteligenŃă Artificială. Tehnici.

variabile, etc. În general există trei cazuri distincte de unificare, referindu-ne la nivelul cel
mai de jos al acestui proces :

(1) Structurile identice se asociază evident între ele.


-- avînd o clauză (axioma) de forma :

părinte(mircea, ioana). (f)

şi o întrebare :
? - părinte(mircea, ioana) (g)
evident structurile clauzei şi a întrebării sînt identice.
Fără nici o problemă se asociază :
-- predicatul din întrebarea (g) cu predicatul din clauza (f) -axioma
-- primul argument din întrebarea (g) cu primul argument din clauza (f)
-- al doilea argument din întrebarea (g) cu al doilea argument din clauza (f)

Ca urmare se poate spune că întrebarea (g) se asociază cu clauza (f), mai exact (g)
se unifică cu (f).

(2) O unificare se poate face şi cînd apar una sau mai multe variabile libere.
--Fie clauza (axioma) :

părinte (mircea, ioana). (a)

şi întrebarea :
? - părinte(mircea, X). (g)

care se traduce prin : ''Al cui părinte este Mircea? -''


În cadrul procesului deunificare (matching) dintre (g) şi (a), are loc :
--unificarea între predicatele întrebării (g) şi a clauzei (a)
--unificarea între primul argument din întrebare şi clauza
--unificarea între variabila X din întrebare şi argumentul ''ioana'' din
clauză; aceasta este posibilă doar dacă variabila X este liberă, iar în urma procesului de
unificare, variabila X se leagă de valoarea ''ioana''.
Obs : Dacă în momentul în care se încearcă unificarea, variabila X ar fi ''legată'',
unificarea reuşeşte doar dacă X ar fi legată de valoarea ''ioana''. Această situaŃie este de
fapt o variantă a cazului (1).
Variabilele ramîn ''legate'' pînă în momentul obŃinerii unei soluŃii pentru acea
13
InteligenŃă Artificială. Tehnici.

instanŃiere a lor, după care devin ''libere'' şi dacă este cazul, se caută alte soluŃii.
Astfel, singura posibilitate ca o variabilă dintr-o întrebare să fie ''legată'' în momentul
încercării unei asocieri este ca întrebarea să fie compusă, să implice mai mulŃi paşi;
variabila poate deveni ''legată'' într-un pas anterior.

Exemplu :
? - părinte(mircea, X) and părinte(X, anca).
Cu semnificatia: ''Găseşte pe cineva care este copilul lui Mircea şi este părintele lui
Anca.''
Întrebarea este compusă de fapt din două sub-întrebări, şi întotdeauna cînd se
ajunge la a doua sub-întrebare, variabila X este ''legată'' de o valoare. Prima sub-întrebare
se asociază conform cazului (2), a doua sub-întrebare conform cazului (1).

(3) Două variabile libere se asociază între ele.


--Fie clauzele :
tata (mircea, ioana). (a)
părinte(mircea, X) if
tata(mircea, X). (r)

şi întrebarea :
? - părinte (mircea, Y) (g)

Procesul de obŃinere a soluŃiilor la întrebarea dată este următorul:


(3.1.) Se unifică întrebarea (g) cu capul regulii (r) astfel :
-- se asociază predicatele ''părinte'' pentru (g) şi (r)
-- se asociază primul argument (care are valoarea ''mircea'') din (g) cu cel
din (r).
-- se asociază variabila liberă Y din (g) cu variabila liberă X din (r); ca urmare
cele două variabile se leagă între ele, procesul decurge în continuare tratîndu-le ca o
singură variabilă. Cînd una dintre ele se leagă de o valoare, automat şi cealaltă se leagă de
aceeaşi valoare.
Cînd se face o asemeneaunificare, variabilele devin ''variabile libere comune''
(free sharing variables).
(3.2.) După realizarea unificării între întrebarea (g) şi capul regulii (r), noua întrebare
pentru care se caută una sau mai multe soluŃii este :
tata(mircea, X) (g1)
obŃinută din corpul regulii (r).
(3.3.) Noua întrebare (g1) se unifică cu clauza (a), moment în care, conform cazului
(3.2.), variabila X devine ''legată'' de valoarea ''ioana''. Variabila X fiind comună cu
14
InteligenŃă Artificială. Tehnici.

variabila Y, rezultă că şi Y se leagă de aceeaşi valoare ''ioana''.

(4) O variabilă anonimă (''_'') se asociază întotdeauna cu orice.


-- Fie clauzele :
tata (mircea, ioana). (a1)
tata (sandu, ana). (a2)

şi întrebarea :
? - tata (X, _ ) (g)
tradusă astfel : ''Cine este tată ?'', fără a se cere şi cine este copilul.
(4.1.) În primul rînd se încearcă unificarea întrebării (g) cu clauza (a1):
-- se asociază predicatele ''tata'' pentru (g) şi (a1).
-- se asociază variabila liberă X din (g) cu valoarea ''mircea'' din (a1);
variabila X devine ''legată'' de valoarea ''mircea''
-- variabila anonimă din (g) se asociază cu orice ar fi pe poziŃia argumentului
doi din (a1).
(4.2.) Se returnează o soluŃie X = mircea.
(4.3.) Se revine la clauza (a2), unde întrebarea (g) încearcă o nouă unificare; în
prealabil variabila X a devenit ''liberă''. De data aceasta X se ''leagă'' de valoarea ''sanda''
, iar variabila anonimă din (g) se asociază cu argumentul ''ana'' din (a2).
(4.4.) Se returnează a doua soluŃie X = sanda.

Obs. : - în cadrul procesului de unificare a 2 termeni se mai foloseşte termenul de


''instanŃiere'' în loc de ''legare'' a unei variabile de o valoare; astfel, în exemplul de mai sus
se poate spune că variabila X se instanŃiază cu valoarea ''mircea'', apoi cu valoarea
''sandu''.

2. Backtracking
Este o metodă folosită de maşina de inferenŃă PROLOG pentru obŃinerea unei soluŃii
(eventual mai multe soluŃii) pentru o anumită problemă.
Din momentul în care maşina de inferenŃă a sistemului PROLOG începe căutarea
unei soluŃii pentru o întrebare dată, se poate ajunge în situaŃia de a decide între două sau
mai multe posibile căi pe care să se continue căutarea; în acest caz se fixează un indicator
pentru acest punct de ramificare (punct de backtracking) şi se selectează prima cale
pentru căutare. Dacă se termină cautarea pe această variantă, se revine la ''punctul de
backtracking'' şi se reia căutarea unei soluŃii pe următoarea cale disponibilă.
În continuare vom folosi şi noŃiunea de sub-întrebare (sub-scop); aceasta pentru a
exprima mai exact faptul că o întrebare (scop) poate fi compusă din mai multe sub-
întrebări.
15
InteligenŃă Artificială. Tehnici.

Cele patru principii de bază ale procesului de backtracking sînt:


(1) Sub-întrebările trebuie să fie satisfăcute (rezolvate) în ordinea în care
apar.
(2) Clauzele sînt testate în ordinea în care apar în program (de la începutul la
sfîrşitul programului).
(3) Cînd o sub-întrebare se unifică cu capul unei reguli, corpul acelei reguli
este cel care urmează să fie satisfăcut (rezolvat). Deci corpul regulii constituie un nou set
de sub-întrebări (sub-scopuri) ce trebuie rezolvate.
(4) O întrebare (scop) este satisfăcută cînd se găseşte cîte o axiomă pentru
procesul de unificare cu fiecare sub-întrebare pozitionată la extremităŃile arborelui de sub-
întrebări.

Algoritmul de căutare a soluŃiilor


Astfel, pentru a rezolva o sub-întrebare oarecare, sistemul PROLOG începe
căutarea cu prima clauză din setul de clauze care definesc predicatul ce apare în sub-
întrebare. Pot exista două situaŃii distincte :
(1.) Să se realizeze o unificare între sub-întrebare şi una din clauze, caz în care :
(a) - dacă mai există o altă clauză care ar putea să se unifice cu aceeaşi sub-
întrebare, sistemul PROLOG fixează un pointer (indicator, punct de backtracking) la
următoarea clauză, după cea pentru care s-a reuşit unificarea.
(b) - toate variabilele ''libere'' din sub-întrebare, care se asociază cu valori din
clauză devin variabile ''legate'' de valorile corespunzătoare.
(c) - dacă clauza cu care s-a reuşit unificarea sub-întrebării este capul unei
reguli, urmează evaluarea corpului acelei reguli; termenii ce formează corpul devin sub-
întrebări care trebuie satisfăcute în ordinea în care apar, pentru a putea spune că apelul la
acea clauză a reuşit.
(2.) Să nu se găsească nici o clauză care să se unifice cu sub-întrebarea dată.
Sistemul PROLOG revine la ultimul pointer de backtracking, eliberează de valori
toate variabilele care au fost ''legate'' după momentul poziŃionării acelui indicator de
backtracking, apoi încearcă să resatisfacă sub-întrebarea ce era activă în acel punct.
Conform algoritmului de căutare a soluŃiilor descris mai sus, se poate dezvolta un
arbore al întrebărilor (goal tree), după cum se descrie în continuare .
Exemplu :
Fie secvenŃa de program PROLOG :
mîncare (pui-grill). % A1
mîncare (lup_de_mare). % A2
mîncare (guvid). % A3
băutura (coca_cola). %A4
băutura (bere). %A5
16
InteligenŃă Artificială. Tehnici.

lista_meniu (X) :- %R1


mîncare (X).
lista_meniu (X) :- %R2
băutura (X).
dif (Y, Z) :- Y< >Z.

şi întrebarea compusă :
Goal : lista_meniu (X) , dif (X, guvid).
Modul de căutare a soluŃiilor se poate reprezenta sub forma următorului arbore,
parcurgerea fiind de sus în jos, şi de la stînga la dreapta:

2.6. Exemplu
Vom incerca sa exemplificam acest mecanism prin rezolvarea unei enigme logice.
Patru copii, Ion, Petru, Gabriel şi Dan, se joacă în curte cu mingea şi sparg un geam.
Fiecare spune ca nu a facut-o el, dar mai afirmă că:
Ion spune că Petru şi Gabriel sunt mincinoşi.
Gabriel spune ca Ion, Petru şi Dan sunt mincinoşi.
Dan spune ca Ion, Petru şi Gabriel sunt mincinoşi.
Cine spune adevărul?
Din analiza setului de afirmaŃii rezultă doua axiome elementare:
1.-o persoana spune despre celelalte două că mint
2.-o persoana spune despre celelalte trei că mint

17
InteligenŃă Artificială. Tehnici.

doi_mint(A,B,C) A spune că B şi C mint.


trei_mint(A,B,C,D) A spune că B, C şi D mint.
Cele două axiome conduc la un număr de 12 clauze ca urmare a combinaŃiilor ce
pot apare. Din considerente de simplificare vom considera că
% mincinos=m cinstit=c
predicates
doi_mint(symbol,symbol,symbol)
trei_mint(symbol,symbol,symbol,symbol)
cine_minte(symbol,symbol,symbol,symbol)
clauses
doi_mint(m,m,c).
doi_mint(m,c,m).
doi_mint(m,c,c).
.
.
cine_minte(Ion,Petru,Gabriel,Dan) if
doi_mint(Ion,Petru,Gabriel),
doi_mint(Petru,Ion,Gabriel),
trei_mint(Gabriel,Ion,Petru,Dan),
trei_mint(Dan,Ion,Petru,Gabriel).
Goal:
? - cine_minte(Ion,Petru,Dan,Gabriel)
Ion=m, Petru=m, Gabriel=c, Dan=m
1 solution

Remarcă.
Practic intrebarea parcurge prin intermediul mecanismului de inferenŃă informaŃia
din baza de date, pană in momentul in care prin cautare şi unificare realizate in etape
succesive se indeplinesc toate restrictiile impuse de axiomele prezente in baza de
cunoştinŃe din sectiunea clauses.

Exercitii
1) Presupunem ca avem urmatoarea baza de cunoştinŃe:

a(1,1). a(2,1). a(3,2). a(4,4).


b(1,2). b(1,3). b(2,3). b(3,2). b(4,4).

(a) Care este raspunsul la intrebarea ?- a(X,Y),b(X,Y)


(b) Care este raspunsul la intrebarea ?- a(X,Y),b(X,Y),a(Y,Y)

2) Intr-o baza de cunoştinŃe exista N axiome a caror nume este p cu un argument şi


M axiome cu un argument a caror nume este q.

(a) Care este numarul maxim de raspunsuri , fara a contoriza cele de tip nu, care se
obtin la intrebarea :
?- p(X), q(Y).
(b) Care este numarul maxim de raspunsuri care se obtin la intrebarea
?- p(X), q(X).

18
InteligenŃă Artificială. Tehnici.

3. STRUCTURI DE DATE 1.
În acest capitol se vor discuta doua mari probleme:
- prima este legată de structurile de date utilizate pentru descrierea elementelor
care apar in propoziŃiile şi frazele din limbaj natural care se transpun intr-o baza
de cunostinŃe;
- cea de a doua problemă se referă la faptul că in baza de cunostinŃe se pot
introduce strategii suplimentare de explorare a cunostinŃelor prezente, acestea
vor complecta maşina de inferenŃă şi o vor face mai selectivă şi specifică in
actiunea sa in momentul interogarii.

3.1. Obiecte compuse.


În general obiectele şi fenomenele analizate ( prezente in faptele descrise in baza de
cunostinŃe) nu sunt indivizibile, ele fiind compuse la rândul lor din componente ce pot
conŃine sau nu alte componente. Această stare de fapt a necesitat introducerea noŃiunii de
obiect compus în Prolog deoarece în lipsa acestuia pot apare ambiguităŃi. De exemplu
afirmaŃile Dan are cartea "Cei trei muşchetari" şi Dan are AT 586 se traduc prin:
carte("Cei trei muşchetari").
calculator(at586).
are(dan,"Cei trei muşchetari").
are(dan,at586).
La întrebarea ce are Dan se răspunde:
? - are(dan,X)
X="CEi trei muşchetari"
X=at586
2 solutions
fara să se stie dacă at586 este carte sau un alt obiect. Acest motiv a generat noŃiunea de
obiect compus definit sub forma:
nume_obiect (element1,element2,...,elementm)
unde nume_obiect este numele obiectului, iar elementi atributele componente care
caracterizeaza obiectul in cauza. Deoarece pot exista mai multe obiecte care aparŃin
aceleaşi clase, devine necesară definirea lor separat în secŃiunea domains de forma:

domains
clasa_obiecte=obiect_1(...);
obiect_2(...);
.
.
obiect_k(...);

Pentru exemplul dat vom avea:


domains
obiecte=carte(nume_carte,autor);
calculator(tip);
nume_p, nume_carte, autor, tip=symbol
predicates
are(nume_p, obiecte)
19
InteligenŃă Artificială. Tehnici.

clauses
are(dan, carte("Cei trei ...", "Al.Dumas")).
are(da,. calculator(at586)).

Comentarii:
1.-domeniul string este un subdomeniu al celui symbol
2.-o întrebare se poate pune sub forma:
a)?-are(dan,X)
X=carte(...,...)
X=calculator(...)
b)?-are(dan,carte(_,A))
A="Al.Dumas"
1 solution
S-a specificat că elementele componente pot fi la rîndul lor divizate în alte
subansamble cea ce corespunde de fapt situaŃiei din lumea reală. De exemplu, autorul
poate fi divizat în nume şi prenume. în aceste condiŃii exemplul poate fi rescris sub forma:
domains
obiecte=carte(nume_carte,autor);
calculator(tip)
autor=autor(nume,prenume);

Observatii:
1.-se observa apariŃia unui arbore a cărui rădăcină este functorul, nodurile sunt
elementele componente ce se pot divide în subansamble iar frunzele sunt elemente
indivizibile.

2.-pentru elementele care se împart în alte componente definirea domeniului este identică
cu cea a functorului
clasa=obiect(element1,...,elementk);
element1=element1(s1,...,sm);
s1=s1(...);

20
InteligenŃă Artificială. Tehnici.

3.2 Recursivitate
Pană in present, baza de cunostinŃe este alcatuita numai din fapte care au
corespondent propoziŃii şi fraze din limbajul natural care se referă la o anumită problemă şi
care sunt analizate de o maşina de inferenŃă prezentă in cadrul limbajului Prolog. Este
evident ca in multe situaŃii mecanismul de inferenŃă pus la dispozitie este insuficient de
selectiv, ceea ce face ca gasirea solutiei sa dureze mult sau sa fie imposibila de obtinut,.
Acest aspect face ca natura problemei analizate sa impuna utilizarea unor strategii
specifice de explorare, care evident vor trebui sa fie integrate in contextual maşinii de
prezente. Pentru a putea complecta maşina de inferenŃă cu aceste strategii devine
necesară prezenŃa unui mecanism de construire a acestora. Acest mecanism este dat de
recursivitate şi este utilizat pentru construirea regulilor ce descriu strategii specifice unei
baze de cunostinŃe particulare. Prin urmare in cazul general o baza de cunostinŃe poate fi
formată la nivelul sectiunii clauses din:
Clauses
CunostinŃe (premise şi reguli)
Strategii de explorare a cunoştinŃelor care
cooperează cu maşina de inferentă

Strategiile complementare sunt la randul lor formate din premise şi reguli, insa de
data aceasta ele nu mai descriu fapte din lumea inconjuratoare ci modul in care acestea
pot fi explorate. PrezenŃa acestui mecanism dă posibilitatea de asemenea de a extinde
tehnicile de reprezentare a informaŃiilor prezente in fraze şi propoziŃiile din limbajul natural
care in pană acum nu erau posibil de rezolvat, prin introducerea a ceea ce poarta
denumirea de obiect recursiv.

3.2.1 Reguli recursive.


O regulă apelată în corpul propriei sale definiŃii poartă denumirea de regulă
recursivă.
Exemplul 1:
ConstruiŃi o procedura care să calculeze F=N!.
domains
nr , valoare=real
predicates
f ( nr,valoare )
clauses
f ( 1,1 ).
f ( N,Rez ) if N>1,
N1=N-1,
F ( N,Rez1 ),
Rez=N * Rez1.
Goal: f ( 4,R )

21
InteligenŃă Artificială. Tehnici.

În momentul construirii unor apeluri recursive se va Ńine seama de faptul că:


1 - este obligatorie prezenŃa unei axiome care să definească punctul din care începe
rezolvarea apelurilor recursive;
2 - datorită faptului că apelul se face sub controlul mecanismului de inferenŃă, devine
necesară amplasarea unei condiŃii care să stopeze acest mecanism. Stoparea are loc
atunci când condiŃia este falsă. În lipsa acestei conditii mecanismul de backtracking intră în
ciclu infinit.
Exemplul 2:
ConstruiŃi o procedură care să construiască numerele din şirul lui Fibonacci. Un
numar se va identifica prin numărul lui în şir.
Termeni 1 1 2 3 5 8 13 21
Nr. termeni 1 2 3 4 5 6 7 8

| 1 pentru n=1;
f ( 0 )= { 1 pentru n=2;
| f ( n-1 ) +f ( n-2 ) pentru n>2;

predicates
f ( integer,integer )
clauses
f ( 1,1 ).
f ( 2,1 ).
f ( N,T ) if N>2,
N1=N-1,
f ( N1,T1 ),
N2=N-2,
f ( N2,T2 ),
T=T1-T2.

3.2.2 Obiecte recursive.


In lumea inconjuratoare există multe situaŃii in care numărul de elemente ce o
descriu este variabil de un moment la altul. Aceasta variabilitate se mentine şi in frazele din
limbajul natural care le descriu. Ca urmare, a apărut necesitatea de a descrie obiecte a
căror număr de componente nu este cunoscut aprioric, ceea ce a dus la apartia structurii
de tip obiect recursiv.
Un obiect recursiv se declara sub forma:
nume_obiect ( element ,empty )
element - defineşte o componenta a obiectului;
empty - obiect fară nici o componentă.

În acest contextual acestei definitii,o grupă de studenŃi poate apare sub forma:
grupa ( ion ,empty ) - grupa cu 1 student;
22
InteligenŃă Artificială. Tehnici.

grupa ( ion ,grupa ( radu ,empty )) - grupa cu 2 studenti;

Exemplu :
ConstruiŃi o procedură care să calculeze expresii de forma: 1-2+3-4+5.....UtilizaŃi un
obiect recursiv pentru descrierea unei astfel de expresii. Se va folosi forma prefixată
poloneză pentru scrierea expresiilor.
De exemplu:
7-3+10-20+11 se poate scrie +(-(+(-(7,3),10),20)11)

Baza de cunoştinŃe este formata practice in acest caz de strategia de explorare a unei
expresii care se specifica in momentul punerii unei întrebări.

domains
expr=num ( real );
min ( expr,expr );
plus ( expr,expr )
predicates
rezolvă ( expr,val )
clauses
rezolvă ( num ( X ), X).
rezolvă ( min ( E1,E2 ),R ) if rezolvă ( E1,R1 ),
rezolvă (E2,R2 ),
R=R1-R2.
rezolvă ( plus (E1,E2 ),R ) if rezolvă ( E1,R ),
rezolvă ( E2,R2 ),
R=R1+R2.

ObservaŃie:
Expresia din exemplul anterior se scrie şi se pune intrebarea de forma:
?-E=plus( min ( plus( min( num ( 7 ),num ( 3 ) ),num ( 10 ) ),num ( 20 ) ),num ( 11 ) ),
rezolvă ( E,R )
R=5
1 solutions

23
InteligenŃă Artificială. Tehnici.

4. STRUCTURI DE DATE 2.
Pană in prezent am utilizat propoziŃii şi fraze pentru a descrie situaŃii care urmeaza
sa fi analizate de maşina de inferenŃă in contextul unor întrebări puse de utilizator. Aceasta
interogare, asa cum s-a vazut putea fi complectată de utilizator prin definirea unor strategii
proprii care sunt de asemenea cuprinse in baza cunostinŃe. Diversitatea situaŃiilor care apar
in lumea reală impune complectarea modalitatilor de concepere a bazelor de cunostinŃe
prin posibilitatea definirii de structuri in care să se incadreze obiecte, fapte sau chiar seturi
de propoziŃii sau fraze care se refera la acelaşi aspect. Ca urmare s-au definit noi structuri
de organizare a informaŃiilor care se adauga la cele existente ( obiecte compuse, respectiv
obiecte recursive ). Aceste noi structuri sunt:
- liste
- arbori
- grafuri.

4.1. Liste. DefiniŃie. Caracteristici.


O listă reprezintă un obiect compus (multime) cu elemente de acelaşi tip. Lista este
definită de o construcŃie de forma
[ element1 ,element2 ,.......elementn ].
Din punctul de vedere al limbajului Prolog lista este vazută ca o structură formată din
capul listei ( primul element) şi coada listei (restul elementelor rămase după îndepărtarea
capului ). Pentru a specifica partajarea în cele doua componente se utilizeaza semnul | (
bara verticală ). Cu aceste specificatii, sunt liste următoarele constructii de mai jos:

Lista Cap Coada Mod de scriere


[ 1, 2 ,3 ] 1 [ 2,3 ] [ 1| 2,3 ]
[ ion,dan,radu ] ion [ dan,radu ] [ ion|dan,radu ]
[a] a [] [a|[]]
[] nedefinit nedefinit nedefinit

Mecanismul de backtracking ,atunci când sunt implicate 2 liste ,încearcă legarea


elementelor primei liste la elementele listei a doua:

Lista1 Lista2 Valoare


[ 1,2,3 ] [ x,y,z ] x=1,y=2,z=3
[ 1,2,3 ] [ x|y ] x=1,y=[ 2,3 ]
[ ion ] [x|y ] x=ion,y=[ 2,3 ]
[ 1,2,3,4 ] [ x,y|z ] x=1,y=2,z=[ 3,4 ]
[ 1,2,3 ] [ 3,y ] eroare

O listă se declară în secŃiunea domenii ,specificând domeniul la care aparŃin elementele


listei , urmat de semnul * ( stea ):
24
InteligenŃă Artificială. Tehnici.

domains
list=integer * %-> [ 1,2,3 ]
list1=symbol * %-> [ a,ana,alfa,beta ]
Elementele listei pot fi inclusiv liste, obiecte compuse sau alte structuri utilizator.
Exemple de liste astfel structurate sunt date in continuare.
domains
el=integer *
lista=el* %A -> [ [ 1,2 ], [ ],[ 4 ] ]
expr=n( real ); p ( expr,expr ); m ( expr,expr )
lista1=expr * % -> [ [ n ( 7 ),p ( n (3 ),n ( 2 ) ),....]

4.2 OperaŃii elementare pe liste


O dată definite astfel de structuri devine evident faptul ca sunt necesare mecanisme
de explorare a elementelor care sunt prezente, mecanisme care sa poată fi utilizate ulterior
in strategiile complementare maşinii de inferentă.
Aceste mecanisme elementare se refera la:

4.2.1 ApartenenŃa.
ConstruiŃi o procedură care să determine dacă un element aparŃine sau nu la o listă
de elemente. La construire se pleacă de la observaŃia: elementul aparŃine listei dacă este
identic cu capul listei sau aparŃine cozii acesteia. Prima parte conduce la o axioma ,a doua
la definirea unei reguli recursive.
domains
L=integer *
predicates
aparŃine ( integer,L )
clauses
aparŃine ( X,[ X| _ ] ).
aparŃine ( X, [ _|R ] ) if apartine ( X,R ).

Pe acest mecanism vom prezenta şi cele doua moduri de interogare prin care un
utilizator se poate adresa mecanismului de inferenŃă şi strategiilor complementare acestuia.
Aceste moduri sunt cunoscute sub denumirea de:
- mod de lucru declarativ;
- mod de lucru procedural.

• Interogarea declarativă : - în modul de lucru declarativ se verifică dacă relaŃia


este adevărată pentru variabilele declarate prezente, singurul răspuns posibil
fiind DA sau NU. De exemplu:
?- aparŃine (2, [ 1,2,3,4 ] ) - variabilele sunt de tip intrare ,intrare
Yes.

25
InteligenŃă Artificială. Tehnici.

• Interogarea procedurală : - se urmăreşte obŃinerea unui rezultat ,cel puŃin una


dintre variabile fiind de ieşire. Pentru procedura de apartenenŃă întrebarea se
pune astfel: "Care sunt elementele care aparŃin listei specificate ?"
?- aparŃine ( X,[ 1,2,3,4 ] ) - variabilele sunt de tip ieşire ,intrare
X=1
X=2
X=3
X=4
4 soluŃii.

4.2.2 Concatenarea
Reprezintă operaŃia prin care se obŃine o a treia listă din unirea elementelor a doua
liste date. De exemplu
conc ( [ 1,2 ],[ 3,4 ],R )
R=[ 1,2,3,4 ]

Procedura de concatenare rezultă din următoarea strategie:


a ) rezultatul concatenării dintre o listă vidă şi una nevidă este o listă nevidă;
b ) doua liste nevide se concateneaza transferând succesiv câte un element din una din
liste în a treia listă.
domains
L=integer*
predicates
conc ( L,L,L )
clauses
conc ( [ ],L,L ).
conc ( [ X|L1 ],L2,[ X|L3 ] ) if conc ( L1,L2,L3 ).

Predicatul prezintă cele doua moduri de interogare:


a ) declarativă:
"Este L3 rezultatul concatenarii lui L1 şi L2 ?"
?- conc ( ( [1,2,3 ],[ 4,5 ] ,[1,2,3,4,5]) - ( intrare,intrare,intrare )
Yes.
b ) procedurală:
"Care sunt listele care prin concatenare duc la L3 ?"
?- conc ( L1,L2,[ 1,2,3 ] ) - ( ieşire,ieşire,intrare )
L1=[ ] L2=[ 1,2,3 ]
L1=[ 1 ] L2=[ 2,3 ]
l1=[ 1,2 ] L2=[ 3 ]
L1=[ 1,2,3 ] L2=[ ]
4 soluŃii.

26
InteligenŃă Artificială. Tehnici.

4.2.3. OperaŃii auxiliare la concatenare.


OperaŃia de concatenare poate fi utilizată pentru obŃinerea unor informaŃii
suplimentare despre structura listei în felul următor:
1 - se poate determina lista care precede şi urmează după un element dat:
?- conc (Inainte, [ 3|Dupa ], [ 1,2,3,4,5 ] )
Inainte=[ 1,2 ] Dupa=[ 4,5 ]

2 - se poate obŃine elementul care precede sau urmează unui element dat dintr-o lista sub
forma:
?- conc ( _ ,[ Inainte,3,Dupa| _ ], [ 1,2,3,4 ] )
Inainte=2 Dupa=4.

3 - se poate construi mecanismul de apartenenŃa a unui element la o listă de forma:


aparŃine ( X,L ) if conc( _ , [ X| _ ] ,L ).

4 - se poate construi o procedură de ştergere aunui element dintr-o listă de forma:


şterge ( X,L,R ) if conc ( L1,[ X|L2 ],L ),
conc ( L1,L2,R ).

5 - se pot determina sublistele care aparŃin unei liste date:


De exemplu lista [ 3,4 ] este sublistă în [ 1,2,3,4,5,6 ].
Modul de lucru: S este sublistă a lui L, dacă L poate fi descompus în două subliste
L1 şi L2 şi dacă la rândul lui L2 poate fi descompus în S, L3.
subl ( L,S ) if conc ( L1,L2,L ),conc( S,L3,L2 ).

Procedura de tip sublistă prezintă ambele moduri de interogare :


a ) declarativ:
?- subl ( [ 1,2,3,4,5 ] ,[ 3,4 ] ) - ( i,i )
Yes
b ) procedural: "Care sunt sublistele ce rezultă dintr-o lista dată ?"
?- subl ( [ 1,2,3 ],S )
S=[ ]
S=[ 1 ]
S=[ 1,2 ]
....
7 soluŃii.
Se poate obŃine răspunsul NU şi în cazul modului procedural ,atuncia cand nu se
poate lega variabila.

4.2.4. Inserarea unui element.


OperaŃia presupune generarea prin backtracking a tuturor variantelor care se obŃin
prin inserarea unui element în fiecare poziŃie a unei liste.
27
InteligenŃă Artificială. Tehnici.

?- inser ( 0, [ 1,2,3 ],R )


R=[ 0,1,2,3 ]
R=[ 1,0,2,3 ]
R=[ 1,2,0,3 ]
R=[ 1,2,3,0 ]
4 solutii.
Modul de inserare a fost dezvoltat sub forma:
a ) elementul de inserat devine capul listei;
b ) elementul de inserat devine capul cozii listei.
domains
L=integer*
predicates
inser ( integer,L,L )
clauses
inser ( X,L,[ X|L ]. - devine capul listei;
inser ( X,[ Y|L1 ],[ Y|L2 ] ) if
inser ( X,L1,L2 ).

Procedura prezintă cele două moduri de interogare:


a ) declarativ:
?- inser ( 0,[ 1,2,3 ],[ 1,0,1,2,3 ] ) - ( i,i,i ) Yes.
b ) procedural:
?- inser ( 0,[ 1,2,3 ],R ) - ( i,i,o ) Yes

4.2.5. Permutarea.
Este operaŃia prin care sunt generate toate permutările posibile de generat cu o listă.
Aplicând permutarea asupra listei [ 1,2,3 ]:
?- perm ( [ 1,2,3 ] ,R )
R=[ 1,2,3 ]
R=[ 1,3,2 ]
......
6 soluŃii.
Procedura rezultă din următoarele observatii:
a ) rezultatul permutarii unei liste vide este lista vidă;
b ) dacă lista nu este vidă se permută coada listei ,după care se inserează capul listei
iniŃiale în lista cu elementele permutate.
domains
L=integer*
predicates
inser ( integer,L,L )
permut ( L,L )
clauses
permut ( [ ],[ ] ).
permut ( [ X|L ],R ) if permut ( L,L1 ),
inser ( X,L1,R ).

4.2.6. Stergerea unui element.


Construim o procedură care să efectueze ştergerea unui element dintr-o listă.

28
InteligenŃă Artificială. Tehnici.

Modul de ştergere urmăreşte strategia:


- elementul poate fi şters dacă este capul listei ,dacă nu, ştergerea continuă pe coada
acestuia. Procedura prezintă aspectul.
domains
L=integer*
predicates
sterg(integer,L,L))
clauses
sterg ( X, [ X|L ], L ).
sterg ( X, [ Y|L1 ], [ Y|L2 ] ) if sterg ( X, L1, L2 ).

Procedura prezintă cele doua moduri de interogare:


a ) declarativ:
?- sterg (2,[ 1,2,3 ],[ 1,3 ] ) Yes.
b ) procedural:
?- sterg ( 2,[ 1,2,3 ],R )
R=[ 1,3 ]
R=[ 1,2,3 ]
2 soluŃii.
Sa consideram următorul exemplu:
?-sterg ( 2,[ 1,2,3,2,4 ],R )
R=[ 1,3,2,4 ]
R=[ 1,2,3,4 ]
R=[ 1,2,3,2,4 ]
Se observă că se şterge primul element întâlnit şi elementele următoare de acelaşi
tip dupa care se recompune inclusiv lista iniŃială. SituaŃia apare ca urmare a interferentei
dintre maşina de efectuat deductii logice din Prolog şi modalitatile de rezolvare a apelurilor
recursive.
Pare ca rezultatul este incorect, de fapt insa maşina de inferenŃă ofera utilizatorului
intreg spaŃiul de soluŃii posibile, ramanand la alegerea acestuia sa defineasca criterii de
alegere a solutiei corecte din punctul sau de vedere.
?-sterg ( X,[ 1,2,3 ],R ) - ( o,i,o )
X=1 R=[ 2,3 ]
X=2 R=[ 1,3 ]
X=3 R=[ 1,2 ]
3 soluŃii - în acest mod nu mai apare [ 1,2,3 ] ca solutie.

Procedura de ştergere se observa ca poate acŃiona în 2 etape: - iniŃial se


detectează elementul care urmează a fi şters ,după care se procedează la stergerea
acestuia.

29
InteligenŃă Artificială. Tehnici.

Operatii auxilare cu procedura sterge


a ) inserarea unui element intr-o listă sub forma:
inser ( X,L,R ) if sterg ( X,R,L ). - ( i,o,i )

b ) se poate construi o procedură de tip apartenenŃă sub forma:


aparŃine ( X,L ) if sterg ( X,L,_ ).

c ) se poate construi o procedură care să ştergă toate apariŃiile unui element de acelaşi tip
dintr-o listă:
clauses
sterg ( X,[ X|L ],L1 ) if sterg ( X,L,L1 ).
sterg ( X,[ Y|L1 ], [ Y|L2 ] ) if sterg ( X,L1,L2 ).

4.3. Exemple.
(1) ConstruiŃi o procedură care plecând de la o listă de numere cuprinse între 0 şi 9
să construiască o listă a cărei elemente sunt cuvintele corespunzătoare elementelor din
prima lista.
De exemplu:
tradu ( [ 1,0,4 ],R )
R=[ unu,zero,patru ]

Procedura prezintă aspectul:


domains
l1=integer *
l2=symbol *
predicates
tradu ( l1,l2 )
înseamnă ( integer,symbol )
clauses
înseamnă ( 0,zero ).
înseamnă ( 1,unu ).
........
înseamnă ( 9,noua ).
tradu ( [ ],[ ] ).
tradu ( [ T|L1 ],[ TR|L2 ]) if înseamna ( T,TR ),
tradu ( L1,L2 ).

Procedura prezintă în cazul apelului procedural modalitătile ( i,o ) şi ( o,i ).

Exercitii
1) ConstruiŃi o procedură care să construiască o listă a carei elemente sunt în
ordine inversă în raport cu elementele listei iniŃiale.
exemplu: ?- invers ( [ 1,2,3 ],R )
R=[ 3,2,1 ]

30
InteligenŃă Artificială. Tehnici.

Procedura trebuie să admită atât modul declarativ cit şi cel procedural ,în cele două
variante ( i,o ) şi ( o,i ).

2) Construiti un predicat de tip 'taie(A,B)' care elimina elementele de acelaşi tip din
lista A care apar de mai multe ori şi retine in lista B elementele o singura data. De exemplu:
?- taie([a,1,b,2,a,3,a,4,b],B).
B = [a,1,b,2,3,4]

3) Implementati utilizand predicate de tip concatenare un predicat de forma:


before(Element1,Element2,ListaElemente)
care sa fie adevarat daca Element1 apare in ListaElemente in fata lui Element2.
De exemplu: ?- before(4,2,[5,8,4,0,2,12])
Yes
?- before(4,8,[5,8,4,0,2,12])
No

31
InteligenŃă Artificială. Tehnici.

5. OPERAłII ARITMETICE şi RELAłIONALE


5.1. Expresii aritmetice
Chiar dacă principalul scop a maşinii de inferenŃă este acela de a efectua
deducŃii logice, funcŃie de întrebările puse aceasta dispune şi de facilitati de a
efectua calcule matematice in domeniul intreg şi real. Ca urmare maşina de
inferenŃă accpta ca in cadrul unor expresii aritmetice sa apara numere şi variabile
despartite prin operatori aritmetici clasici : + , -- , * , mod , div , / ,etc ...
Expresiile pot sau nu fi delimitate de paranteze . Regulile de evaluare a
unor expresii aritmetice, respectă convenŃiile standard referitoare la evaluarea
operanzilor şi parantezelor .
5.2. Expresii relaŃionale
Pot fi comparate expresii aritmetice , caractere , şiruri şi respectiv
simboluri . Operatorii relaŃionali :
< , > , <= , >= , <> , = .

Modul de aplicare este cel standard ,cu observaŃia că pentru variabile de


tip string se efectuează compararea codului ASCII a caracterelor intilnite.

5.3. Exemple
1. ConstruiŃi o procedură care să calculeze numărul de elemente ale unei
liste. Predicatul este de forma: nr(lista,nr_elemente). Regulile de construcŃie
pornesc de la două observaŃii :
- lungimea unei liste vide este 0
-dacă lista nu este vidă, lungimea este dată de 1 (lungimea capului listei)
+ lungimea cozii listei. Procedura prezintă aspectul:
clauses
nr([ ], 0).
nr([ _ | Rest ],N) if
nr(Rest, N1),
N=1+N1.

32
InteligenŃă Artificială. Tehnici.

O intrebare se pune de forma:


?- nr([ a,b,c],R)
R=3
1 solutie
2. ConstruiŃi o procedura care să determine elementul maxim al unei liste.
Considerăm un predicat de forma
maxim(lista,element_maxim)
Procedura rezultă din observatiile:
a) Dacă lista este formată dintr-un singur element ,atunci max este elementul
respectiv .
b) În caz contrar, max se obŃine prin compararea capului listei cu maximul
cozii listei.
ObservaŃie: OperaŃia de comparare presupune prezenŃa unui predicat
suplimentar care să compare două elemente, de forma:
max(X, Y, maxin_dintre_X_Y)
Procedura prezintă aspectul:
clauses
maxim ([X] , X).
maxim ([X| Rest], Maxim) if
maxim (Rest, Max_rest)
max( X, Max_rest, Maxim).
max (A,B,A) if A>=B.
max (A,B,B) if A<B.

Goals:
?-maxim ([7,3,9,0], M)
M=9
Comentarii
Regula maxim divizează lista în elemente componente, reŃinându-le în stiva.
Când lista se reduce la un singur element ,începe rezolvarea apelurilor
recursive, moment in care regula max funcŃionează ca un filtru intre 2
elemente reŃinându-se de fiecare dată pe cel mai mare găsit.

33
InteligenŃă Artificială. Tehnici.

3. ConstruiŃi o procedură care să determine c.m.m.d.c dintre 2 valori


numerice , x, y .Considerăm un predicat de forma:
cmmdc(x, y, rezultat)
Se pleacă de la considerentul :
--Dacă X=Y cmmdc este unul dintre cele două
--Dacă X>Y cmmdc se obŃine între X şi Y-X
--Dacă X<Y cmmdc se obŃine între X şi Y-X
Procedura prezintă aspectul:
clauses
cmmdc(X, X ,X).
cmmdc(X,Y,R) if
X>Y, X1=X-Y, cmmdc(X1,Y,R) .
cmmdc(X, Y, R) if
X<Y, Y1=Y-X, cmmdc(X,Y1,R) .

exemplu: ?-cmmdc( 15,20,R)


R=5

Exercitii
(1) ExerciŃii:specificaŃi dacă intrebările:
?- nr(L,4)
?- nr([a,b,c],3)
sunt corecte sau nu.
(2) Procedura max definite anterior acceptă sau nu modul de lucru declarativ ?
Se acceptă o întrebare de forma ?- maxim(L,9)
(3) Sunt acceptate de către procedura cmmd definita anterior întrebări de forma:
-cmmdc(15,20,5)
-cmmdc (X,20,5)
-cmmdc (15,Y,5)

34
InteligenŃă Artificială. Tehnici.

6. DETERMINISM ŞI NEDETERMINISM ÎN BAZELE DE


CUNOŞTINłE

Asa cum s-a specificat maşina de inferenŃă in momentul in care actioneaza


asupra unei baze de cunoştinŃe in contextual unei întrebări adresate de utilizator
va furniza intregul spaŃiu de solutii posibile. Acest aspect care se datoreste
modului specific de functionare a mecanismului de backtracking Prolog face ca
solutiile oferite sa aiba un caracter nedeterminist şi implicit ca intreaga baza de
cunoştinŃe formata din cunoştinŃe propriuzise şi din strategii complementare sa
aiba un character nedeterminist.

6.1. Problematica.
Pentru a ilustra conceptul de clauză deterministă ,respectiv
nedeterministă , considerăm exemplul definit de ştergere a unui element dintr-o
listă .SecvenŃa de clauze pentru un predicat de forma:
sterg(element, lista, rezultat) este

sterg( _ , [ ] , [ ] ).
sterg (X, [ X | R ], R).
sterg(X, [ Y | R1] , [ Y | R2 ]) if
sterg(X ,R1, R2).
Pentru o intrebare de forma:
?-sterg(2,[1,2,3,2,4],R) apare următoare structura de explorare a bazei de
cunoştinŃe de catre maşina de inferenŃă:

35
InteligenŃă Artificială. Tehnici.

Cu * s-a notat momentul in care incep rezolvarile apelurilor recursive şi refacerea


listelor parcurgand in sus arborele spre radacina ( notaŃia [1| R] insemna ca 1 se
reŃine in stivă, iar procedura de stergere se aplica pe Rest ). Ca urmare rezultă
nu o solutie ci un spaŃiu de soluŃii de forma:
[1,2,3,4] [1,2,3,4] [1,2,3,2,4] => 3 solutii
Datorită modului de construcŃie a mecanismului de backtracking şi a
complectarii acestuia cu mecanismul de rezolvare a apelurilor recursive, în cazul
general se obŃin mai multe soluŃii . Acest aspect imprimă un caracter
nedeterminist clauzelor din baza de cunoştinŃe . Apare logic necesitatea de a
selecta din multitudinea de soluŃii obŃinute pe acelea care corespund
obiectivului din momentul respectiv. Pentru rezolvarea acestui aspect maşina de
inferenŃă dispune de un mecanism de selectie a solutiilor care este activat de
catre utilizator, daca considera ca este necesara alegerea unei anumite solutii.
Mecanismul este activate de un element de tăiere , definit prin ! (cut) al cărui
efect constă în interzicerea deplasării pe anumite direcŃii din spaŃiul soluŃiilor .
Denumirea de element de tăiere provine din faptul că efectiv se taie o ramură
sau mai multe din graful ce defineşte spaŃiul soluŃiilor.
De exemplu : amplasând elementul ! (cut) pe regula şterg ,efectul se
manifestă prin taierea ramurii drepte, ceea ce are ca efect obŃinerea unei singure
soluŃii.

6.2. Modul de acŃiune a elementului de tăiere (!).


Pentru a explica modul de funcŃionare al elementului ! considerăm o
regulă de forma :
H if B1, B2, … Bm, !, Bm+1, … Bn.
Presupunem ca H a realizat unificarea cu o întrebare care apare în Goal. Prin
mecanismul de căutare în intervalul B1, B2, … Bm, presupunem că s-a găsit o
soluŃie. În momentul atingerii elementului de tăiere, soluŃia găsită este îngheŃată,
operaŃia fiind echivalentă cu ştergerea pointerilor (amplasati de maşina de
inferenŃă) de pe clauzele B1, B2, … Bm. Căutarea continuă pentru Bm+1, … Bn,

36
InteligenŃă Artificială. Tehnici.

în care sunt permise toate soluŃiile posibile. Cu alte cuvinte spaŃiul soluŃiilor este
format din soluŃia definită de B1, … Bm şi variantele oferite de Bm+1, … Bn.
Elementul de tăiere îşi extinde acŃiunea şi pentru clauzele Horn de acelaşi
nume care urmează după acelea în care este prezent.
Sa consideram următoarea situaŃie:

H if P,Q,R,!,S,T,U.
H if U,V . % -> această regulă nu se mai execută
A if B,H,C. %->nu ne mai putem întoarce pentru B
A

Elementul de tăiere va afecta execuŃia lui H astfel: backtrackingul este


posibil în interiorul Ńintelor P,Q,R până în momentul în care ! este atins şi soluŃia
rămine definitiva, toate alternativele posibile fiind eliminate. Rămân în continuare
alternativele relaŃive la Ńintele S,T,U. Următoarea clausa H nu va fi executată
(ştergerea pointerilor fiind efectivă, inclusiv la nivelul clauzei în care se gaseşte).
La nivelul clauzei A, ( în care elementul de tăiere este invizibil ) se oferă de
fiecare dată o singură alternativa la nivelul lui B,H şi una sau mai multe la nivelul
lui C. Următoarea clausa A va fi executată. Deci elementul de tăiere are un efect
local numai la nivelul clauzelor cu acelaşi nume.

Reguli de amplasare
Amplasarea lui ! depinde de contextul întrebării puse.Se recomandă utilizarea
următoarelor 2 metode:

1. Elementul de tăiere se amplasează pe axioma care implementează


întrebarea pusă.
sterge(2,[1, 2, 3],R)
sterge(X,[X|R],R) if !.
sterge(X, [ Y | R1] , [ Y | R2 ]) if
sterge(X,R1,R2)

37
InteligenŃă Artificială. Tehnici.

2. Se utilizează opŃiunea CHECK_DETERM, care se amplasează în faŃa


programului sub forma:
check_determ
domains...

-specifică punctul în care poate fi amplasat elemental de tăiere.Din propunerile


avansate se allege aceea care furnizează rezultatele dorite.

6.3. Construirea regulilor If ... Then ... Else


Elementul de taiere ! poate fi utilizat pentru construirea unor reguli de tip
if_then_else , în Prolog, sub forma:
a) ConstruiŃi o procedură max (x, y, maxim_x_y) care se traduce printr-o regula
de forma:
if x>=y then MAX=x
else MAX=y.

Obişnuit regula poate fi scrisă in Prolog astfel.

max(X,Y,X) if X>=Y.
max(X,Y,Y) if X<Y.

sau

max(X,Y,X) if X>=Y, !.
max( _ ,Y,Y).

Dacă prima regulă este adevarată, elementul de tăiere se ia în considerare şi


cea dea doua regulă nu se mai execută.

b) ConstruiŃi o procedură care să asigure adunarea unui element X la o listă L,


numai dacă X nu este prezent în L (în acest caz X devine capul listei), de forma:

aduna(elem, L,Rezult)

38
InteligenŃă Artificială. Tehnici.

care se traduce printr-o regula de forma:

if elem aparŃine L then Rezultat=L


else Rezultat=[elem | L ]

SecvenŃa se scrie in Prolog astfel:


aduna(X ,L, L) if aparŃine (X,L), ! .
aduna(X,L,[ X |L ]).

Exemplu : ?-aduna (2,[1,3],R)


R=[2,3,1]
?- aduna(3 ,[1, X ,4] ,R)
X=3 ,R=[1 ,3, 4]

c) ConstruiŃi o procedură care pornind de la o listă cu elemente numere


întregi ,să construiască 2 liste: prima conŃinând elemente >0 ,cea de-a doua
conŃinând elemente <=0.

% imparte(lista, lista>0,lista<=0)
imparte( [ ], [ ], [ ] ) .
imparte( [ESTE | R ] , [ESTE |L1], L2) if
ESTE>=0, !, imparte(R,L1 ,L2) .
imparte([ESTE,R],L1,[ESTE|L2]) if
imparte(R,L1,L2).

! acŃionează distinct de fiecare dată la un apel.

d) ConstruiŃi o procedură care să permită clasificarea concurenŃilor dintr-un


turneu de tenis în 3 categorii definite astfel:
--categoria câştigătorilor, dacă jucatorul i-a bătut pe toŃi cei cu care a jucat
--categoria luptător, dacă jucătorul a cîştigat şi a pierdut jocuri.
--categoria sportiv ,dacă jucatorul a piedut toate meciurile.

if X bate pe cineva şi X este bătut de altcineva


then X este luptător
else if X bate pe cineva
then X este cîştigător
else if X primeşte bătaie de la toŃi
then X este sportiv.

39
InteligenŃă Artificială. Tehnici.

Dacă predicatul este de forma: clasa (nume_sportiv,categoria), regula se


implementează astfel :

clasa (X,luptator) if
bate_pe(X, _) ,
bate_pe( _ ,X) , !.
clasa(X,cistigator) if
bate_pe(X, _), !.
clasa (X, sportiv) if
bate_pe( _,X).

6.4. Implementarea negaŃiei.


-Se implementează în două moduri:
a) se utilizează | ,fail , true.
b) not
a) Not şi fail reprezintă predicate standard PROLOG care întotdeauna
precizează valoarea fals, respectiv adevărat.
1. DefiniŃi următoarele aspecte:
Lui Tom îi plac animalele cu excepŃia pisicilor. Considerînd predicatul de forma:
% îi_place(propietar,animal)
% animal(nume_animal)
afirmaŃia anterioară se scrie în prolog sub forma:

îi_place(tom,X) if
X=pisica ,!,fail. %(spune ca proprietatea este falsă)
îi_place(tom,X) if
animal(X).

ObservaŃie : prezenta lui fail în prima regulă face ca aceasta să devină falsă , iar
! din fata lui fail stopează căutarea pe următoarea regulă îi_place.

SecvenŃa poate fi scrisă compactat sub forma:


îi_place(tom,X) if
X=pisica, !, fail;
animal=X.

40
InteligenŃă Artificială. Tehnici.

2. ConstruiŃi o procedură care să furnizeze fals dacă obiectele X şi Y sunt


identice şi adevărat dacă obiectele X şi Y sunt diferite. Modul de funcŃiune este
de forma
diferit(obiect1,obiect2), diferit(2,3) YES
diferit(3,3) NO
Procedura se scrie:

diferit(X,Y) if sau: diferit(X ,Y) if


X=Y, !, fail. X=Y ,! ,fail;
diferit(X,Y) if true.
X< >Y.
sau: diferit(X,Y) if
X=Y, ! ,fail.
diferit( _, _ ).

3. Implementarea negaŃiei printr-o regulă utilizand o combinatie intre fail, ! şi


true apare de forma:

not( P) if
P, !, fail;
true.

b) Maşina de inferenŃă pune la dispozitie predicatul not. Modul lui de acŃionare


consta in inversarea rezultatului oferit de maşina de inferenŃă relativ la clausa
sau clausele asupra careia actioneaza.
Cu aceste observaŃii ,secvenŃele anterioare pot fi rescrise:

îi_place(tom,X) if
animal(X), not(pisica(X)).

diferit(X,Y) if
not(X=Y).

clasa(X,luptator) if
bate_pe(X, _ ),
bate_pe( _, X).
clasa(X,cistigator) if

41
InteligenŃă Artificială. Tehnici.

bate_pe(X, _ ), !.
clasa(X,sportiv) if
bate_pe( _,X).

Exercitii
1) Fiind data secventa: A :- B,C.
A :- not(B),D.
se cere construirea unei secvente care sa se comporte identic, in care negatia sa
dispara prin inlocuirea cu elementul de taiere !.Explicati succint
(1) de ce cele doua secvente au aceiasi comportare.
(2)care este efectul elementului de taiere in caz general
2) Considerind procedura: p(1). p(2) if !. p(3).
Care sunt raspunsurile la întrebările:
(a) ?- p(X).
(b) ?- p(X),p(Y).
(c) ?- p(X),!,p(Y).

42
Inteligenţă Artificială. Tehnici.

7. OPERAŢII DE CITIRE / SCRIERE


Dupa cum s-a vazut pana in momentul prezent, maşina de inferenţă
actioneaza asupra unei baze de cunoştinţe in contextul unei întrebări puse de
utilizator. Acest mod de activare a masinii de efectuat deductii logice reprezinta o
restrictie, deoarece pe de o parte raspunsurile date sunt strict limitate la afisarea
unor solutii posibil, iar pe de alta parte utilizatorul nu poate interveni in derularea
rationamenului efectuat. Asa cum am spus, spaţiul solutiilor care urmeaza sa fie
explorat este extreme de vast, motiv pentru care initierea unui dialog cu
utilizatorul in vederea indrumarii pe o anumita directie s-au alta a rationamentului
devine o necesitate. Toate aceste considerente ridica problema prezentei unei
interfete cu utilizatorul – alta decat cea standard legata de procesul de tip
intrebare / raspuns – care sa dea posibilitatea initierii unui dialog cu utilizatorul in
timpul procesului de inferenţă. Ca urmare a acestui deziderat, s-a prevazut
posibilitatea ca utilizatorul sa-si construiasca propria interfata de intrare / iesire,
adaptata problematicii pe care doreste sa o reyolve, interfata complementara
celei standard de tip intrebare / raspus. Pentru construirea de catre utilizator a
acestei interfete s-au prevazut un numar de predicate standard care se regasesc
in toate implementarile masinilor de inferenţă prolog, predicate care sunt grupate
in jurul operatiilor de tip read / write. Acestea urmeaza sa fie analizate in
continuare, in contextual general al operatiilor de citire / scriere.

7.1. Scrierea.
Predicatul de scriere prezintă sintaxa:
write(arg1,.....,argn)
În care argumentele pot fi constante sau variabile ce aparţin unor domenii
standard sau nu. Dacă argumentul este un şir de caractere atunci acesta
reprezintă mesaj care se tipareşte pe ecran. În interiorul şirului sunt acceptate
următoarele caractere de control:
\n, salt peste n linii
\t, tab

43
Inteligenţă Artificială. Tehnici.

\b. spaţiu
De exemplu
write(" \t lista1= ",L1,"\n \t Lista2 ", L2) are ca efect o tipărire de forma:
lista1=[ ]
lista2 =[1,2]
În general predicatul write apare în proceduri recursive, aspect care implică
stoparea operaţiei de căutare a soluţiilor, astfel încât rezultatele parţiale să nu fie
tipărite.

7.2. Citirea
- este realizată de următoarele predicate:
readint(X) -- citire variabilă de tip intreg.
readreal(X) -- citire variabile din domeniul real
Operaţia de citire se termină în momentul apăsării tastei ENTER. Rezultatul este
un success, dacă numărul citit este un întreg sau real respectiv un eşec dacă
valoarea citită conţine caractere care nu aparţin numerelor întregi sau reale.
readln(X) -- citirea variabilelor din domeniul simbol sau
string
readchar(X) -- citirea caracterelor
Ultimul predicat este întotdeauna un succes. Primul este un eşec dacă şirul citit
nu este delimitat de " .

7.3. Modalităţi de citire / scriere.


Aspectele care apar in momentul efectuarii unui dialog cu masina de
inferenţă sunt illustrate printr-un set de exemple:
1. Construiţi o procedură care să genereze o listă atunci când elementele listei
se citesc. Considerăm că lista este de tip întreg. Dacă predicatul este de forma:
% citeşte(lista) ,procedura apare sub forma:

44
Inteligenţă Artificială. Tehnici.

domains
lista=integer *
predicates
citeşte(lista)
clauses
citeşte([ESTE |Rest]) if write("Element=");
readint(ESTE),
citeşte(Rest).
goal:
citeste(L),
write(L).

Citeşte se termină în momentul în care predicatul este fals.


Element=1 Enter
=4 Enter
Operaţia de introducere continuă până în momentul în care se introduce un
caracter prin care readint este obligat să devină fals. Ca urmare regula citeşte
este falsă, fiind executată regula citeşte plasată după reguli. Prin apeluri
recursive ,se construieşte lista care se scrie.

2. Construiti o procedura care să reia repetat operaţia de citire a unei liste. Dupa
fiecare listă construită prin dialog, se va specifica dacă operaţia continua sau nu.
Reluarea construirii listei va fi efectuată de predicatul repeta, sub forma:

domains
lista=integer*

predicartes
repeat citeste(lista)

goal
repeta.
clauses
repeta if
citeste(L),
write("lista= ",L),
write("\n Continuati? (d/n)"),
readchar(R), R='d', repeta.
% citeste este definit anterior .

45
Inteligenţă Artificială. Tehnici.

Dialogul apare de forma:


ESTE=1
ESTE=2
ESTE=.
lista=[1,2]
Continuati? (d/n) d
Se pot face doua observatii importante:

(1) Procedura "citeşte" este o procedură recursivă. Mecanismul de căutare a


soluţiilor amplasează un pointer pe "citeşte" pentru fiecare element citit. În
momentul în care lista se consideră a fi construită , forţându-se ca readint să fie
fals, are loc rezolvarea apelurilor recursive prin care se construieşte lista. Efectul
pentru exemplul dat este de a fi construite toate listele parţiale care pot apare
prin introducerea fiecarui element, evident insa ca acest aspect nu este de dorit:
Pentru cazul discutat situaţia apare de forma
ESTE=1
ESTE=2
ESTE=.
Lista= [ ]
Continuaţi ? d --------> }
Lista=[2] }Din acest motiv după procedura recursivă este
Continuaţi ? d --------> } obligatorie amplasarea elementului de taiere !
Lista=[1,2]
Se observă ca apar listele parţiale [ ] , [ 2] , [1, 2 ] din care numai ultima lista
intereseaza. Pentru a rezolva problema este necesara stoparea inferentei, motiv
pentru care se utilizeaza elemental de taiere care se va amplasa dupa procedura
recursive care genereaza printre altele şi aceste rezultate partiale.

(2) Problematica apare şi in cazul unor proceduri recursive prezente in strategiile


complementare masinii de inferenţă, moment in care aceste genereaza pe langa
rezultatele corecte şi o multitudine de rezultate partiale care trebuie inlaturate.
Atunci când se doreşte rezolvarea repetată a unor probleme pentru alte
date , procedura generala pentru alte date este :

46
Inteligenţă Artificială. Tehnici.

repeta if
citeste_date ,!, % Dacă procedura citeste_date şi
executa ,!, % executa, sunt recursive , amplasarea
scrie, !, % elementului ! (cut) este obligatorie.
continuare , repeta.

Goal
Interfata de intrare / iesire cu utilizatorul,
repeta.

3. Construiţi o procedură care să asigure scrierea unei liste cu elemente numere


întregi , pe rânduri succesive ,fiecare rând având 3 elemente.
Considerăm că predicatele utilizate sunt :
% scrie (lista)
% scrie_rind(lista,nr_elem_pe_rind)
pot fi luate în considerare următoarele situaţii:
a) Scrierea listei începe cu scrierea primului rând .
b) După ce s-a scris un rând ,se trece la rândul următor.
Procedura apare sub forma:

domains
I = integer*
predicates
scrie (l)
scrie_rind(l,integer)
clauses
scrie (L) if nl, scrie_rind(L,0).
scrie_rind([ ],-). % ------------>oprirea procesului recursiv
scrie_rind(L,3) if nl, scrie_rind(L,0).
scrie_rind ([ESTE|Rest],N) if
write(" ",ESTE),
N1=N+L,
scrie_rind(Rest,N1).

Observaţii:
a)Predicatul ne asigură trecerea la începutul unei linii noi.
b)Pentru procedura scrisă se contorizează numărul de elemente care se
scriu, după care regula scrie_rind(L,3) asigură trecerea la următorul rând.

47
Inteligenţă Artificială. Tehnici.

4) Specificaţi setul de clauze care să asigure citirea unei liste a căror


elemente sunt obiecte compuse , de forma:
% persoana=p(nume,prenume,virsta)

domains
nume,prenume=symbol
persoana =p(nume,prenume,integer)
lista=persoana *
predicates
citesc(lista)
citeste(pers)
clauses
citesc([Obiect|R]) if
citeste(Obiect),
citesc(R).
citesc([ ]).
citeste(p(N,P,V)) if
nl,
write("Nume="),readln(N),
write("Prenume="),readln(P),
write("Virsta="),readint(V),nl.

Observaţii :
Operaţia presupune definirea unui predicat de citire separat, la nivelul de
obiect compus. Acest predicat este utilizat pentru citirea fiecărui element al listei
ce se construieşte. Întreruperea operaţiei de construire se face introducând un
caracter care să forţeze readint să fie fals. Pentru structura de date in discutie se
va obţine o listă de forma :
[p(Ion,V,17),p(Vlad,C,20)...]

5) Scrierea cu format
Este asigurată de predicatul
writef (format, arg1, arg2, ...)
unde:
format reprezinta un şir de caractere în care apar descriptori de forma:

48
Inteligenţă Artificială. Tehnici.

%-m pentru scrierea câmpurilor alfanumerice şi întregi pe m poziţii.


'-' e opţional şi semnifică aliniere la stânga în loc de dreapta implicit
%-m.pf pentru numere reale cu sau fară exponent.
p specifică numărul de poziţii luate în considerare după
virgulă
Exemplu:
Considerand ca avem o lista de obiecte compuse de forma:
p(nume, prenume, vârsta, venit)
unde sunt prezente obiectele

[ p(ion, dan, 20, 37000.0), p(vasile, ionel, 50, 57000.7), ...)]

se cere construire unei proceduri de scrieere a elementelor din lista cu


precizarea semnificatiei fiecarui element component intr-o structura data.
Procedura apare de forma:

scriu([E| Rest]) if scrie_p(E),


scriu(Rest).
scriu([ ]).
scrie_p(p(N,P,Vr,Vn)) if writef("\n Nume= %-20 Prenume= %-10 ,
Venit=%7.1f",N,P,Vr,V)

49
InteligenŃă Artificială. Tehnici.

8. BAZE DE DATE INTERNE


În acord cu modelul relaŃional al unei baze de date, setul de clauze Prolog
poate fi poate fi privit ca o baza de cunoştinŃe, pentru care sunt specificate relaŃii şi
caracteristici ale unor obiecte şi fenomene.
Acest punct de vedere a impus introducerea facilităŃii de a modifica în cursul
execuŃiei setul de clauze prezente în baza de cunoştinŃe. Ca urmare a acestei
caracteristici – modificarea dinamica a setului de cunoştinŃe in urma dialogului cu
utilizatorul – devine posibil ca baza de cunoştinŃe se evolueze in timp, evolutie care
se concretizeaza faptic prin modificarea, disparitia si respective adaugarea de noi
cunoştinŃe. Ca urmare apare un aspect interesant si anume acela ca baza de
cunoştinŃe invata, fiind retinuta intreaga experienta castigate anterior. Din punct de
vedere practice aceasta facilitate se referă atât la adaugarea de noi clauze cât şi la
stergerea selectivă în timpul execuŃiei a acestora. S-a prevazut de asemenea
posibilitatea salvării setului de clauze şi a restaurării acestuia dinamic.

8.1. Caracteristicile bazelor de date interne.


Declararea bazelor de date interne se face în secŃiunea database care
conŃine predicatele ce aparŃin unei baze de date.
Exemplu:
Implementăm relaŃiile dintre persoane referitoare la capacitatea lor de a
alerga (incet,repede).
1)
domains
nume=symbol
predicates
aleargă_repede(nume)
aleargă_încet(nume)
mai_rapid(nume,nume)
clauses
aleargă_repede(ana).
aleargă_repede(radu).
aleargă_încet(doru).
mai_rapid(X,Y) :- aleargă_repede(X), aleargă_încet(Y).

50
InteligenŃă Artificială. Tehnici.

2)
domains
nume=symbol
predicates
mai_rapid(nume,nume)
database
aleargă_repede(nume)
aleargă_încet(nume)
clauses
aleargă_repede(ana).
aleargă_repede(radu).
aleargă_încet(doru).
mai_rapid(X,Y) :- alearga_repede(X), alearga_incet(Y).

Goals : assert(aleargă_repede(ion))
Yes
Goals : aleargă_repede(X)
X=ana X=radu X=ion 3 solutions
Goals : save("axiome.dba")
Yes
Goals:consult("axiome.dba") {se încarcă baza de date}

8.2 . ModalităŃi de asertare a clauzelor


într-o baza de date.
- Asertarea poate fi făcută în spatele setului de clauze cu acelaşi nume prin
predicatele :
assert(clausa)
assertz(clausa)
- Asertarea poate fi făcută în faŃa setului de clauze cu acelaşi nume prin predicatul :
asserta(clausa)
- Ştergerea unei clauze din setul de axiome se face cu:
retract(clausa) - şterge clausa
retractall(clausa) - şterge toate clauzele cu acest nume

Pentru retract este posibilă în momentul ştergerii, obŃinerea de informaŃii


privind structura clauzei care se şterge dacă variabila din clauză este liberă.

51
InteligenŃă Artificială. Tehnici.

Exemplu: Pentru exemplul de mai sus


Goal : retract(aleargă_repede(X)),write(X)
va legă pe X la valoarea ana
- Salvarea/restaurarea bazei de date se face cu:
save(nume_dos)
consult(nume_dos)

Observatii:
1) Intr-o baza de date nu pot fi asertate decât axiome. Există totuşi dialecte
de Prolog care permit şi asertarea regulilor.
2) La un moment dat pot exista 2 sau mai multe baze de date active. Pentru
a face deosebirea între acestea setul de predicate prezintă extensiile:
assertz(clausa,nume_baza_date)
asserta(clausa,nume_baza_date)
retract(clausa,nume_baza_date)
retractall(clausa,nume_baza_date)
save(nume_dos,nume_baza_date)
consult(nume_dos,nume_baza_date)

Pe întregul set, indiferent câte baze de date am deschise se lucrează cu


predicatele standard (se folosesc pentru toate bazele de date).
3) Numele bazei de date se specifică direct sub forma unui nume simbolic în
predicatele care gestionează o baza de date.
Exemplu:
ConstruiŃi un sistem de clasificare a obiectelor utilizând o baza de date
internă a cărei structură este de forma:
este_un( limbaj, unealtă, ["comunic"])
este_un( plug, unealtă, ["ara camp", "folosit de fermier"])
este_un(creion,unealtă,["scris", "folosit la scris"])
tip_de(engleză, limbaj, ["comunicarea cu oamenii"])
tip_de(pascal, limbaj, ["comunicarea cu calculatorul"])

52
InteligenŃă Artificială. Tehnici.

domains
obiect=string atribut=string atribute=atribut*

database
este_un(obiect,obiect,atribute) tip_de(obiect,obiect,atribute)
fals(atribut)

predicates
run(obiect) intreaba(atribute)

clauses
run(Art):- este_un(X, Art, Lista ),
întreabă( Lista ),
tip_de(Răspuns,X,Lista2),
întreabă(Lista2),
write(Art, " de care aveŃi nevoie este ", Raspuns), nl, !.
run( _ ) :- write( "Nu există informaŃie suficientă" ).

întreabă( [ ] ).
întreabă( [A|R] ) :- not(fals(A)),
write("Vă ajută la",A),
write(" da sau nu?
readchar(C), nl, C='d',
întreabă(R).
întreabă( [A|_ ] ) :- assertz(fals(A)), fail.

Goal:run(unealtă)
Vă ajută la comunicare? d
Vă ajută la comunicarea cu oamenii? n
{În baza de date se assertează clausa fals("comunicarea cu oamenii") }
Vă ajută la comunicarea cu calculatorul? d
Unealta de care aveŃi nevoie este Pascal

ObservaŃie:
1) În acest mod, procedura poate reŃine o informaŃie în timpul dialogului
(faptul ca comunicaŃia cu oamenii este falsă) ceea ce face ca la o nouă reluare a
execuŃiei această întrebare să nu se mai pună.

53
InteligenŃă Artificială. Tehnici.

2) Practic in acest moment s-a generat o baza de cunoştinŃe care


este independentă de componta care este utilizată pentru interogarea ei ( baza de
cunoştinŃe poate fi editată şi actualizată cu orice utilitar de editare n mod text )

3) In baza de cunoştinte informaŃiile se reŃin prin intermediul unor structuri


de tip arbore. Fiecare arbore defineşte o clasa de obiecte în care rădăcina defineşte
clasa de obiecte, frunzele obiectele care sunt indivizibile iar nodurile subclase de
obiecte de aceaşi natură prezente în clasa definită de arboreal respective. Fiecare
nod (radaăcina, intermediary sau de tip frunză) are ataşată o listă de attribute care
sunt validate sau nu în cursul procesului de inferenŃă. Modul de validare determină
sensul de parcurgere a arborelui (vezi figura următoare).

Clase de obiecte

Clasa 1 …………………………..Clasa n

Da
Subclase

Nu

………………….

Obiect 1 2……………m

Pentru raspuns:
Da pentru toate atributele unui nod acesta este validat
Nu pentru un singur răspuns de acest tip se invalideaza nodul

54
InteligenŃă Artificială. Tehnici.

8.3 Colectarea soluŃiilor


Prin mecanismul de backtracking, soluŃiile sunt generate pas cu pas. Utilizatorul are
acces numai la soluŃia din pasul curent (soluŃiile anterioare sunt pierdute). Pentru a
da posibilitatea prelucrării întregului ansamblu de soluŃii, s-a prevăzut facilitatea de
colectare a acestora într-o listă în care elementele sunt soluŃii. OperaŃia e realizată
de predicatul :

findall(SoluŃie,Întrebare, Listă_soluŃii)

Pentru a ilustra tehnica de colectare, considerăm o procedură în care se stabileşte


apartenenŃa unui caracter la clasa vocale sau consoane. IniŃial, programul prezintă
aspectul :
domains
literă = char
predicates
tip_literă = ( literă, symbol )
clauses
tip_literă( 'a', vocală ). tip_literă( 'b', consoană ). tip_literă( 'c', consoană ).

Pentru a colecta soluŃia se pot utiliza două tehnici :


a) goal findall( C, tip_literă( C, consoană ), L ),
write( 'SoluŃie = ', L )
=> SoluŃie = [ b, c ]
b) findall poate fi întrebuinŃat în procedura utilizator. In acest caz, devine
necesară declararea în secŃiunea domains a unei liste de soluŃii :
domains
litera = char lista = litera*

.
findall( C, tip_literă( C, consoană ), L ),
.
procedura de prelucrare a listei L,

Exercitii
1) Care sunt raspunsurile la întrebările:
? assert(p(a)),assertz(p(b)),asserta(p(c))
? p(X)

55
InteligenŃă Artificială. Tehnici.

9. GENEREAZA ŞI TESTEAZĂ

Un aspect al modelelor de calcul din programare logică, ce nu este prezent în


modelele convenŃionale este nedeterminismul. Utilizând acest concept, se pot defini
tehnici de construire a unor algoritmi de calcul pentru programarea logică. Întuitiv, o
maşină nedeterminista este o maşină care poate alege singura operaŃia corectă
atunci când sunt prezente cu multe alternative de calcul. Adevarata maşină
nedeterministă nu poate fi realizată, însă poate fi aproximată. În particular, maşina
de inferenŃă Prolog aproximează comportamentul nedeterminist al unui înterpretor
de programe logice abstracte prin căutari secvenŃiale şi backtracking. Faptul că
nedeterminismul este numai "simulat", fără a fi în realitate "prezent", poate conduce
la abstractizarea şi definirea unor tehnici de construire a strategiilor complementare
bazelor de cunostinte. În cele ce urmează se va arăta cum, gândind nedeterminist,
se pot construi strategii concise şi eficiente de explorare a bazelor de cunoştinŃe.

9.1. Generează şi testează . Principiu.


Tehnica "genereaza şi testeaza" este comună în proiectarea algoritmilor şi
programare. În cadrul acestei tehnici, o rutina generează o mulŃime de soluŃii
posibile pentru problema în cauză, în timp ce un alt proces testează soluŃiile,
alegându-le pe cele corecte. În mod obişnuit, programele de tip "generează şi
testează" sunt simple, însă puŃin eficiente. În scopul optimizării acestei tehnici, se
încearcă amplasarea modulului de testare în înteriorul generatorului, cât mai adinc
posibil. IntenŃia este ca cele doua module să se întreŃese, astfel încit să fie generate
de la început numai soluŃii corecte.
În Prolog, implementarea tehnicii presupune prezenŃa împreună a două
scopuri: primul are rol de generare, cel de-al doilea de testare, sub forma:

find(X) if generez(X),
testez(X).

56
InteligenŃă Artificială. Tehnici.

Datorită modului de lucru a maşinii de inferenŃa Prolog, dacă generez(X) este


un succes, rezultatul va fi testat în continuare. Dacă rezultatul testului este un eşec,
prin backtracking se va reactiva generez(X) şi deci se va propune următoarea
soluŃie. OperaŃiile se repetă, pâna când generez(X) epuizează setul de soluŃii
posibile. Această tehnică, "generare şi testare", poate fi vazută ca o modalitate de
construire a startegiilor complementare. Astfel, într-un program nedeterminist,
generatorul propune un element, iar modulul de test verifică dacă propunerea este
corectă.

9.2. ModalităŃi de implementare.


Pentru a ilustra modul in care tehnica poate fi utilizata, vom incerca sa o prezentam
printr-un numar de trei exemple.

Exemple
(a) apartine(X,Lista) este un exemplu tipic de generator, cât şi de starategie de
testare a unor soluŃii.
Ca generator, aparŃine(X,[1,2,3]) va furniza trei soluŃii: X=1, X=2, X=3.
Ca modul de testare, acesta ar putea să apară sub forma intr-un predicat de
forma:
intersectează(Lx, Ly) if
aparŃine(X ,Lx), <-generează soluŃiile
aparŃine(X, Ly). <-testează soluŃiile

Se observă ca primul apaŃine propune o soluŃie, în timp ce al doilea aparŃine verifică


dacă soluŃia este corectă. Practic, se implementează două cicluri în care unul de
testare este inclus în primul. Această soluŃie este foarte similară cu cele utilizate în
limbajele neconvenŃionale.

(b) Procedura aparŃine poate fi privită ca şi un modul în care tehnicile de generare şi


verificare a soluŃiilor sunt întreŃesute între ele. De exemplu:

57
InteligenŃă Artificială. Tehnici.

aparŃine(X, Lx) if
conc(Ax, [X|Bx], Lx).

Cele două etape sunt întreŃesute, în sensul ca concatenarea generează două liste,
care sunt urmate imediat de verificarea faptului ca X este un element a lui Lx.

(c) ConstruiŃi o procedură care să coloreze o hartă planara, utilizind un număr minim
de culori, astfel încât să nu existe două regiuni vecine cu aceeaşi culoare. (problemă
rezolvată în 1976 când s-a demonstrat ca 4 culori sunt suficiente).
Vom incerca sa standardizam etapele de construire a strategiilor complementare
unei baze de cunostinte si in acelasi timp sa precizam cum se utilizează tehnica
"generează şi testează. Etapele care se recomanda a fi parcurse sunt urmatoarele:
1. Se stabileste structura de date care urmeaza sa fie utilizata. Aceasta depinde
de baza de cunostinte careia urmeaza sa i se ataseze strategia. Pentru cazul
dat structura de date este impusa de structura hartii si apare de urmatoarea
maniera : harta apare ca o lista de unde:
-fiecare regiune are un nume, o culoare şi o listă de culori ce
aparŃin regiunilor adiacente;
- de dexemplu pentru harta:

Structura de date apare de forma:


Map = [ regiunea(a,A,[B,C,D]), regiunea(b,B,[A,C,E]), regiunea(c,C,[A,B,D,E,F]),
regiunea(d,D,[A,C,F]), regiunea(e,E,[B,C,F]), regiunea(f,F,[E,C,D]) ]

58
InteligenŃă Artificială. Tehnici.

2. Se defineste intrebarea care urmeaza sa fie pusa. Pentru cazul dat aceasta
este definite de predicatul:
color_map(harta, lista_de_culori),
unde harta reprezintă structura anterioară, lista_de_culori este o listă a culorilor
utilizate.

3. Se detaliaza intrebarea pusa la nivelul structurilor de date aflate la un nivel


imediat inferior celei generale. Pentru cazul de fata vom avea de colorant in
cadrul hartii o regiune – aceasta reprezentand un element al listei care
defineste structura supusa prelucrarii. Obtinem:

color_map([Regiune|Regiuni],Culori) if
color_regiune(Regiune,Culori),
color_map(Regiuni,Culori).
color_map([ ] , _ ).

4. Utilizand tehnica genereaza si testeaza se procedeaza la specificarea


atributelor cerute pentru un element al structurii de date. Pentru cazul dat
vom avea pentru fiecare regiune a hărŃii de realizat urmatoarele::
-alege o culoare (genereaza);
-alege (testează) culorile pentru regiunile vecine, care au rămas
de colorant, astfel incat restrictia impusa de enunt sa fie indeplinita. Vom
obtine:
color_regiune(regiunea(Nume,Culoare,Vecini),Culori) if
obtin(Culoare,Culori,Rest_Culori), %genereaza
verific(Vecini,Rest_Culori). %testeaza
unde:

(a) Generarea unei soluŃii (obtin) constă din scoaterea din lista de culori a
celei în care intenŃionăm a se desena harta. Rezultatul este o culoare şi o lista de
culori minus cea selectată.

59
InteligenŃă Artificială. Tehnici.

(b) Testarea (verific) presupune verificarea faptului ca lista de culori în care


sunt desenaŃi vecinii este un subset al listei rezultate în pasul anterior.
In acest context strategia de colorarea va apare de forma:

color_map([Regiune|Regiuni],Culori) if
color_regiune(Regiune,Culori),
color_map(Regiuni,Culori).
color_map([ ] , _ ).
color_regiune(regiunea(Nume,Culoare,Vecini),Culori) if
obtin(Culoare,Culori,Rest_Culori),
verific(Vecini,Rest_Culori).
obtin(X,[X|R],R).
obtin(X ,[Y|R1], [Y|R2]) if
obtin(X, R1, R2).
verific([ C|R],Lista) if
apartine(C,Lista),
verific(R,Lista).
verific([ ], _ ).

5. Se recomanda ca structura de date sa fie initializata in cadrul strategiei, asfel


incat fie evitate erorile datorate introducerii unei structuri de date complexe.
Este evident insa ca aceasta poate fi introdusa prin dialog cu utilizatorul in
cadrul unei interfete adecvate. Pentru cazul dat vom avea:

test_color(Map) if
map(Map),
culori(Culori),
color_map(Map,Culori).
Map = [ regiunea(a,A,[B,C,D]), regiunea(b,B,[A,C,E]), regiunea(c,C,[A,B,D,E]),
regiunea(d,D,[A,C,F]), regiunea(e,E,[B,C,F]), regiunea(f,F,[E,C,D]) ].
culori([rosu,galben,alb,verde]).

60
InteligenŃă Artificială. Tehnici.

9.3. Rezolvarea enigmelor logice.


O enigmă logică constă dintr-o serie de observaŃii (constatări), referitoare la un
numar mic de obiecte, care au diverse proprietaŃi. Plecând de la acest set de
informaŃii, se cere găsirea unui mod unic de atribuire a proprietăŃilor la obiecte.

Exemplu:
Trei prieteni au sosit pe locurile I, II, III într-o competiŃie sportivă. Fiecare din cei trei
au nume diferite, le plac sporturi diferite şi au diferite naŃionalităŃi. Lui Mihai îi place
baschetul şi este mai bun decât americanul. Simon, care este francez, este mai bun
decât jucătorul de tenis. Jucătorul de cricket a sosit primul. Cine este australianul?
Ce sport face Robert?

Mod de rezolvare
Enigmele se rezolvă instanŃiind valorile la o structură de date adecvată,
urmată de extragerea valorilor soluŃiilor. Fiecare afirmaŃie este tradusă printr-o
constatare care propune soluŃii şi le verifică imediat pentru structura de date
existentă. În final rezultă o structură de date ce prezintă variabile anonime (locuri
goale). Aceasta urmează sa fie completată de întrebările ce se pun structurii.
Practic tehnica genereaza si testeaza actioneaza ca un filtru care propune
solutii si retine numai pe acelea care corespund restrictiilor impuse. Pentru
realizarea acestui filtru se impune descrierea “ad literam” a fiecarei afirmatii din
contextual enigmei logic.
Pentru exemplul dat, din primele 2 propoziŃii rezultă structura de date care
urmeaza a fi utilizată.

prieten(Nume,Tara,Sport)
st=[ prieten(_, _, _), prieten(_, _, _), prieten(_, _, _) ]

Ultima structura reprezinta filtrul care urmeaza a fi utilizat in cadrul tehnicii


genereaza si testeaza.
Din a 3-a propoziŃie se intra în etapa de construire a afirmaŃiilor. Din prima

61
InteligenŃă Artificială. Tehnici.

afirmaŃie rezultă că sunt referiŃi 2 oamenii care sunt prieteni, unul este Mihai, căruia
îi place baschetul, cel de-al 2-lea este un american. Mai departe ştiu că Mihai este
mai bun decât americanul; rezultă afirmaŃia:

mai_bun(Conc1A1,Conc2A1,Prieteni),nume(Conc1A1,Mihai),
sport(Conc1A1,baschet),nationalitatea(Conc2A1,americana).

Din propoziŃia a 4-a sunt referiŃi 2 concurenŃi care sunt prieteni, primul
concurent este Simon-francez, cel de-al 2-lea practică tenisul. ªtiind că Simon este
mai bun decât tenismen-ul, apare:

mai_bun(Conc1A2,Conc2A2,Prieteni),nume(Conc1A2,simon),
naŃionalitatea(Conc1A2,francez),sport(Conc2A2,tenis).

PropoziŃia 5 ne furnizează cel de-al 3-lea indice de forma:


primul(Prieteni,ConcA3),sport(ConcA3,cricket)

Ansamblul celor 3 afirmaŃii pot fi incorporate în :


afirm_ca(Prieteni) if A1,A2,A3.

Aceasta implementează o procedură de tipul generează şi testează asigurând


instanŃierea structurii de date definite. Fiecare întrebare pusă este tradusă printr-o
constatare care se tratează similar cu afirmaŃiile

62
InteligenŃă Artificială. Tehnici.

% STRUCTURA DE DATE
domains
nume=symbol tara=symbol sport=symbol
concurent=prieten(nume,tara,sport)
prieteni=concurent*

% STRUCTURA PREDICATELOR
predicates
rezolva(prieteni) afirm_ca(prieteni)
pun_intreb(prieteni) mai_bun(concurent,concurent,prieteni)
nume(concurent,nume) sport(concurent,sport)
natiune(concurent,tara) primul(prieteni,concurent)
apartine(concurent,prieteni)

clauses
afirm_ca(Prieteni):-
% Afirmatia 1
mai_bun(Conc1A1,Conc2A1,Prieteni),
nume(Conc1A1,mihai),
sport(Conc1A1,baschet),natiune(Conc2A1,americana),
% Afirmatia 2
mai_bun(Conc1A2,Conc2A2,Prieteni),nume(Conc1A2,simon),
sport(Conc2A2,tenis),natiune(Conc1A2,francez),
% Afirmatia 3
primul(Prieteni,ConcA3),sport(ConcA3,crichet).

pun_intreb(Prieteni):-
% Intrebarea 1

apartine(C1,Prieteni),nume(C1,Nume),natiune(C1,australiana),
% Intrebarea 2
apartine(C2,Prieteni),nume(C2,robert),sport(C2,Sport),
% Raspuns
write("Australianul este ",Nume),
write("Robert joaca ",Sport).

% Clasament locurile 1 2 3
mai_bun(A,B,[A,B,_]). mai_bun(A,C,[A,_,C]). mai_bun(B,C,[_,B,C]).

% Selectie componente structura de date


nume(prieten(A,_,_),A). natiune(prieten(_,B,_),B). sport(prieten(_,_,C),C).

rezolva(Prieteni) if
afirm_ca(Prieteni),
pun_intreb(Prieteni).

63
InteligenŃă Artificială. Tehnici.

primul([X|_],X).

apartine(X,[X|_]).
apartine(X,[_|R]) :- apartine(X,R).

% INTREBARE
goal
St is [prieten(_, _, _),prieten(_, _, _),prieten(_, _, _)],
rezolva(St).

64
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

10. STRUCTURI DE DATE 3.

10.1 Grafuri

Asa cum s-a specificat structura de tip graf este utilizata cu precadere in cazurile
in care se doreste reprezentarea cunostintelor structurate. Din aceste considerete
reprezentarea lor cat si tehnicile de cautare in astfel de stucturi in contextul programarii
logice reprezinta un aspect important.

10.1.1. Reprezentare.
In cazul general, un graf se reprezintă ca un obiect compus, de forma :
Graf = g( listă_noduri, listă_muchii )

Deoarece nodurile apar implicit în lista de muchii, se mai utilizează forma


simplificată :
Graf = g( listă_muchii )

Reprezentarea listei de muchii depinde de tipul grafului : orientat sau neorientat. De


exemplu un graf neorientat din figura de mai sus, se va reprezenta de forma:
G = g( [ a, b, c, d ], [ m( a, b ), m( b, c ), m( c,d ), m( d, b ) ] )

In timp ce un graf orientat va avea urmatoarea reprezentare


G = g( [ a, b, c, d ], [ m( a, b ), m( d, b ), m( b, c ), m( b, d ), m( c, d ) ] )

65
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

In majoritatea cazurilor arcele sunt etichetate (caz in care spunem ca unei muchii i se
ataşează un cost) fapt care modifica structura de reprezentare de forma (exemplul s-a
facut pentru un cost definit de o valoare intreaga):
G = g( [ a, b, c, d ], [ m( a, b, 3 ), m( b, c, 7 ), m( c, d, 2), m( d, b, 4 ) ] )
Se pun două probleme :
- găsirea unui drum aciclic într-un graf;
- găsirea unui drum cu cost minim într-un graf.

10.1.2. Găsirea unui drum aciclic într-un graf.


Un drum e definit de o mulţime de muchii care conectează un nod de start şi unul
final, cu proprietatea că un nod, respectiv o muchie apare o singură dată în cadrul
drumului. Procedeul de constituire rezultă din următoarea secvenţă de figuri :

Formăm drumuri parţiale.

Iniţial se pleaca cu o lista cu un singur element care contine nodul tinta de forma [ Z ]

66
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

Desenul sugerează următoarea procedură recursivă de căutare a unui drum :


găsesc drumul de la Y la Z şi găsesc un drum de la A la X, care continuă cu drumul
parţial astfel încât nodul X (extremitatea muchiei ce conţine pe y) să nu fie prezent în
drumul parţial. Această observaţie conduce la definirea a două predicate având structura
:
% drum( Nod_start, Nod_final, Graf, Drum )
% drum_p( Nod_start, Drum_parţial, Graf, Drum_final )
Procedura prezintă următorul aspect :
domains
nod = symbol
muchie = m( nod, nod )
noduri = nod*
muchii = muchie*
graf = g( noduri, muchii )

predicates
drum( nod, nod, graf, noduri )
drum_partial( nod, noduri, graf, noduri )
adiacent( nod, nod, graf )
aparţine( nod, noduri )
aparţine( muchie, muchii )

clauses
drum( A, z, G, Drum ) if
drum_partial( A, [z ], G, Drum ).
drum_partial( A, [ A | Rest_drum ], _, [ A | Rest_drum ] ).
drum_partial( A, [ Y | Rest_drum ], G, Drum) if
adiacent( X, Y, G ),
not( aparţine( X, Rest_drum ) ),
drum_partial( A, [ X, Y | Rest_drum ], G, Drum ).
adiacent( X, Y, g( _, Arce ) ) if
aparţine( m( X, Y ), Arce );
aparţine( m( Y, X ), Arce).

67
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

Comentarii :
1. not( aparţine( ... ) ) implementează un mecanism de detecţie a unui ciclu în
cadrul unui drum parţial.
2. Predicatul adiacent furnizează ca rezultat un nod ce defineşte extremitatea
muchiei căutate. Deoarece în definirea grafului nu se impune o restricţie privind ordinea
de scriere a nodurilor, devine necesară prezenţa dublei verificări de apartenenţă (
determininată de prezenţa unei simetrii în scrierea unuei muchii, o muchie poate apare
de forma m(a,b) sau m(b,a)).
3. Rezultatele pot fi obţinute sub forma :
goal
G = g( [ a, b, c, d ], [ m( a, b ), ... , m( d, b ) ] ),
drum( a, d, G, D )
D = [ a, b, c, d ]
D = [ a, b, d ]
2 soluţii

Dacă se intenţionează construirea unei liste a tuturor drumurilor posibile, se va lucra


astfel :
domains
lista = noduri*

goal
findall( D, drum( a, d, G, D ), L),
write( " Drumuri = ", L).
Aceasta va da soluţia :
Drumuri = [ [ a, b, c, d ], [ a, b, d ] ]

10.1.3. Găsirea unui drum cu cost minim.


Spre deosebire de cazul anterior, simultan cu construcţia drumului parţial se va
calcula şi costul acestuia, definit de suma costurilor muchiilor din drum. In descrierea
muchiei este inclus costul acesteia sub forma : m( nod1, nod2, cost ).
domains
nod = symbol noduri = nod*

68
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

muchie = m( nod, nod, integer ) muchii = muchie*


graf = g( muchii )

predicates
% drum(Start, Tinta, Graf, Drum, Cost_Drum)
drum( nod, nod, graf, noduri, integer )
drum_partial( nod, noduri, integer, graf, noduri, integer )
adiacent( nod, nod, integer, graf )
aparţine( nod, noduri )
aparţine( muchie, muchii )
clauses
drum( A, z, G, Drum, Cost ) if
drum_partial( A, [ z ], 0, G, Drum, Cost ).
drum_partial( A, [ A | Rest_drum ], Cost, _, [ A | Rest_drum ], Cost ).
drum_partial( A, [ Y | Rest_drum ], Cost, G, Drum_final, Cost_final ) if
adiacent( X, Y, Costxy, G ),
not( aparţine( X, Rest_drum ) ), % ( detecţie cicluri )
Nou_cost = Cost + Costxy,
drum_partial( A, [ X,Y | Rest_drum],Nou_cost,
G,Drum_final,Cost_final ).
adiacent( X, Y, Costxy, g( Arce ) ) if
aparţine( m( X, Y, Costxy ), Arce );
aparţine( m( Y, X, Costxy ), Arce ).
Observaţie :
1) Procedura aparţine din adiacent determină un nod şi un cost al muchiei a cărei
extremitate a detectat-o.

2) In figura de mai jos se prezinta modalitatea de determina un drum si costul


aferent acestuia , ambele informatii find memorate liste separate de forma:

Drumuri = [ [ a, b, c, d ], [ a, b, d ] ] Costuri = [ 13, 10 ]

3) P
e
n
t

69
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

ru a gasi un drum de cost minim se procedeaza de o maniera asemanatoare


care face apel la un artificiu si anume:

minim(X,Z,Graf, MinDrum, MinCost) if


drum( A, Z, G, Drum, MinCost ),
drum( A, Z, G, _, Cost ),
MinCost<Cost
Artificiul utilizeaza modul de functionare a masinii de inferenta prin intermediul
careia se creaza practic un filtru. Astfel se propune un drum si un cost. Prin modul de
plasare a punctului de reluare, al doilea cost propus se compara cu primul considerat
minim, daca relatia de comparare este adevarata se pastreaza propunerea facuta, daca
nu se avanseaza un alt drum a carui cost este considerat minim. In acest mod se retine
un drum si un cost minim care se compara cu toate drumurile posibile de construit intre
nodul de start si cel tinta.

10.2. Arbori
Necesitatea e a utiliza arbori apare din urmatoarele considerente:
- spatiul alternativelor posibile este explorat intr-o maniera de tip arbore
- cunostintele se pot reprezenta prin structuri de tip arbore

10.2. 1. Reprezentare.
Un arbore se reprezintă ca un obiect recusriv sub forma :
arbore( arbore, rădăcina, arbore )
Datorita acestui mod de reprezentare se pune problema delimitarii zonei pana unde se
intinde un arbore. De obicei se utilizeaza pentru delimitarea frontierii arborelui un cuvant
specificat de utilizator, varianta de delimitator cu numele nill fiind cea mai utilizata in
prezent (este insa evident ca se poate utiliza orice alt cuvant). De exemplu pentru
arborele din figura de mai jos vom avea structura de date prezentata alturat.

70
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

10.5.2. Operaţii asupra arborilor.


Asupra arborilor se pot efectua operaţiile principale de inserare, ştergere şi
tipărire.

Inserarea ( construirea unui nod într-un arbore ).


La cel mai general nivel, arborele e privit ca fiind format dintr-o rădăcină R, un
subarbore stâng şi un subarbore drept. Premergător operaţiei de inserare apare operaţia
de verificare a apartenenţei unui nod la un arbore. Dacă vom considera că predicatul de
verificare e de forma :
in( nod, arbore ),
atunci procedura de verificare pentru o structura de forma

t(SubarboreStang,Nod,SubarboreDrept)
va avea forma :

nodul se afla in arbore daca:


in( X, t( _, X, _ ) ). - e identic cu rădăcina arborelui
in( X, t( S, _, _ ) ) if sau
in( X, S ). - se află în subarborele stâng
in( X, t( _, _, D ) ) if sau
in( X, D ). - se află în subarborele drept.

Pentru a optimiza operaţiile de căutare, s-a introdus noţiunea de Arbore Binar


Ordonat ( ABO ), care prezintă următoarele proprietăţi :
- rădăcina subarborelui stâng e mai mică decât rădăcina ABO;
- rădăcina subarborelui drept e mai mare decât rădăcina ABO;
- cei doi subarbori sunt, la rândul lor, ABO.

71
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

In aceste condiţii, operaţia de verificare a apartenenţei se optimizează, în sensul


selectării direcţiei de căutare, sub forma :
in( X, t( _, X, _ ) ).
in( X, t( S, R, _ )) if X < R, in( X, S).
in( X, t( _, R, D )) if X > R, in( X, D).

Plecând de la aceste considerente, operaţia de inserare a unui nod într-un arbore binar
ordonat poate fi realizată cu ajutorul predicatului :

inserez( nod, Tree, Nou_tree )

Procedura se construieşte plecând de la observaţiile :


- dacă arborele e vid, prin inserarea nodului X se obţine

arborele t( nil, X, nil )

- în caz contrar, inserarea se face în subarborele stâng, respectiv drept, în


funcţie de raportul existent între X şi R.

- Pentru un arbore binar cu noduri numere întregi, operaţia de inserare prezintă


in contextul acestei strategii aspectul:

domains

răd = integer

tree = t( tree, răd, tree )

predicates

ins( nod, tree, tree )

clauses

ins( X, nil, t( nil, X, nil ) ).

ins( X, t( S, R, D ), t( S_nou, R, D ) ) if X < R, ins( X, S, S_nou ).

ins( X, t( S, R, D ), t(S, R, D_nou ) ) if X > R, ins( X, D, D_nou ).

72
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

De obicei, procesul de inserare e utilizat în contextul unui apel repetitiv prin care
se construieşte arborele dorit. De exemplu, o astfel de procedură poate fi de forma :

domains
.
predicates
ins( nod, tree, tree )
start( tree )
clauses
start( T ) if
write( " Nod = " ), readint( N ),
ins( N, T, Tnou ) ! ,
write( " Arbore = " ), Tnou),
start( Tnou).
start( T ) if
prelucrez( T ).
Ieşirea din procedura de construire a ABO se face obligând predicatul
readint(N) să fie fals (pentru exemplul dat – orice alta modalitate de a obliga regula
sa devina falsa se poate utiliza).

Ştergerea unui nod dintr-un arbore binar ordonat (ABO).


Operaţia de ştergere pleacă de la următoarele observaţii :
- dacă la nodul care trebuie şters sunt conectaţi doi subarbori dintre care unul este
vid, conectarea se face direct, ataşând arborele nevid în locul elementului şters.
- dacă nodul prezintă doi arbori nevizi, atunci în locul nodului de şters se transferă
cel mai din stânga nod al arborelui drept, sau cel mai din dreapta nod al arborelui stîng.
Utilizând această metodă, arborele rămâne ordonat.

73
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

Implementare :

predicates
şterg( nod, arb, arb_nou )
clauses
şterg( X, t( S, X, nil ), S ).
şterg( X, t( nil, X, D ), D ).
şterg( X, t( S, X, D ), t( Snou, Y, D ) ) if mut( S, Y, Snou ).
şterg( X, t( S, R, D ), t( Snou, R, D ) ) if X < R, şterg( X, S, Snou ).
şterg( X, t( S, R, D ), t( S, R, Dnou ) ) if
X > R, şterg( X, D, Dnou ).
mut( t( S, Y, nil ), Y, S ).
mut( t( _, _, S ), Y, Snou ) if mut( S, Y, Snou ).

Similar ca în cazul inserţiei unui nod se poate defini o procedură repetitivă prin care se
pot şterge succesiv noduri în cadrul unui arbore.

Exerciţii:
1. Construiti procedura de tipărire a unui arbore binar astfel încât să apara grafic
structura lui. Se propune urmatorul mod de tiparire:

Arborele este rotit cu 90 grade astfel încât radăcina să fie punctul cel mai din stânga şi
elementele se tipăresc iniţial subarborele drept, astfel încât nodurile de aceeaşi înălţime
vor fi prezente pe aceeaşi coloană , se tipăreşte în continuare radacina, şi se continuă
cu subarborele stâng, respectând aceleaşi condiţii ca pentru subarborele drept.

74
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

Vom utiliza urmatoarele predicate


scriu(arb,pozitie) % scrie arborele
tab(poz) %pozitioneaza cursorul pe pozitia unde se va face scrierea

domains
tree=t(tree,integer,tree)
predicates
scriu(tree,integer) tab(integer)
clauses
scriu(nil, _).
scriu( t(S,R,D),Poz) :- Poz2=Poz+2,
scriu(D,Poz2),
tab(Poz),
write(R),nl, scriu(S,Poz2).
tab(0).
tab(P) :- write(" "), P1=P-1, tab(P1).

2. Construiti o procedură care construieste arborii unui graf conex


Se cunoşte că un graf conex prezintă proprietatea - plecind de la un nod se ajunge la
oricare altul inclusiv la cel de la care s-a plecat. In figura de mai jos pentru graful conex
dat rezulta un numar de trei arbori care pot fi construiti.
Graful apare sub forma:
graf=g(lista_muchii)
iar arborele se defineşte tot ca liste de muchii, ca in figura de mai jos.
Procedura de construcţie implică prezenţa predicatului extinde. Acesta are rolul de a
extinde (construi ) arborele plecând de la o muchie iniţială, la care prin adunarea
succesivă a unor muchii ce aparţin grafului se va tinde spre arborele final.

extinde(Arb,Arb_final,Graf)
extinde(Tree,Tree_f,Graf) :- adun(Tree,Tree-1,graf),
extinde(Tree_1,Tree_f,Greaf),!.
extinde(Tree,Tree,Graf) :- not(adun(Tree,_,Graf)).

75
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

adun - ataşează arborelui prezent o muchie a grafului respectând condiţiile ca aceasta


să nu existe în arborele deja prezent. Secventa este de forma:
adun(Tree,[m(X,Y)|Treee],Graf) :-
adiacent(X,Y,Graf),nod(X,Treee),not(nod(Y,tree)).

Unde: nod - verifică dacă un nod aparţine arborelui

nod(Nod,Tree) :- aparţine(n(Nod, _),Tree);


aparţine(m(_, Nod),Tree)).

procedura finală pentru un arbore cu noduri de tip sibol urmând această strategie va fi de
forma:
domains

nod=symbol arc=m(nod,nod)

arce=arc* graf=g(arce)

76
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

tree=arc*

predicates

tree(graf,tree) extinde(tree,tree,graf)

adun(tree,tree,graf) nod(nod,tree)

aparţine(arc,tree) aparţine(muchie,graf)

clauses
tree(Graf,Tree) :- apartine(Muchie,Graf),
extinde([Muchie],Tree,Graf).
Procedura extinde
Procedura adun
Procedura nod
Procedura aprtine

Procedura aparţine, extrage câte o muchie pe care o transmite predicatului extinde,


definind astfel punctul de iniţiere a construcţiei arborelui. Pentru ca aparţine va furniza ca
rezultat toate muchiile grafului se asigura testare fiecarei muchie ca punct de plecare
posibil de construire a unei structuri arborescente. Procedura aparţine(muchie,graf) este
identică de aparţine(arc,tree).

3. Construti o procedură ce determină înalţimea unui arbore, de forma:

înalt(Tree,Inaltime_Tree)

domains
tree=t(tree,integer,tree);nil
predicates
înalt(tree,integer)
max(integer,integer,integer)
clauses
înalt(nil,0).
înalt(t(S, _,D),Is) :- înalt(S,Is),înalt(D,Id), max(Is,Id,M), I=M+1.

77
Inteligenţă Artificială.
Structuri de Date. Grafuri, Arbori

4. Scrieți o procedura care sa creeze o listă cu frunzele existente intr-un arbore


binar de forma

% leaves(T,S) :- S este lista tuturor frunzelor din arborele binar T.

5. Un nod intern a unui arbore binar este un nod care are unul sau doi succesori
care nu sunt vizi. Scrieți o procedură care să creeze o lista cu nodurile interne a
unui arbore binar. Procedura este de forma

% intern (T,S) :- S este lista cu nodurile interne a unui arbore binar T.

6. Scrieți o procedura care sa numere cate frunze exista intr-un arbore binar de
forma

% count_leaves(T,N) :- arborele binar T are N frunze.

78
Inteligenţă Artificială. Tehnici.

11. STRATEGII DE CĂUTARE


11.1 Concepte.
Vom exemplifica formalizarea problemelor de IA pentru jocul de șah relativ la
conceptele fundamentale cat și pentru lumea cuburilor când le vom particulariza
(a) Spaţiul stărilor, Stare Inițială, Stare finală. Soluție

Prima preocupare într-o problemă de IA este de a


recunoaşte în problema generală instanţele acesteia

Să luăm ca exemplu jocul de şah. O poziţie de pe tablă reprezintă complet starea


jocului într-un anumit moment. Evoluţia jocului poate fi privită ca o secvenţă de tranziţii
dintr-o stare în alta, plecând de la o stare iniţială şi ajungând până într-o stare finală.
Există o stare iniţială descrisă de o poziţie standard, întotdeauna aceeaşi în orice joc de
şah. Nu există o anume stare finală, dar poate fi considerată stare finală orice
configuraţie a tablei în care un rege se află într-o poziţie atacată şi nu poate ieşi din
acea poziţie prin nici o mutare legală. Între aceste două stări există un număr finit dar
extrem de mare de posibilităţi de a ajunge prin mutări legale. Numărul total de poziţii ale
jocului de şah formează ceea ce se numeşte spaţiul stărilor.
Cum se defineşte o problemă? Dându-se o poziţie iniţială şi o indicaţie asupra
terminării (de exemplu, care jucător trebuie să câștige, eventual şi în câte mutări), cat și
regulile de joc. O astfel de descriere defineşte o instanţă de problemă.
In concluzie
 Spațiul stărilor este definit de un graf în care nodurile reprezintă configurații,
arcele tranziții intre configurații. Vom avea un nod de start care definește
starea inițiala și un (sau mai multe) noduri țintă care definesc starea finala.
 O instanță este definita de ansamblul stare inițială, stare finala, reguli de joc.
 O soluție într-o problemă de IA înseamnă găsirea unei căi între o stare iniţială
şi o stare finala

79
Inteligenţă Artificială. Tehnici.

(b) Stare

A doua preocupare într-o problemă de IA este de a recunoaşte


o stare şi de a aprecia dimensiunea spaţiului stărilor

Așa cum am spus în contextul jocului de șah o stare este definita de configurația
pieselor existente la un moment dat al jocului, ansamblul lor alcătuind ceea ce am
definit ca spațiul configurațiilor de joc posibile.
In concluzie
 Starea reprezintă a configuraţie anumită a entităţilor care populează
universul problemei în drumul spre soluţie.

Nu este însă întotdeauna elementar a decide care dintre momentele


intermediare trebuie considerată stare şi care nu. Aceasta afirmație este datorita
faptului ca o configurație de joc poate fi corecta sau nu din punctul de vedere al regulilor
de joc corespunzătoare în cazul nostru jocului de șah. De exemplu în cazul jocului de
șah plecând din starea inițială (alb la mutare) sunt corecte 28 configurații (24 fiind
datorate mutării pionilor iar 4 mutării cailor). Pe lângă aceste configurații corecte mai
exista încă 24 configurații incorecte datorate pionilor care avansează mai mult de 3
poziții intrând în câmpul advers la care se adaugă 2 poziții datorate mișcării cailor care
încearcă sa ocupe o poziție ocupata de un pion propriu. Aprecierea dimensiunii acestui
spațiu este esențială pentru alegerea modului de reprezentare a unei stări cat și pentru
strategia de trecere de la o stare inițială la una finala.

Spre exemplu pentru un joc care are în jur de 20 mutări (atât pentru piesele albe
cat și pentru piesele negre) se ştie că spaţiul stărilor în jocul de şah atinge
valoarea de 10120.

80
Inteligenţă Artificială. Tehnici.

(c) Reprezentarea unei stări

A treia preocupare într-o problemă de IA este găsirea


celei mai adecvate reprezentări a stărilor

Reprezentarea unei configurații reprezintă o problema extrem de importanta


datorita dimensiunii spațiului configurațiilor posibile care face ca resursele cerute
(memorie, putere de calcul) sa fie deosebit de mari. Acest aspect face ca problema sa
fie tratata separat de al strategiilor de rezolvare și sa constituie un capitol separat al IA.

(d) Reprezentarea unei tranziții

A patra preocupare în descrierea unei probleme de IA este


reprezentarea tranziţiilor posibile între stări (reguli)

Putem să ne imaginăm un proces de rezolvare în două moduri:


 manieră în care stările există deja, iar rezolvarea presupune o tranzitare, de
către un automat, a acestui spaţiu al lor deja generat şi o alta în care
 stările se creează doar în momentul atingerii lor, ele neexistând anterior.
În primul caz o mişcare legală provoacă părăsirea unei stări şi trecerea în alta, în
timp ce în al doilea caz o mişcare legală provoacă transformarea unei stări în altă stare.
Deosebirea are evident, o mare importanţă în eficienţa procesului de rezoluţie însă nu
influenţează maniera generală de rezolvare a problemei şi deci, nici considerentele
noastre din acest capitol.
Pentru efectuarea acestei "deplasări" în spaţiul stărilor trebuie aşadar definit un
set de reguli, sau operatori, care precizează ceea ce înseamnă mişcările legale. Se
întâmplă adesea ca aceleaşi tipuri de tranziţii să poată fi aplicate între perechi de stări
diferite. Spre exemplu, în Figura 1 sunt sugerate prin culori diferite patru tipuri de
tranziţii.

81
Inteligenţă Artificială. Tehnici.

Figura 1: Tranziţiile între stări pot fi clasificate după tipuri

Dacă este posibilă clasificarea tranziţiilor pe tipuri, atunci este probabil ca


aceleaşi tranziţii să se aplice atunci când stările de plecare au ceva în comun, cu alte
cuvinte îndeplinesc nişte condiţii similare. Acest lucru este sugerat în Figura 1 prin
elipse care acoperă parţial stările de plecare, colorate la fel cu săgeţile cărămizii. Acest
lucru face ca o tranziţie să poată fi descrisă, în general, de o construcţie de forma:

dacă starea satisface nişte condiţii,


atunci ea se transformă prin aplicarea asupra ei a unor acţiuni.

Aceste descrieri se mai numesc şi reguli de producţie. Din cele de mai sus rezultă
că preocuparea a patra constă în inventarierea tuturor tranziţiilor posibile între stări şi
descrierea lor ca reguli formate din condiţii şi acţiuni.

Există mai multe modalităţi de a descrie regulile, ori tranziţiile legale dintre stări. O
manieră ar putea fi "cu cărţile foarte aproape de ochi", cu alte cuvinte puternic influenţaţi
de anumite instanţe particulare ale problemei. În general obţinem astfel un număr mare
de reguli. De exemplu, o mişcare uzuală de deschidere la un joc de şah este avansarea
pionului cu două poziţii. Această mişcare a pionului nu este însă permisă decât atunci
când pionul se află în poziţia lui iniţială, în orice alt moment al jocului pionul putând
avansa doar cu o poziţie. Am avea aşadar o serie de reguli de forma:

82
Inteligenţă Artificială. Tehnici.

regula mută-pion-din-a
DACĂ
pion în poziţia (a,2) şi
poziţia (a,3) e liberă şi
poziţia (a,4) e liberă
ATUNCI
mută pionul din poziţia (a,2) în poziţia (a,4).

Vom avea un număr de 8 reguli de acest fel, câte una pentru fiecare pion.
O descriere satisfăcătoare trebuie însă să fie suficient de generală pentru a
putea fi utilizată în cât mai multe instanţe diferite ale problemei. O reprezentare mai
economică ar utiliza o singură regulă capabilă a exprima poziţia oricărui pion aflat pe al
doilea rând.
regula mută-pion(x)
DACĂ
pion în poziţia (x,2) şi
poziţia (x,3) e liberă şi
poziţia (x,4) e liberă
ATUNCI
mută pionul din poziţia (x,2) în poziţia (x,4).

În general o regulă este de forma:


<nume regulă>
DACĂ <condiţii> ATUNCI <aacțiuni>

Activitatea pe care o poate desfăşura o regulă poate fi exprimată astfel: dacă


partea de condiţii este satisfăcută de faptele existente în memoria de lucru, atunci
acţiunile pot fi executate.
Un set de reguli este specific unei probleme iar nu unei instanţe de problemă. Cu
alte cuvinte, acelaşi set de reguli trebuie să poată fi aplicat pentru rezolvarea oricărei
instanţe a unei probleme date.

83
Inteligenţă Artificială. Tehnici.

(e) Căutarea soluţiei


Am văzut până acum modul în care o problemă de IA poate fi formalizată. Am
discutat despre spaţiul stărilor unei probleme şi am prezentat cum să alegem o
reprezentare pentru stări. Ştim că tranziţiile între stări sunt descrise de un set de
operatori pe care le-am numit reguli de producţie şi am văzut că a rezolva o problemă
înseamnă a găsi un drum între o stare iniţială şi una sau mai multe stări finale ce sunt
cunoscute precis ori numai descrise printr-un set de restricţii. Maniera în care
organizăm căutarea în spaţiul stărilor, deci modul în care înlănţuim operatorii pentru
găsirea soluţiei constituie subiectul prezentului curs.

Problemele de IA se aseamănă prin aceea că toate presupun existenţa unei stări


iniţiale cunoscute, a uneia sau mai multe stări finale precizate exact sau prin condiţii, iar
rezolvarea ei înseamnă găsirea unui traseu între starea iniţială şi o stare finală. Aşadar,
de cele mai multe ori, a rezolva o problemă de IA înseamnă nu a găsi o anume stare, ci
a găsi un drum care să unească o stare iniţială de una finală.

stare stare finală


transitiv fundătură posibilă
e

stare finală
atinsă
stare
iniţială
solutia
n

dimensiunea spaţiului
stărilor

Figura 2 Spaţiul stărilor în problemele de IA

84
Inteligenţă Artificială. Tehnici.

Acest lucru face ca o problemă de IA să fie una de căutare într-un spaţiu al stărilor. În
funcţie de dimensiunea acestui spaţiu se utilizează diferite metode pentru a eficientiza
procesul de navigare. În limbajului domeniul IA, aceste metode se mai numesc şi
strategii. Există mai multe tipuri de strategii, dar ele sunt clasificate în două clase mari:

 Strategii de căutare neinformate, (Uninformed Search Strategy). Sunt


strategii oarbe, în care nu există nici o informație legată de direcția posibilă de
avans în spațiul alternativelor posibile. Căutarea soluției, se face fără a avea
informații legate de direcția care conduce la atingerea țintei.

 Strategii de căutare informate, (Informed Search Strategy). Sunt strategii în


care sunt prezente informații euristice, care fac posibilă determinarea unei direcții
probabile de căutare a soluției.

Datorită faptului ca numărul configurațiilor crește pe măsură ce noi configurații sunt


create, plecând de la configurația curentă denumirea acceptată în momentul de față
pentru astfel de probleme este cea de problemă de tip combinatorial.

O problemă de tip combinatorial este definită de:


- un spaţiu al stărilor posibile
- o stare iniţială şi una finală, care pot fi oricare din stările posibile
ale spaţiului alternativelor.

Concluzii
Rezolvarea unei probleme de IA are două aspecte:
- formalizarea problemei, care presupune recunoaşterea diferenţei dintre problema
generală şi o instanţă a acesteia, recunoaşterea a ce constituie cea mai bună
alegere pentru stări, găsirea unei reprezentări a stărilor şi găsirea unei
reprezentări pentru reguli;
- lansarea unei căutări în spaţiul stărilor care să găsească o cale între starea
considerată iniţială şi o stare finală.

85
Inteligenţă Artificială. Tehnici.

Măsuri cantitative şi calitative pentru estimarea eficienţei unei strategii de


căutare.
Acestea sunt următoarele:
 Măsuri cantitative:
 Complexitatea de Timp a strategiei T - în cât timp (măsurat ca număr de
paşi ai algoritmului) este găsită soluţia.
 Complexitatea de Spaţiu a strategiei S – de cât spaţiu (este vorba de
memorie) este nevoie pentru găsirea soluţiei.

Măsurile cantitative sunt aprecieri pur cantitative.


Notația utilizată este O(Complexitate)

 Măsuri calitative:
 Completitudine – o strategie se numeşte completă dacă garantează găsirea
unei soluţii.
 Optimalitate – o strategie se numeşte optimală dacă garantează găsirea
celei mai bune soluţii din punctul de vedere al costului căii între starea iniţială
şi starea finală.

Masurile calitate sunt aprecieri binare. Astfel completitudinea este întotdeuna o


proprietate binară: o strategie este sau nu este completă. În ceea ce priveşte
optimalitatea, aceasta este în general tot o proprietate binară: o strategie este sau nu
este optimală, dar, există şi strategii, numite sub-optimale, care nu găsesc cea mai
bună soluţie dar găsesc o soluţie foarte apropiată ca şi cost de cea mai bună soluţie.

86
Inteligenţă Artificială. Tehnici.

11.2. Strategii de căutare neinformate


Așa cum am specificat spațiul stărilor este definit de un graf în care nodurile
corespund la situaţiile posibile, iar arcele la tranziţiile care sunt autorizate între stări.
Problema găsirii unei soluţii este echivalentă cu găsirea unui drum între starea iniţială
(dată de nodul de start) şi o stare finală (specificată de nodul ţintă). Determinarea
drumului între start şi ţintă presupune exploatarea unor alternative pe măsură ce se iau
în considerare.
Rezolvarea problemei impune găsirea unei strategii care să asigure
determinarea celui mai scurt drum între start şi ţintă. Sunt prezentate 2 strategii de
căutare neinformată, fundamentale, care stau la baza tuturor operațiilor de căutare în
spațiul alternativelor posibile:

 una de căutare în adâncime, (Depth-first search)


 cealaltă de căutare în lăţime a alternativelor posibile (Breadth-first search).

În cele ce urmează, vom considera că generarea unei alternative este


implementată de procedura S(X,Y) (succesor). Aceasta procedură este specificată
fiecărei probleme în parte. Practic, S(X,Y) va implementa regulile de mutare (trecere de
la o configurație curenta la na următoare) pentru jocul logic sau strategic luat în
considerare.
In cadrul discuției vom utiliza un concept suplimentar și anume cel de arbore de
căutare. Spațiul alternativelor posibile este definit de un graf. Datorita faptului ca
alternativele (configurațiile) se construiesc pe măsura ce se avansează în acest spațiu
se formează un arbore de căutare a alternativelor posibile , acesta reprezentând o
submulțime din spațiul stărilor. Vom utiliza acest concept deoarece în marea majoritate
a situațiilor reale nu vom avea niciodată acces la toate stările spațiului.

87
Inteligenţă Artificială. Tehnici.

11.2.1 Căutarea în adâncimea arborelui de alternative.


Principiul de căutare Depth-First Search – (DFS) este ilustrat de cele două figuri
de mai jos:

Adâncimea de căutare d=3, numărul de succesori b=2

88
Inteligenţă Artificială. Tehnici.

Dacă considerăm că nodul de start este 'a' şi ‘j’, ‘f’ sunt soluţiile posibile, căutarea
în adâncime presupune vizitare tuturor nodurilor aflate pe fiecare ramură până în
momentul găsirii soluţiei căutate, apelul fiind de forma
?- rezolva(a,Sol)
Sol=[a, b, e, j]
Căutarea în adâncime se pretează stilului recursiv al mașinii de inferență din
Prolog, deoarece însăşi căutarea de tip backtracking este o tehnică de căutare în
adâncime.
Principiul de căutare a soluției – lista de configurații, intre configurația inițială și
cea finala – poate fi definit astfel:
Se pleca de la configurația inițială se generează prin procedura S(X,Y)
succesori ai poziției curente X, aspect care are ca efect creșterea arborelui de căutare
și formarea de drumuri parțiale. Acestea se dezvolta pana în momentul în care una din
configurațiile generate reprezintă ținta ( ținta fiind considerata una din configurațiile
finale posibile de atins). în acest moment, drumul parțial devine o soluție care se
creează pe rezolvarea apelurilor recursive.
Principiul căutării în adâncime este definit de un predicat de forma:
caut_a(Drum, Nod, Solutie)
și este ilustrat de figura:

Tehnica poate da greş dacă apar alternative identice care se repetă (in calea

89
Inteligenţă Artificială. Tehnici.

determinată pana în momentul curent este prezenta configurația care s-a generat ca
alternativa următoare a stării curente). Astfel de situaţii impun implementarea unui
mecanism de detecţie a ciclurilor, al cărui rol este interzicerea deplasării pe direcţia în
cauză

In cadrul strategiei de căutare prezentate considerăm că :


 Drum = listă noduri între start şi nodul curent (un drum parțial)
 Soluţie = drum extins prin Nod, până la ţintă
 Nod reprezintă o alternativă intermediară ce poate fi găsită în drumul până la
nodul ţintă.
Cu remarca ca Soluţie şi Drum sunt liste de noduri, în care Drum este o soluţie
posibilă, care devine definitivă în momentul atingerii ţintei, procedura de căutare poate
apare sub forma:
rezolvă (Start,Solutie) if
caut_a([ ], Start, Solutie).
caut_a(Drum, Nod, [Nod|Drum]) :-
apartine(Nod,Tinte).
caut_a(Drum, Nod, Solutie) if
s(Nod, Nod1),
not(apartine(Nod1, Drum)),
caut_a([Nod|Drum], Nod1, Solutie).

90
Inteligenţă Artificială. Tehnici.

Se pot face observaţiile:


- soluţia problemei este o listă de stări alternative în ordine inversă. Primul
element este ţinta , ultimul - nodul de start.
- not(apartine(Nod1, Drum)) verifică dacă alternativa generată nu a fost deja
luată în considerare prin prezenţa sa în drumul construit până în
prezent.
- O problema care apare este aceea ca datorita complexității problemelor
,spațiul stărilor poate fi extrem de mare, astfel încât exista riscul pierderii
controlului (numărul drumurilor parțiale care se construiesc este atât de
mare încât apare posibilitatea săturării stivei datorita multiplelor apeluri
recursive). Pentru a preveni astfel de cazuri, se introduce o procedura de
limitare a adâncimii de căutare. Practic, aceasta consta intr-un contor care
limitează înălțimea arborelui de căutare în spațiul alternativelor posibile.
Pentru exemplul dat, strategia căutării în adâncime cu limitarea
adâncimii de căutare, Depth-Limited Search – (DLS) apare de forma:

rezolva(Start, Solutie) if
caut_a([ ], Start, Solutie, Adancime_max).
caut_a(Drum, Nod, [Nod|Drum] ) :-
apartine(Nod,Tinte).
caut_a(Drum,Nod,Sol,Max)if
Max>0,
s(Nod, Nod1),
not(apartine(Nod1,Drum)),
Max1=Max-1,
caut_a([Nod|Drum], Nod1, Sol, Max1).

- variantă a strategiei de tip DLS apare în momentul în care adâncimea de


căutare se modifică iterativ. Principiul este ilustrat de secvența de figuri
următoare:

91
Inteligenţă Artificială. Tehnici.

Strategia cunoscută sub denumirea de Iterative Deepening Search – IDS ,


implică creșterea adâncimii de căutare dacă nu s-a găsit starea de tip țintă. Această
abordare reprezintă un compromis între tehnicile DFS și DLS deoarece pe de o parte se
evită un avans necontrolat pe o direcție de căutare (DFS) iar pe de altă parte nu
blochează căutarea ca în cazul strategiei DLS.

Avantaje și Dezavantaje
O căutare complectă pentru un arbore de căutare de adâncime d, în care fiecare
nod are b succesori, conduce la un număr total de noduri:
 pentru strategia DLS
NDLS = b0 + b1 + b2 + … + bd-2 + bd-1 + bd
 pentru strategia IDS
NIDS = (d+1)b0 + d b1 + (d-1)b2 + … + 3bd-2 +2bd-1 + 1bd

De exemplu pentru b = 10, d = 5,


o NDLS = 1 + 10 + 100 + 1,000 + 10,000 + 100,000 = 111,111

92
Inteligenţă Artificială. Tehnici.

o NIDS = 6 + 50 + 400 + 3,000 + 20,000 + 100,000 = 123,450

Dacă notăm Complexitatea strategiei de căutare, timp și spațiu, cu O(bd) vom avea
 pentru strategia DLS , O(bd)DLS
 pentru strategia IDS , O(bd+1)IDS

11.2.2. Căutarea în lăţime.


Tehnica de căutare Breadth-First Search – (BFS) asigură parcurgerea acelor
noduri care sunt mai apropiate de nodul de start. Ca urmare rezultă un proces ce tinde
să se dezvolte în lățimea spaţiului alternativelor posibile, (v. figura de mai jos). Apelul în
acest caz este de forma:
?- rezolvă(a,Sol).
Sol=[a, c, f]

Strategia ridică problema menţinerii în atenţie a unui set de noduri ( și nu a unuia


singur ca în cazul căutării în adâncime) care reprezintă vârfurile arborelui la care s-a
ajuns cu operaţia de căutare la un moment dat. Acest set de noduri nu este suficient,
motiv pentru care se menţine în atenţie un set de drumuri posibile. Acestea drumuri
posibile, sunt reprezentate fiecare printr-o listă de noduri, al căror prim element va fi
întotdeauna nodul cel mai recent generat, iar ultimul element va fi întotdeauna nodul de
strat. La un moment dat, căutarea este iniţiată de un singur drum şi respectiv de un

93
Inteligenţă Artificială. Tehnici.

singur element de forma [ [Nod_Start ] ], care este dezvoltat în unul sau mai multe
drumuri din care la un moment dat se selectează drumul soluție.

Pentru a exemplifica procedeul, pentru exemplul dat în figură avem:


1) primul drum conţine nodul de start de la care se iniţiază procesul de căutare:
[[a]]
2) se generează o extensie a nodului de start rezultând
[ [b, a], [c, a] ]
3) se scoate primul drum din set şi se generează o extensie a acestuia rezultând
[ [d, b, a] , [e , h, a] ].

Drumurile noi rezultate se amplasează la sfârșitul drumului iniţial sub forma:


[ [c, a], [d, b, a], [e ,h, a] ]
4) Se scoate [c, a] și extensiile care apar se adaugă la drum
[ [d, b, a], [e, b, a], [f, c, a], [g, c, a ] ]
5) operaţia continuă până în momentul în care drumul ce urmează a fi extins
prezintă ca nod de creştere nodul ţintă. Pentru exemplul dat, situaţia apare sub forma:
[ [f, c, a], [g, c, a], [h, d, b, a], [i, e, b, a], [j, e, b, a] ]
Cu observația ca Soluţie reprezintă un drum ce pleacă din start şi ajunge în
ţintă şi Drum este o lista a drumurilor ce se dezvolta pe parcurs strategia de căutare
prezintă aspectul.

rezolvă (Start, Soluție) if


caut_l([ [Start] ], Soluție).
caut_l ([ [Nod|Drum]| _ ], [Nod|Drum]) :-
aparține(Nod,Ținte).
caut_l ([ [Nod|Drum]| Drumuri], Soluție) :-
findall (Nod1,s(Nod,Nod1), Noi_noduri),
adaug ([Nod|Drum], Noi_noduri, Noi_drumuri),!,
conc (Drumuri, Noi_drumuri, Drumuri1),
caut_l (Drumuri1,Sol) ;
caut_l (Drumuri,Sol).

94
Inteligenţă Artificială. Tehnici.

adaug ( _, [ ], [ ]).
adaug (Drum, [Nod1|Rest], [ [Nod1|Drum] | Drumuri_noi]) if
not(aparține(Nod1,Drum)),
adaug(Drum,Rest,Drumuri_noi).
%conc implementează procedura de concatenare

Comentarii
1) Prin findall se generează toţi succesorii (alternative) posibili ai unui nod dat.
Acestea sunt incluse intr-o listă de noi alternative.
2) adaug utilizează noile alternative pentru a crea noi drumuri posibile plecând de
la drumul care a iniţiat construirea alternativelor not(aparține) verifică dacă nu există
alternative identice, caz în care se renunţă la direcţia de dezvoltare în cauză (drum este
o variantă moartă, care se abandonează).
3) conc pune noile drumuri găsite la sfârşitul listei iniţiale.
4) deoarece este posibil ca prin findall să nu se determine nici o alternativă
posibilă (nu mai există succesori), operaţia de căutare va continua pe lista iniţială,
minus drumul abandonat.
5) aceeaşi problemă se poate pune şi pentru căutarea în lăţime, referitoare la
limitarea adâncimii de căutare.
6) Avantaje și Dezavantaje

Dezavantaj : cantitatea mare de memorie.


O căutare complectă pentru un arbore de căutare de adâncime d, în care fiecare
nod are b succesori, conduce la un total de
1 + b + b2 + ... + bd = (b(d+1) - 1) / (b-1).
Complexitatea strategiei de căutare, timp și spațiu, se va nota cu O(bd+1). De
exemplu pentru o căutare complectă într-un spațiu al stărilor definit de un arbore cu
adâncime 12 , unde fiecare nod are 10 succesori, va conduce la o complexitate de
1 + 10 + 100 + 1000 + ... + 1012 = (1013 - 1)/9 = O(1012) noduri.
Dacă strategia rezolvă 1000 noduri pe secundă iar fiecare nod utilizează 100
bytes de memorie , vor fi necesari 35 ani pentru a rula strategia în cel mai rău caz, și se
va utiliza o cantitate de 111 terabytes de memorie !

95
Inteligenţă Artificială. Tehnici.

Avantaj : soluţie optimă

În rezumat avantajele respectiv dezavantajele strategiilor de căutare neinformate sunt


prezentate în tabelul următor, unde
 b - este numărul de succesori ( numărul de ramuri din poziția curentă)
 l - adâncimea maximă de căutare permisă
 d - adâncimea unde este prezentă soluția optimă
 m - adâncimea maximă de căutare atinsă

Criteriul Depth-First Depth-Limited Iterative Breadth - First


Search - Search – Deepening Search –
(DFS) (DLS) Search – IDS (BFS)
Timp O(bm) O(bl) O(bd) O(bd+1)
Spațiu O(bm) O(bl) O(bd) O(bd+1)
Optim? Nu Nu Da Da
Complect? Nu Da if l ≥ d Da Da

Exerciții
1. Scrieţi procedura de căutare în adâncime, atunci când adâncimea de căutare
este limitata. Care sunt dezavantajele acestei strategii?

2. Menţionaţi dezavantajele pe care le implica procedura de căutare în adâncimea


spaţiului de stări şi cum pot fi remediate (dacă este posibil).

3. Menționați dezavantajele pe care le implică procedura de căutare în lățimea


spațiului de stări.

96
Inteligenţă Artificială. Tehnici.

12.TEHNICI DE CONSTRUCŢIE A PROCEDURILOR


DE TIP SUCCESOR.
Vom exemplifica formalizarea problemelor ridicate de tehnicile de construire a
succesorilor în IA pe câteva exemple de probleme considerate clasice. Astfel de
probleme, datorită dimensiunilor lor mici, sunt cunoscute în literatură sub numele de
probleme jucărie (toy problems). În multe cazuri studiul lor ajută la identificarea
metodologiei de rezolvare a problemelor de dimensiune reală. În alte cazuri însă
diferenţa de dimensiune între problemele jucărie şi cele reale este atât de mare încât
soluţiile probate pe primele nu pot fi aplicate pe cele din urmă. Şi într-un caz şi în
celălalt studiul problemelor jucărie constituie un antrenament util pentru dezvoltarea
abilităţilor de a lucra cu concepte ale domeniului IA.

Procedura de generare a unei alternative plecând de la o stare data este


specifică fiecărui tip de problema în parte. Se pot deosebi totuşi doua modalităţii de
lucru care:
1) implica utilizarea unor obiecte standard PROLOG
2) implica utilizarea unor obiecte compuse utilizator

12.1. Alternative reprezentabile prin obiecte standard PROLOG


Alternativa (instanţa) este o listă ale cărei elemente sunt de tip întreg, symbol,
sau liste de elemente de tipul specificat anterior.

Problema misionarilor şi canibalilor: 3 misionari şi 3 canibali se află la marginea unui


râu cu scopul de a trece pe celălalt mal. Ei au la dispoziţie o barcă de două persoane.
Dacă la un moment dat, pe un mal sau pe celălalt numărul canibalilor întrece pe cel al
misionarilor, misionarii sunt în pericol de a fi mâncați de canibali. Problema constă în a
afla cum pot trece râul cele 6 persoane în deplină siguranţă.

Instanţele care caracterizează o alternativă (configurație) pentru această


problema pot fi definite după cum urmează:
 Configurația : este în acest caz dată de o listă cu 5 elemente de tip întreg în
care se reprezintă numeric și pozițional configurația unei alternative.
97
Inteligenţă Artificială. Tehnici.

Convenim să codificam configurația de forma:

 Poziția bărcii este codificata de forma

- 1 daca se află pe malul stâng


Barca=
1 dacă se află pe malul drept

Cu această reprezentare starea iniţială şi starea finală se vor codifica ca în figura


de mai jos:

 Devine necesară inclusiv reprezentarea modului de ocupare a bărcii :


[misionar, canibal]
Pentru generarea succesorilor trebuie luate în considerare toate posibilităţile de
ocupare a bărcii sub forma, ceea ce se va obține prin intermediul unui obiect compus de
98
Inteligenţă Artificială. Tehnici.

forma:
ocup_barca([1,0], [0,1], [1,1], [2,0], [0,2])

Acesta urmează să fie utilizat în procedura de generare a stărilor alternative


configurației curente în conformitate cu regulile de traversare. Procedura succesor
integrata intr-o strategie de căutare în adâncime va avea următorul aspect:

domains
nod=integer* drum=nod*
predicates
rezolva(nod,drum) caut_a(drum,nod,drum)
apartine(nod,drum) s(nod,drum,nod)
test(integer,integer,integer,integer)
clauses
rezolvă(Nod,Solutii) :- caut_a([ ],Nod,Solutie).
caut_a(Drum,Nod,[Nod|Drum]):- Nod=[1,0,0,3,3].
caut_a(Drum,Nod,Sol) :-
s( Nod,
[[1,0], [0,1], [1,1], [2,0], [0,2]],
Nod1),
not(apartine(Nod1,Drum)),
caut_a([Nod|Drum],Nod1,Sol).
/*
s(configuratie_curenta, ocupare_barca, configuratie_ulterioara)
D  pozitia barcii
Ms  numar misionari de pe malul stang
Cs  numar canibali de pe malul stang
Md  numar misionari de pe malul drept
Cd  numar canibali de pe malul drept
Configuratia_ulterioara este D1, Ms1, Cs1, Md1, Cd1
*/
s( _, [ ], [ ] ).

99
Inteligenţă Artificială. Tehnici.

s( [D, Ms, Cs, Md, Cd], [[M,C]| _], [D1, Ms1, Cs1, Md1, Cd1] ) :-
Ms1 is Ms-M*D, Cs1 is Cs-C*D,
Md1 is Md+M*D, Cd1 is Cd+C*D,
D1 is -1*D,
test (Ms1,Cs1, Md1, Cd1).
s(R, [ _ |R1], R2) :-
s(R, R1, R2).
test(M, C, M1, C1) :-
M>=0, C>=0, M1>=0, C1>=0, M>=C, M1>=C1;
M>=0, C>=0, M1>=0, C1>=0, M>=C, M1=0;
M>=0, C>=0, M1>=0, C1>=0, M=0, M1>=C1.

Pot fi făcute următoarele observații:


 Procedura succesor s utilizează variantele de ocupare a bărcii pentru a
aduna sau scădea pe ocupanţii acesteia pentru generarea configurațiilor
posibile a fi obținute din cea curenta. Se scad ocupanții bărci din numărul
prezent pe malul de unde se pleca și se aduna la numărul prezent pe malul
unde se ajunge.
 Schimbarea sensului de mers este asigurată de comutatorul D (direcţie), care
este basculat utilizând un artificiu de forma
D1 is -1*D,

 . Procedura test verifică condiţiile impuse problemei


1. numărul misionarilor trebuie să fie mai mare sau cel puțin egal cu cel al
canibalilor;
2. apare un caz particular datorat modului în care se genereaza
configurațiile ulterioare celei curente (prin scădere și adunare) situaţia
în care pe un mal pot fi 0 sau <0 misionari respectivi canibali. Acest
aspect reprezintă o consecința a modului de generare și apare ca o
restricție suplimentara de care trebuie să se tina cont.
 .Procedura
s(R, [ _ |R1], R2) :-

100
Inteligenţă Artificială. Tehnici.

s(R, R1, R2).


Asigura parcurgerea tuturor configurațiilor posibile de încărcare a bărcii.

Problema celor patru cavaleri: Pe o tabla de șah de dimensiune 3 x 3 sunt


amplasați 4 cai ca în figura de mai jos. Se cere specificarea secvenței de mutări care
să asigure trecerea din starea initiala în cea finala specificata în figura. Caii se vor
amplasa în starea finala fără a exista o restricție impusa de poziția cailor pe poziții
impuse. Prima mutare este efectuată de un cal alb, urmând ca în continuare mutările să
se facă alternativ.

Instanţele care caracterizează o alternativa (configuratie) pentru aceasta


problema pot fi definite după cum urmează:
 Configurația este definita în acest caz de o listă de elemente de tip integer, ce
definesc poziţia pe tablă a unei piese. În cadrul listei, poziţia pieselor albe şi
negre alternează, modelând ordinea de mutare. Se consideră o numerotare a
poziţiilor de forma (vezi figura de mai jos) [1, 6, 3, 8]:

101
Inteligenţă Artificială. Tehnici.

 Secvenţa de mişcări autorizate rezultă din următoarea observații:


Considerăm un sens de parcurs orar, mişcările autorizate (rezulta din pozițiile
libere în care poate fi amplasata o piesa de șah) vor fi definite de o lista de forma:

Miscari_autorizate is [1, 5, 6, 2, 8, 4, 3, 7, 1 ]
 Procedura succesor va prezenta următoarea structura
s(configuratie_curenta, miscari_autorizate, configuratie_urmatoare)
Considerând ca am o pozitie curenta corespunzătoare celei din figura de mai sus unde
am 2 cai albi pe 1 și 3 , respectiv am 2 cai negri pe 5 și 7 procedura succesor va
apare de forma:

/*
Tabla de șah apare sub forma
-------------
l 6 l 7 l 8 l
l---l---l---l
l 4 l l 5 l
l---l---l---l
l 1 l 2 l 3 l
-------------
am 2 cai albi pe 1 și 3
am 2 cai negri pe 6 și 8
*/
domains
lista=integer*

predicates
s(lista,lista,lista)
muta(integer, integer, lista)
subst(integer, integer, lista, lista)
apartine(integer,lista)

goal
P is [1, 6, 3, 9 ],
Miscari_autorizate is [1, 5, 6, 2, 8, 4, 3, 7, 1 ],
s([P, Miscari_autorizate,Configuratie_urmatoare),
write(Configuratie_urmatoare).

clauses
s(Poz, Misc, Pnou) :-
apartine(Piesa, Poz),
muta(Piesa, Piesa1, Misc),
not(apartine(Piesa1, Poz)),
102
Inteligenţă Artificială. Tehnici.

subst(Piesa,Piesa, Piesa1, Poz, Pnou).

muta(P, P1, [ P, P1 | _ ]).


muta(P, P1, [ P, P1 |Rest]) :-
muta(P, P1, Rest).

subst(P, P1, [P | Tabla], [P1|Tabla]).


subst(P, P1, [X | Tabla], [X|Tabla1]) :-
subs(P, P1, Tabla, Tabla1).

% procedura apartine

 Se pot face urmatoarele observatii relative la modul în care sunt generate pozitiile
succesive celei curente:
1. muta(Configuratie_curenta, Configuratie_urmatoare, Miscari_autorizate) are rolul
de a gasi o mutare posibila plecand de la o configuratie de piese data.
2. subst(Pozitie_curenta_Piesa, Pozitie_urmatoare_Piesa, Configuratie_Curenta,
Configuratie_Urmatoare) are rolul de a efectua o mutare propriuzusa pe tabla de
sah.
3. apartine actioneaza în doua moduri. Initial selecteaza o pozitie pe tabla, iar în al
doilea caz verifica daca pozitia în care este posibila de efectuat mutarea este sau
nu ocupata de alta piesa.

Problema coumtatoarelor: Se considera un numar de 6 intrerupătoare care se


găsesc intr-o pozitie oarecare, de exemplu:

Se doreste ca cestea să apara sub forma

103
Inteligenţă Artificială. Tehnici.

Se impune ca la un moent dat se pot misca numai doua comutatoare la un moment dat.

Instanţele care caracterizeaza o alternativa (configuratie) pentru aceasta


problema pot fi definite dupa cum urmeaza:
 Configuratia este definita în acest caz de o listă de elemente de tip integer, 6
elemente, ce definesc poziţia și starea unui comutator. Convenim să notam
cu 0 respectiv 1 starea comutatorului. Cu aceasta conventie, starile
corespunzatoare de ai sus apar de forma:

Starea a  [ 0, 0, 0, 1, 0, 1 ] Starea b  [ 1, 1, 1, 1, 1, 1 ]

 Se va utiliza o procedura de generare a succesorilor de forma de forma:


s(Configuratie_Curenta,
Configuratie_posibila_de_actionare_Comutatoare,
Configuratie_Urmatoare_dupa_Basculare)

 Pentru a putea lua în considerare toaate configuratiile de comutare posibile în


procedura successor apare
Configuratie_posibila_de_actionare_Comutatoare
prin care se codifică perechile de comutatoare care pot fi acționate.

104
Inteligenţă Artificială. Tehnici.

 Operația propriu zisă de codificare a modificării stării unui comutator prin


basculare se va reprezenta sub forma:
stare_noua = - stare_curenta + 1
Procedura incorporata intr-o strategie de căutare în adâncime (s-a limitat adâncimea
de căutare la 20) apare în continuare de forma
/*
nod  reprezintă o configurație a comutatoarelor in
spațial stărilor, fiind definite de o lista de
numere întregi
drum  reprezintă o secvența de configurații de
comutatoare, fiind definite de o lista de
configurații de tip nod
*/

domains
nod=integer* drum=nod*
predicates
rezolva(nod,drum) caut_a(drum,nod,drum,integer)
apartine(nod,drum) s(nod,nod,nod)
goal
rezolva([0, 0, 0, 1, 0, 1], R),
write(“Solutie de comutare”),nl.

clauses
rezolvă(Nod,Solutie) :-
caut_a([ ],Nod,Solutie,0).
caut_a(Drum,Nod,[Nod|Drum]):-
Nod is [1,1,1,1,1,1].
caut_a(Drum,Nod,Sol,Adancime) :-
s( Nod,
[1, 2, 3, 4, 5 ],
Nod1),
not(apartine(Nod1,Drum)),
Adancime1 is Adancime + 1,
Adancime <= 20,
caut_a([Nod|Drum],Nod1,Sol,Adancime1).
/*
s(configuratie_curenta,
configuratii autorizate de comutare,
configuratie_ulterioara)
C1,C2,C3,C4,C5,C6  configuratia initiala de
Comutatoare
NC1,NC2,NC3,NC4,NC5,NC6  configuratia ulterioara de
Comutatoare

105
Inteligenţă Artificială. Tehnici.

*/
s([C1,C2,C3,C4,C5,C6], [1 | _ ], [NC1, NC2, C3,C4,C5,C6]) :-
NC1 is -C1 + 1,
NC2 is -C2 + 1.
s([C1,C2,C3,C4,C5,C6], [2 | _ ], [C1, NC2, NC3,C4,C5,C6]) :-
NC2 is -C2 + 1,
NC3 is -C3 + 1.
s([C1,C2,C3,C4,C5,C6], [3 | _ ], [C1, C2, NC3,NC4,C5,C6]) :-
NC3 is -C3 + 1,
NC4 is -C4 + 1.
s([C1,C2,C3,C4,C5,C6], [4 | _ ], [C1, C2, C3,NC4,NC5,C6]) :-
NC4 is -C4 + 1,
NC5 is -C5 + 1.
s([C1,C2,C3,C4,C5,C6], [5 | _ ], [C1, C2, C3,C4,NC5,NC6]) :-
NC5 is -C5 + 1,
NC6 is -C6 + 1.
S(L1, [_ | R], L2) :-
S(L1, R, L2)
% procedura apartine

Problema mutarii unei stive de cuburi: Se cere definirea planului de miscari care
conduce de la o configuratie data de 3 cuburi la o configuratie tinta formata de
asemnea din aceleasi 3 cuburi altfel pozitionate.

Instanţele care caracterizeaza o alternativa (configuratie) pentru aceasta


problema pot fi definite dupa cum urmeaza:
 Configuratia este definita în acest caz de o listă de elemente de tip symbol,
fiecare element reprezentand o configuratie posibila pe de o parte și o pozitie
pe suport pe de alta parte. Convenim să consideram ca blocul din varful stivei
este reprezentat de capul listei. Pentru exemplul dat în figura urmatoare vom
avea structurile de date prezentate alaturat fiecarei configuratii în parte.
 Deoarece se ia în considerare și pozitia de amplasare este evident ca ultimile
doua configuratii care din punct de vedere structural sunt identice mai pot
prezenta fiecare cate o varianta în plus

106
Inteligenţă Artificială. Tehnici.

 Având în vedere că un nod reprezintă o configuraţie de 3 stive în care o stivă


poate fi formată din unul, doua , trei blocuri sau nici un bloc, generarea unei
alternative se face în acord cu următoarea regulă:

Nodul 2 este un succesor al nodului 1 dacă în nodul 1 există două stive notate
cu S1 și S2, iar blocul din vârful lui S1 poate fi mişcat pe S2.

In aceste condiţii secvenţa de generare a unui nod sucesor unui nod dat în contextul
unei strategii de căutare în adincime apare sub forma:

domains
bloc =symbol stiva =bloc*
nod =stiva* drum =nod*

107
Inteligenţă Artificială. Tehnici.

predicates
s(nod,nod) sterg(stiva,nod,nod)
rezolva(nod,drum) caut_a(drum,nod,drum)
apartine(stiva,nod) apartine (nod,drum)

goal
rezolva( [[a], [b], [c] ], R ), write(R).

clauses
rezolva(Nod,Solutie) :-
caut_a([ ],Nod,Solutie).

caut_a(Drum,Nod,[Nod|Drum]) :-
apartine([a,b,c],Nod).

caut_a(Drum,Nod,Sol) :-
s(Nod, Nod1),
not(apartine(Nod1, Drum)),
caut_a([ Nod | Drum ], Nod1, Sol).

s(Nod,[ Stiva1, [V1 | Stiva2 ]| AlteStive ]) :-


sterg( [V1 | Stiva1], Nod, Nod1),
sterg(Stiva2, Nod1, AlteStive)..

sterg(X,[X|L],L).
sterg(X,[Y|L],[Y|L1]) :- sterg(X,L,L1).

apartine(X,[X|_]).
apartine(X,[_|R]) :- apartine(X,R).

108
Inteligenţă Artificială. Tehnici.

Comentarii
1. In procedura succesor predicatul sterg acţionează în două etape:
- In prima în regim de lucru procedural ( sterg ( o, i, o) ) selecţionează stiva care
urmează să fie ştearsă iar
- în a doua care lucrează de asemenea în mod procedural ( sterg ( i, i, o) ) se
procedează efectiv la ştergerea stivei din nod.
2. Presupunând că se pleacă de la prima configuraţie pentru primul predicat sterg
avem:
sterg ( [ _ | _ ] , [ [ a ] , [ b ] , [ c ] ] , _ )
cu rezultatul

iar la a doua apelare


sterg ( [ a | [ ] ] , [ [ a ] , [ b ] , [ c ] ] , _ )
cu rezultatul
*sterg ( [ a | [ ] ] , [ [ a ] , [ b ] , [ c ] ] , [ [ b ] ] , [ c ] ] )

3. Cel de al doilea predicat sterg în prima fază detectează stiva pe care urmeaza
să fie amplasat blocul posibil de a fi mutat detectat de primul predicat sterg,
după care se efectuează stergerea stivei detectate în cea de a doua fază.
Vom avea
sterg ( _ , [ [ b ] , [ c ] , [ c ] ] , _ )
cu rezultatul
*sterg ( [ b ] , [ [ b ] , [ c ] ] , _ )
la a doua apelare a predicatului astfel construit
sterg ( [ b ] , [ [ b ] , [ c ] ] , _ )
se obţine
*sterg ( [ b ] , [ [ b ] , [ c ] ] , [ [ c ] ] )

109
Inteligenţă Artificială. Tehnici.

4. In urma execuţiei celor două apeluri ale predicatului sterg se obţin fragmente care
sunt recompuse de către predicatul succesor fiind în final obţinută structura
*sterg ( [ [ a ] , [ b ] , [ c ] ] , [ [ ] , [a | [b] ] | [[c]] ])
s( Nod, [ Stiva1, [V1 | Stiva2 ] | AlteStive ] )

şi deci obţinerea configuraţiei


[ [ ] , [ a ,b ] , [ c ] ]

Exercitiu
Pe planeta Marte există două partide politice rivale: Federaţia Marţiană şi Partidul
Progresist Marţian .În cursul unei campanii electorale, 3 membrii ai FM şi 3 membri ai
PPM trebuie să treacă râul cu o barcă cu 2 locuri. Presupunem că este suficient ca
membrii FM să fie majoritari într-un grup pentru a-i converti pe cei din PMM la ideile lor,
cum pot aceştia din urmă să treacă râul astfel încât să nu rişte să-şi schimbe partidul ?

12.2. Alternative reprezentabile prin obiecte compuse PROLOG


In acest caz o alternativa este definita printr-un obiect compus, iar secventa de
alternative care specifica drumul dintre o stare inițială și una finala este data de o lista
cu elemente de tip obiecte compuse.

Problema barcagiului: Un barcagiu dorește să treacă un lup, o capra și o varza de pe


malul stâng a unui râu pe malul drept, cu ajutorul unei bărci care poate transporta o
data numai doi pasageri ( sau nici unul). Lupul și capra nu pot rămâne împreună singuri
nesupravegheați, la fel capra și varza.

110
Inteligenţă Artificială. Tehnici.

Instanţele care caracterizează o alternativa (configurație) pentru aceasta


problema pot fi definite după cum urmează:
 Configurația : este în acest caz o un obiect compus prin care se reprezintă
configurația unei instanțe. Convenim să codificam configurația – vezi figura
următoare – care conduce la o structura de date de forma :

domains
drum = nod*
element = lup; varza; capra; alone
stare = element*
mal = stinga;dreapta
nod = lvc(mal, stare, stare)

Se observa faptul ca se reprezintă explicit configurația de elemente care


urmează a fi operate, utilizându-se o combinație de elemente singulare și structurate în
liste care sunt incorporate intr-un obiect compus care definește configurația ( o stare în
cadrul spațiului alternativelor posibile)
Utilizarea acestui mod de reprezentare permite o structurare a procedurii
succesor de forma:
s(Stare1,Stare2) :-
move(Stare1,Stare2),
update(Stare1,Move,Stare2),
legal(Stare2).

111
Inteligenţă Artificială. Tehnici.

unde vom avea explicit prezente urmatoarele proceduri:


 move(Stare1,Move) prin intermediul căreia se propune plecând de la o
configurația curenta Stare1 o configurația următoare care poate fi obținuta
efectuând o mutare data de Move, în conformitate cu regulile impuse de
problema de rezolvat
 update(Stare1,Move,Stare2) asigura actualizarea configurației curente și
transformarea acesteia intr-o configurație următoare data de Stare2.
 legal(Stare2) implementează restricțiile cerute de problema la tranzitarea dintr-o
configurație în alta configurație
 fiecare din cele trei proceduri principale care în ultima instanță implementează o
tehnica de tip genereaza și testeaza pot conține la rândul lor alte proceduri cu
rol de explicitare a acțiunilor respective. Pentru cazul în discuție vom avea
urmatoarele proceduri:
- update_boat(mal, mal) cu rolul de a stabili poziția bărcii;
- update_bank (
incarcatura barca,
pozitie barca,
configuratie initiala mal stang, respectiv drept,
configuratie urmatoare mal stang, respectiv drept
)
cu rolul de a actualiza cele doua maluri după efectuarea transportului
- select(
selectare incarcatura barca,
configuratie mal de unde se încarcă barca
noua configuratie a malului de unde au urcat pasagerii în barca
)
cu rolul de a stabili încărcarea bărcii funcție de malul pe care se găsește aceasta.
Procedura este obligatoriu să fie recursiva, deoarece este posibil ca un pasager să
fie refuzat, caz în care trebuie selectat altul ( prin backtracking se va trece la o noua
încercare pentru un alt pasager)
- insert(

112
Inteligenţă Artificială. Tehnici.

eliberare încărcătura barca,


configuratie mal initiala unde coboară pasagerii din barca,
noua configuratie a malului unde au coborât pasagerii din barca
)
cu rolul de a actualiza malul unde urmează să coboare pasagerii. Procedura va
trebui să amplaseze pasagerul în nici un caz pe prima pozitie a celor care sunt
prezenți pe un mal, deoarece poate apare șansa ca tot el să fie trecut înapoi, ceea
ce poate conduce la un ciclu infinit.

In contextul unei strategii de căutare în adâncime problema apare de forma:

domains
drum =nod* element=lup;varza;capra;alone
stare=element* mal=stinga;dreapta
nod=lvc(mal,stare,stare)

predicates
rezolva(nod,drum) caut_a(drum,nod,drum)
s(nod,nod) move(nod,element)
update(nod,element,nod) update_boat(mal,mal)
select(element,stare,stare) apartine(element,stare)
apartine(nod,drum) legal(nod)
ilegal(stare) insert(element,stare,stare)
update_banks(element,mal,stare,stare,stare,stare) tip(drum)

clauses
rezolva(Nod,Solutie) :-
caut_a([ ],Nod,Solutie).

caut_a(Drum,Nod,[Nod|Drum]) :-
Nod is lvc(dreapta,[ ],[lup,capra,varza]).

caut_a(Drum,Nod,Sol) :-
s(Nod,
Nod1),
not(apartine(Nod1,Drum)),
caut_a([Nod|Drum],Nod1,Sol).

s(Stare1,Stare2) :-
move(Stare1,Move),
update(Stare1,Move,Stare2),

113
Inteligenţă Artificială. Tehnici.

legal(Stare2).

move(lvc(stinga,S,_),Cargo) :-
apartine(Cargo,S).
move(lvc(dreapta,_,D),Cargo) :-
apartine(Cargo,D).
move(_,alone).

update(lvc(B,S,D),Cargo,lvc(B1,S1,D1)) :-
update_boat(B,B1),update_banks(Cargo,B,S,D,S1,D1).

update_boat(stinga,dreapta).
update_boat(dreapta,stinga).

update_banks(alone,_,S,D,S,D).
update_banks(Cargo,stinga,S,D,S1,D1) :-
select(Cargo,S,S1),insert(Cargo,D,D1).
update_banks(Cargo,dreapta,S,D,S1,D1) :-
select(Cargo,D,D1),insert(Cargo,S,S1).

select(X,[X|Ys],Ys).
select(X,[Y|Ys],[Y|Zs]) :-
select(X,Ys,Zs).
select(X,[X],[ ]).

insert(X,[ ],[X]).
insert(X,[Y|R],[Y,X|R]).

legal(lvc(stinga, _ , D)) :- not(ilegal(D)).


legal(lvc(dreapta, S, _)) :- not(ilegal(S)).

ilegal(L) :- apartine(lup,L),apartine(capra,L).
ilegal(L) :- apartine(capra,L),apartine(varza,L).

apartine(X, [X | _ ] ).
apartine(X, [ _ | R]) :-
apartine(X,R).

tip([ ]).
tip([ X | R]) :- write(X),nl,readchar( _ ),tip(R).

goal
clearwindow,rezolva(lvc(stinga,[lup,capra,varza],[ ]),R),
tip(R).

114
Inteligenţă Artificială. Tehnici.

Problema mutării unei stive de cuburi: Se cere definirea planului de mișcări care
conduce de la o configuratie data de 3 cuburi la o configuratie ținta.

Instanţele care caracterizează o alternativa (configuratie) pentru aceasta


problema pot fi definite după cum urmează:
 Configurația : este în acest caz o un obiect compus prin care se reprezintă
relațiile intre obiecte. Convenim să codificam relația intre blocuri printr-un obiect
de forma:
on(X, Y )
in care X este un bloc, iar Y este fie un bloc, fie un loc de amplasare. De exemplu
pentru configurația de mai jos avem următoarea reprezentare

 Reprezentând o configurație prin intermediul relațiilor care apar intre elementele


componente apare posibilitatea simplificării definirii posibilităților de mișcare și
reprezentare a restricțiilor impuse de aceasta operație ( de exemplu un bloc nu
poate fi mișcat deoarece deasupra să se găsește un alt bloc). în acest context
apar urmatoarele aspecte:
 Pentru a verifica daca un bloc poate să fie mișcat sau nu putem utiliza un
predicat de forma:
not (apartine( on( _ ,X), Configuratie))
De exemplu presupunem ca avem configurația:

115
Inteligenţă Artificială. Tehnici.

Deoarece on( _ , b) apartine configurației [ on(a,b), on(b,p), on(c,q) ] rezulta ca blocul b


nu poate fi mișcat
 Pentru a verifica daca un loc este sau nu liber utilizând aceeași modalitate de
verificare voi avea
not(apartine( on( _ , p), [ on(a,b), on(b,p), on(c,q) ])
mă va conduce la concluzia ca locul p este ocupat
 Principiul general de mișcare a blocurilor este următorul:
atâta timp cat exista un loc liber se muta unul din blocuri pe locul liber
existent, daca nu mai exista nici un loc liber se procedează la amplasarea unui
bloc peste un alt bloc pana când nu mai exista posibilitatea de a mai pune alte
blocuri.
Pentru a delimita cele doua moduri de lucru se utilizează doua obiecte
compuse corespunzătoare celor doua alternative de mutare
- to_place( bloc, suport, loc_disponibil) structura care reprezintă una din cele doua
tipuri de situații care pot apare, prezente în cele doua figuri de mai jos

116
Inteligenţă Artificială. Tehnici.

- to_block( bloc1, suport, loc_bloc2) structura care reprezintă una din cele doua
tipuri de situații care pot apare, prezente în cele doua figuri de mai jos

 Utilizarea acestui mod de reprezentare permite o structurare a procedurii


succesor de forma:
s(Stare1,Stare2) :-
legal_action(Action,Stare1),
update(Action,Stare1,Stare2).
Unde:
- legal_action(Action,Stare1), propune o mutare definite de Action (procedura
incorporează inclusiv verificarea daca mutarea este posibila de efectuat )
plecând de la o configuratie curenta Stare1. Se observa în acest caz ca tehnica
de tip genereaza și testeaza este implementata de un singur predicat spre
deosebire de exemplul discutat anterior. Acest lucru este posibil datorita modului
de descriere prin relații între elemente a configurațiilor cat și a implementării
procedurilor de căutare a unui bloc și loc liber pe care acesta poate fi mutat.
- update(Action,Stare1,Stare2), are rolul de a actualiza configurația curenta data
de Stare1 prin efectuarea unei mutări de bloc specificata de Action, cu urmarea
obținerii unei noi configurații definite de Stare2. Este de remarcat faptul ca
update prezintă doua forme datorate faptului ca suportul pe care se amplasează
blocul poate fi un alt bloc sau un loc liber. Cele doua aspecte sunt evidențiate
prin variantele:
update(to_place( bloc, suport, loc_disponibil) Stare1,Stare2)

117
Inteligenţă Artificială. Tehnici.

update(to_block(bloc1, suport, loc_bloc2,) Stare1,Stare2)

 Complementar acestor structuri de date și proceduri de mai utilizează


următoarele proceduri:
- clear( bloc / support, Stare)cu rolul de a:
1. determina daca pot atribui rolul de suport unui bloc sau unui loc.
2. elibera un suport (indiferent daca este un bloc sau un loc) de blocul
prezent pe acesta.
3. substitute (on(X,Y),on(X,Z),State,State1) având rolul de a modifica
configurația curenta State cu relațiile noi găsite on(X,Y),on(X,Z)
pentru a obține o noua configuratie State1
- block(bloc) și place(lsuport) cu rolul de a defini prin axiome blocuri și locurile de
amplasare a acestora
In contextul unei strategii de căutare în adâncime problema apare de forma:

domains
pozitie = on(symbol,symbol) stare = pozitie*
mut = to_place(symbol,symbol,symbol);
to_block(symbol,symbol,symbol)

predicates
s(stare,stare) legal_action(mut,stare)
clear(symbol,stare) update(mut,stare,stare)
member(pozitie,stare) substitute(pozitie,pozitie,stare,stare)
on(symbol,symbol,stare) place(symbol)
block(symbol)

clauses
s(Stare1,Stare2) :-
legal_action(Action,Stare1),
update(Action,Stare1,Stare2).

legal_action(to_place(Block,Y,Place),State) :-
on(Block,Y,State),clear(Block,State),
place(Place),clear(Place,State).

legal_action(to_block(Block1,Y,Block2),State) :-
on(Block1,Y,State), clear(Block1,State),
block(Block2), Block1 <> Block2,
clear(Block2,State).
118
Inteligenţă Artificială. Tehnici.

clear(X,State) :- not(member(on(_,X),State)).
on(X,Y,State) :- member(on(X,Y),State).

update(to_block(X,Y,Z),State,State1) :-
substitute(on(X,Y),on(X,Z),State,State1).

update(to_place(X,Y,Z),State,State1) :-
substitute(on(X,Y),on(X,Z),State,State1).

substitute(on(X,Y),on(X,Z),[on(X,Y)|R],[on(X,Z)|R]).
substitute(on(X,Y),on(X,Z),[W|R],[W|R1]) :-
substitute(on(X,Y),on(X,Z),R,R1).

member(X,[X|_]).
member(X,[_|R]) :- member(X,R),!.

Block(a). Block(b). Block(c).


Place(p). Place(q). Place(r).

goal
s( [on(a,p), on(b,q), on(c,r) ],R), write(R).

12.3. Concluzii
Plecând de la tehnicile de construire a succesorilor prezentate anterior pot fi de
desprinse câteva aspecte:
1. Reprezentarea prin obiecte standard prolog în care se codifica în general
numeric și pozițional instanţele, este simpla și nu consuma resurse. Prezintă
însă marele dezavantaj ca interpretarea unei instanţe este dificila, deoarece
este necesara interpretarea valorilor și a pozițiilor acestora, aspect care
complica depanarea unei proceduri de tip succesor. Pentru acest tip de
reprezentare, este obligatorie prezenta unui interpretor de instanţe care să fie
utilizat după găsirea secvenței de instanţe care face trecerea de la o poziție
inițială la una finala. Un alt aspect, care poate constitui un dezavantaj se
refera la faptul ca nu apar explicit etapele corespunzătoare unei tehnici de tip
generează și testează, aspect care reprezintă un impediment, dar și un
avantaj deoarece procedurile în care cele doua aspecte se întrepătrund sunt
mult mai rapide decât cele în care cele în care generarea și testarea sunt
definite explicit. Acesta caracteristica este importanta, deoarece spațiul
119
Inteligenţă Artificială. Tehnici.

alternativelor posibile este considerabil pentru problemele din lumea reala. în


generala acest mod de reprezentare poate utiliza tehnici standard de căutare
în spațial stărilor, de obicei fiind folosit și un contor de limitare a adâncimii de
căutare.
2. Reprezentarea prin obiecte compuse prolog prin care o instanță se reprezintă
printr-un articol (obiect compus) în care diversele câmpuri (de tip intreg,
symbol, liste sau obiecte compuse) descrie mai exact structura unei
configurații la un moment dat. Prezintă avantajul ca este mult mai explicita,
fapt care face ca punerea la punct a procedurii succesor să fie considerabil
mai simpla decât în cazul reprezentării prin obiecte standard. Acest mod de
descriere face inutila prezenta unui interpretor pentru analiza secvenței de
configurații găsită intre o instanță inițială și una țintă. Este de remarcat faptul
ca acest avantaj este obținut în detrimentul unui consum mult mai mare de
resurse (atât memorie cat sit timp), fapt care face ca reprezentarea de acest
tip să se preteze pentru căutări euristice care se desfășoară pe direcții
privilegiate. Este de asemenea de remarcat faptul ca procedura successor
este mult mai bine structurata, apărând explicit componentele unei tehnici de
tip generează și testează.

120
Strategii de căutare
Neinformate
O ”problemă” constă din
• O stare inițială, q(0)
• O listă posibilă de acțiuni, a,
• O stare țintă (pot fi prezente mai multe stări
ținte)

Rezolvarea constă în găsirea unui drum de forma


q(0) → q(1) → q(2) → ... → q(N)
în care q(N) este o stare țintă.
Spaţiul stărilor în problemele de tip
IA - combinatoriale
Exemplu: 8-puzzle
• Stare: Orice configurație de 8
piese plasată în cele 9 locații
ale tablei.
• Stare inițială: Orice stare.
• Funcție Succesor (acțiuni):
Poziția liberă mută Stânga,
Dreapta, Sus sau Jos.
• Test verificare atingere stare
2 8 3 1 2 3 țintă: Se verifică dacă se
atinge starea țintă.
1 6 4 8 4

7 5 7 6 5

Start State Goal State


Exemplu: 8-puzzle
• Stare: Configurația de 8 piese
în 9 poziții posibile ( poziția
spațiu este pătratul liber rămas
).
• Initial state: Any state.
Exemple:
• Successor function
(actions): Blank moves Left,
q = Right,
{7, 2, 4,Up,
5, 0,
or6,Down.
8, 3, 1}

2 8 3 1 2 3 • = Goal
q test:
{2, 8, 3, 1, 6,Check
4, 7, 0,whether
5} the
goal state has been reached.
1 6 4 8 4 • Path cost: Each move costs 1.
The path cost = the number of
7 5 7 6 5 moves.
Start State Goal State
Exemplu: 8-puzzle
• State: Specification of each of
the eight tiles in the nine
squares (the blank is in the
remaining square).
• Initial state: Any state.
• Funcție Succesor (acțiuni):
Poziția liberă mută mută
Stânga, Dreapta, Sus sau Jos.
2 8 3 1 2 3 • Goal test: Check whether the
goal state has been reached.
1 6 4 8 4 • Path cost: Each move costs 1.
The path cost = the number of
7 5 7 6 5 moves.
Start State Goal State
Expandare 8-puzzle
2 8 3
q = {2, 8, 3, 1, 6, 4, 7, 0, 5}
1 6 4

7 5

Spațiul mută stânga Spațiul mută dreapta

Spațiul mută sus

2 8 3 2 8 3 2 8 3

1 6 4 1 4 1 6 4

7 5 7 6 5 7 5

q = {2, 8, 3, 1, 6, 4, 0, 7, 5} q = {2, 8, 3, 1, 6, 4, 7, 5, 0}
q = {2, 8, 3, 1, 0, 4, 7, 6, 5}
Strategii de căutare
Neinformate
Strategiile de căutare de bază fără a se cunoaște direcția
de avans în spațiul stărilor sunt.

– căutare în lăţime a alternativelor posibile (Breadth-first search)


– căutare în adâncime, (Depth-first search)
Breadth-first search

Image from Russel & Norvig, AIMA, 2003


Image from N. J. Nilsson, Artificial Intelligence – A New Synthesis, 1998
Depth-first
Image from Russel & Norvig, AIMA, 2003
Image from N. J. Nilsson, Artificial Intelligence – A New Synthesis, 1998

Depth-first adâncimea de
căutare 5
Exemplu :
Problema misionarilor şi
canibalilor
Problema misionarilor şi canibalilor: 3 misionari şi 3 canibali se află la marginea unui râu cu scopul de
a trece pe celălalt mal. Ei au la dispoziţie o barcă de două persoane. Dacă la un moment dat,
pe un mal sau pe celălalt numărul canibalilor întrece pe cel al misionarilor, misionarii sunt în
pericol de a fi mâncați de canibali. Problema constă în a afla cum pot trece râul cele 6 persoane
în deplină siguranţă.
Strategia de căutare
Breadth-first
Misionari & Canibali 

Stările sunt generate aplicând


conținutul bărcii pe configurația
celor două maluri:
ocup_barca(
[1,0], [0,1], [1,1], [2,0], [0,2]
)

Stări roșii= misionari sunt mâncați


Stări galbene= stări care se repetă
Strategia de căutare
Breadth-first
Misionari & Canibali 

Stările sunt generate aplicând


conținutul bărcii pe configurația
celor două maluri:
ocup_barca(
[1,0], [0,1], [1,1], [2,0], [0,2]
)

Stări roșii= misionari sunt mâncați


Stări galbene= stări care se repetă
Strategia de căutare
Breadth-first
Misionari & Canibali 

Stările sunt generate aplicând


conținutul bărcii pe configurația
celor două maluri:
ocup_barca(
[1,0], [0,1], [1,1], [2,0], [0,2]
)

Stări roșii= misionari sunt mâncați


Stări galbene= stări care se repetă
Strategia de căutare
Breadth-first
Misionari & Canibali 

Stările sunt generate aplicând


conținutul bărcii pe configurația
celor două maluri:
ocup_barca(
[1,0], [0,1], [1,1], [2,0], [0,2]
)

Stări roșii= misionari sunt mâncați


Stări galbene= stări care se repetă
Strategia de căutare
Breadth-first
Misionari & Canibali 

Stările sunt generate aplicând


conținutul bărcii pe configurația
celor două maluri:
ocup_barca(
[1,0], [0,1], [1,1], [2,0], [0,2]
)

Stări roșii= misionari sunt mâncați


Stări galbene= stări care se repetă
Strategia de căutare
Breadth-first
Misionari & Canibali 

Stările sunt generate aplicând


conținutul bărcii pe configurația
celor două maluri:
ocup_barca(
[1,0], [0,1], [1,1], [2,0], [0,2]
)

Stări roșii= misionari sunt mâncați


Stări galbene= stări care se repetă
Strategia de căutare
Breadth-first
Misionari & Canibali 

Stările sunt generate aplicând


conținutul bărcii pe configurația
celor două maluri:
ocup_barca(
[1,0], [0,1], [1,1], [2,0], [0,2]
)

Stări roșii= misionari sunt mâncați


Stări galbene= stări care se repetă
Strategia de căutare
Breadth-first
Misionari & Canibali 

Stările sunt generate aplicând


conținutul bărcii pe configurația
celor două maluri:
ocup_barca(
[1,0], [0,1], [1,1], [2,0], [0,2]
)

Stări roșii= misionari sunt mâncați


Stări galbene= stări care se repetă
Strategia de căutare
Breadth-first
Misionari & Canibali 
-(0,2,1) [2 canibali trec de la L → R]
+(0,1,1) [1 canibal trece de la R → L]
-(0,2,1) [2 canibali trec de la L → R]
+(0,1,1) [1 canibal trece de la R → L]
-(2,0,1) [2 misionari trec de la L → R]
+(1,1,1) [1 canibal & 1 misionar
trece de la R → L]
-(2,0,1) [2 misionari trec de la L → R]
+(0,1,1) [1 canibal trece de la R → L]
-(0,2,1) [ 2 canibali trec de la L → R]
+(1,0,1) [1 misionar trece de la R → L]
-(1,1,1) [1 canibal & 1 misionar
trece de la L → R]
Strategia
Breadth-first

Misionari & Canibali
Sunt generate 48 noduri

Strategia
Depth-first
Misionari & Canibali
Sunt generate 30 noduri
Strategii de căutare informate
Utilizarea de cunoștințe în
strategiile de căutare.
◼ Fără a dispune de informații
Căutare
în operația de căutare suntem
siliți să căutăm la întâmplare. oriunde!!

◼ În consecință complexitatea
care o implică căutarea
neinformată (timp, spațiu)
este greu de acceptat.

2
Utilizarea de cunoștințe în
strategiile de căutare.
◼ Conduce la o creștere dramatică a eficienței vitezei strategiei
de căutare.

Se caută B C D E
numai în F G H I J
acest
subtree! K L M N

3
De ce funcționează euristica?
◼ În orice problemă de cătare unde există mai mult de b
alegeri în fiecare nod și este prezentă o adâncime de
căutare d la nodul țintă, o strategie care caută la
întâmplare , va trebui în cel mai defavorabil caz să
parcurgă aproape O(bd) noduri înainte de găsirea unei
soluții (Complexitatea de Timp este exponențială).

◼ Utilizarea euristiicii îmbunătățește eficiența strategiei de


căutare prin reducerea factorului de ramificare de la b la
o valoare mult mai mică b* (ideal 1)
1 =< b* << b
4
Funcții Euristice
◼ O funcție euristică este o funcție f(n) care dă o estimare a costului
drumului de la nodul n la starea țintă – ca urmare se va selecta acel nod
care conduce la cel mai mic cost. Acest nod se va utiliza pentru
expandare.

◼ Caracteristici f:
◼ este o măsură a cât de promițătoare este starea curentă definită de nodul n.

◼ f este o estimare a costului atingerii stării țintă din starea curentă:


◼ f(n) = h(n) unde h(n) = o estimare a costului de la n la țintă

◼ f estimează costul atingerii stării țintă din starea curentă și costul drumului
până la acesta. În acest caz f va avea două componente:
◼ f(n) = g(n) + h(n) unde g(n) = costul până la n (din starea inițială)

5
Caracteristicile funcției euristice f(n) văzută
co o măsură a cât de promițătoare este
starea curentă definită de nodul n.

◼ O funcție euristică f(n) = g(n) + h(n) este admisibilă dacă h(n) nu


suprestimează niciodată costul atingerii țintei, chiar dacă, g(n) este
costul exact al atingerii nodului n din starea inițială.

◼ Cu alte cuvinte, f(n) nu va supraestima costul real al atingerii stării


țintă prin starea definită de nodul n.

◼ O strategie este optimă (reurnează o soluție optimă) dacă h(n) este


admisibilă.

6
Strategii de căutare informate

◼ Greedy Best first search


◼ “Întodeauna se alege succesorul nodului cu cea mai bună f
valoare” unde f(n) = h(n)
◼ Se va obține o stare care este apropiată de starea finală
optimă.

◼ A* search
◼ Ia în calcul o funcție euristică f care ia în considerare și
costul curent g
◼ Întotdeuna returnează cea mai optimă soluție (drumul este
optim) 7
Strategii de căutare informate
Măsuri cantitative şi calitative pentru estimarea eficienţei unei
strategii de căutare.

Măsurile cantitative sunt aprecieri pur cantitative. Notația utilizată este


O(Complexitate)
◼ Complexitatea de Timp a strategiei - în cât timp (măsurat ca număr
de paşi ai algoritmului) este găsită soluţia.
◼ Complexitatea de Spaţiu a strategiei – de cât spaţiu (este vorba de
memorie) este nevoie pentru găsirea soluţiei.

Măsuri calitative:
◼ Completitudine – o strategie se numeşte completă dacă garantează
găsirea unei soluţii.
◼ Optimalitate – o strategie se numeşte optimală dacă garantează
găsirea celei mai bune soluţii din punctul de vedere al costului căii
între starea iniţială şi starea finală.
8
Strategii de căutare informate

Greedy Search
eval-fn: f(n) = h(n)
Greedy Search
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
Goal f(n) = h (n) = euristica este dată de distanța în
linie dreptă dintre Start și o Stare
10
Greedy Search
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
Goal f(n) = h (n) = euristica este dată de distanța în
linie dreptă dintre Start și o Stare
11
Greedy Search
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
Goal f(n) = h (n) = euristica este dată de distanța în
linie dreptă dintre Start și o Stare
12
Greedy Search
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
Goal f(n) = h (n) = euristica este dată de distanța în
linie dreptă dintre Start și o Stare
13
Greedy Search
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
Goal f(n) = h (n) = euristica este dată de distanța în
linie dreptă dintre Start și o Stare
14
Greedy Search
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
Goal f(n) = h (n) = euristica este dată de distanța în
linie dreptă dintre Start și o Stare
15
Greedy Search
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
Goal f(n) = h (n) = euristica este dată de distanța în
linie dreptă dintre Start și o Stare
16
Greedy Search
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
Goal f(n) = h (n) = euristica este dată de distanța în
linie dreptă dintre Start și o Stare
17
Greedy Search
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
Goal f(n) = h (n) = euristica este dată de distanța în
linie dreptă dintre Start și o Stare
18
Greedy Search
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
Goal f(n) = h (n) = euristica este dată de distanța în
linie dreptă dintre Start și o Stare
19
Greedy Search: Tree Search
Start
A

20
Greedy Search: Tree Search
Start
A 75
118

[329] 140 [374] B


C

[253] E

21
Greedy Search: Tree Search
Start
A 75
118

[329] 140 [374] B


C

[253] E
80 99

[193] [178]
G F
[366] A

22
Greedy Search: Tree Search
Start
A 75
118

[329] 140 [374] B


C

[253] E
80 99

[193] [178]
G F
[366] A
211

[253] E I [0]

Goal

23
Greedy Search: Tree Search
Start
A 75
118

[329] 140 [374] B


C

[253] E
80 99

[193] [178]
G F
[366] A
211

[253] E I [0]

Goal
Costul drumului(A-E-F-I) = 253 + 178 + 0 = 431
24
Distanța(A-E-F-I) = 140 + 99 + 211 = 450
Greedy Search: Optim ?
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
f(n) = h (n) = euristica este dată de distanța în linie dreptă
Goal
dist(A-E-G-H-I) =140+80+97+101=418 25
Greedy Search: Complet ?
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 ** C 250
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I
Goal f(n) = h (n) = euristica este dată de distanța în
linie dreptă
26
Greedy Search: Tree Search
Start
A

27
Greedy Search: Tree Search
Start
A 75
118

[250] 140 [374] B


C

[253] E

28
Greedy Search: Tree Search
Start
A 75
118

[250] 140 [374] B


C

[253] E
111
[244] D

29
Greedy Search: Tree Search
Start
A 75
118

[250] 140 [374] B


C

[253] E
111
[244] D

Infinite Branch !
[250] C

30
Greedy Search: Tree Search
Start
A 75
118

[250] 140 [374] B


C

[253] E
111
[244] D

Infinite Branch !
[250] C

[244] D

31
Greedy Search: Tree Search
Start
A 75
118

[250] 140 [374] B


C

[253] E
111
[244] D

Infinite Branch !
[250] C

[244] D

32
Greedy Search: Complexitatea
de Timp și Spațiu?
Start
118
A 75 • Greedy search NU este optim.
C 140 B • Greedy search este incomplet fără
111 o verificare a stărilor care se repetă.
E
D 80 99 • În cel mai rău caz, Complexitatea
de timp și spațiu pentru Greedy
G F
Search este de O(bm)
97
Unde b este factorul de ramificare și
H 211 m lungimea maximă a drumului găsit
101
I
Goal
33
Greedy Search
Concluzii

Greedy Search minimizează o euristică h(n) care este


costul estimat de la un nod n la nodul țintă. Greedy Search
este eficient dar nu este optim și nici complet.

34
Strategii de căutare informate

A* Search
eval-fn: f(n)=g(n)+h(n)
A* (A Star)
◼ A* utilizează o funcție euristică care
combină g(n) și h(n): f(n) = g(n) + h(n)

◼ g(n) reprezintă costul exact al drumului de


la nodul start la nodul n.

◼ h(n) reprezintă o estimare a drumului rămas


de la nodul n până la nodul țintă.
36
A* (A Star)

g(n)

f(n) = g(n)+h(n) n

h(n)

37
A* Search
Start Stare Euristica: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 98
101 I 0
I f(n) = g(n) + h (n)
Goal
g(n): este exact costul drumului de la nodul Start la nodul Țintă.
38
A* Search: Tree Search
A Start

39
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C

40
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[413] G F [417]

41
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[413] G F [417]

97
[415] H

42
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[413] G F [417]

97
[415] H

101
Goal I [418]

43
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[413] G F [417]

97
[415] H I [450]

101
Goal I [418]

44
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[413] G F [417]

97
[415] H I [450]

101
Goal I [418]

45
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[413] G F [417]

97
[415] H I [450]

101
Goal I [418]

46
A* Search: h nu este admisibilă !
Start State Heuristic: h(n)
A 75
118 A 366
140 B B 374
C
111 C 329
E
D 80 99 D 244
E 253
G F
F 178
97 G 193
H 211 H 138
101 I 0
Goal I f(n) = g(n) + h (n) – (H-I )Supraestimată
g(n): g(n) = costul până la n (din starea inițială). 47
A* Search: Tree Search
A Start

48
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C

49
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[413] G F [417]

50
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[413] G F [417]

97
[455] H

51
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[413] G F [417]

97
[455] H Goal I [450]

52
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[473] D [413] G F [417]

97
[455] H Goal I [450]

53
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[473] D [413] G F [417]

97
[455] H Goal I [450]

54
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[473] D [413] G F [417]

97
[455] H Goal I [450]

55
A* Search: Tree Search
A Start

118 75
140

E [393] B [449]
[447] C
80 99

[473] D [413] G F [417]

97
[455] H Goal I [450]

A* nu este optimă !!!


56
A* Search: Caracteristici
Start •A* este complet (găsește o soluție)
A 75
118 •A* este optim dacă euristica h este
140 B admisibilă.
C
111
E •Complexitatea de timp depinde de
D 80 99 calitatea euristicii, fiind încă
exponențială.
G F

97 •Pentru Complexitatea de spațiu, A*


păstrează toate nodurile în memorie.
H 211
A* are în cel mai defavorabil caz o
101
complexitate O(bd).
I
Goal
57
Strategii de căutare informate

Iterative Deepening A*
Iterative Deepening A*:IDA*

Fiecare iterație este depth-first cu tăierea


nodurilor expandate a căror valoare a
funcției euristice este mai mare decât
valoare de referință a funcției f prezentă
în iterația respectivă

59
IDA* Algorithm
◼ În prima iterație se determină “f-cost limit” – cut-off value
f(n0) = g(n0) + h(n0) = h(n0), unde n0 este nodul de start.

◼ Se expandează nodurile a căror funcție euristică f(n) nu depășește


valoare funcției de cost limită . Expandarea utilizează o strategie de
tip depth-first

◼ Daca căutarea nu are succes se determină cea mai mică valoare f(n)
a nodurilor care au fost vizitate dar nu au fost expandate.

◼ Se utilizează această valoare pentru noua limită de tip “f-cost limit”


– cut-off value și se reinițializează o altă căutare de tip dept-first.

◼ S repetă această procedură până în momentul găsirii nodului țintă. 60


f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

4
Cutoff=4

61
f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

4
Cutoff=4 4

6 6

62
f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

4
Cutoff=4 4 5

6 6

63
f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

4
Cutoff=4 4 5

6 6

64
f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

6 5

4
Cutoff=4 4 5

6 6

65
f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

4
Cutoff=5

66
f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

4
Cutoff=5 4

6 6

67
f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

4
Cutoff=5 4 5

6 6

68
f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

4
Cutoff=5 4 5

6 6

69
f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

4 5
Cutoff=5 4 5

6 6

70
f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

4 5 5
Cutoff=5 4 5

6 6

71
f(N) = g(N) + h(N)
8-Puzzle cu h(N) = număr piese incorect plasate

4 5 5
Cutoff=5 4 5

6 6

72
Când se utilizează tehnicile de
căutare euristice?

◼ Nu există alte modalități de căutare a


soluției sau

◼ Este dificil de dezvoltat tehnici de căutare


alternative a soluției

73
Inteligenţă Artificială. Tehnici.

13. Strategii de căutare informată - euristică a soluţiilor.

13.1 Căutare euristică. Caracteristici.

Euristic definiție

Termenul euristic (heuristic) era utilizat în limba greacă (heuriskein) precum şi


în limba latină (heuristicus) cu sensul de a căuta, a descoperi. Euristic sau euristica
sunt termeni utilizaţi în mod curent pentru a defini acel procedeu de luare a deciziei
(sau de găsire a unei soluţii) care nu analizează toată cantitatea de informaţie
disponibilă în acest sens.

Euristic principii

Metodele euristice “sar” peste anumite informaţii sau etape utilizate în mod
normal la luarea unei decizii sau găsirea unei soluţii. În anumite situaţii, o metodă
euristica poate duce la rezultate mult mai rapide şi mult precise decât metodele
clasice de analiză. Conform unor autori, scopul euristicii este acela de a studia
metodele şi regulile utilizate pentru descoperiri şi invenţii. Conform altor autori,
euristic, înseamnă o procedură foarte rapidă de rezolvare a unei probleme.

În cele ce urmează vom lua în considerare noțiunea de euristică așa cum este
definită de Judea Pearl “ Heuristics” 1984

Euristicile sunt criterii, metode sau principii utilizate pentru a decide care
dintre mai multe cursuri alternative de acțiune, promite să fie cel mai eficient, în
scopul de a atinge un anumit obiectiv.

Principiul de căutare:
O strategie de căutare euristică a soluţiilor, pleacă de la ideea că avansarea în
spaţiul configuraţiilor se face pe direcţii care promit atingerea configuraţiei dorite într-
un timp rezonabil, cu un număr acceptabil de stări intermediare. Strategia este o
strategie tentativă (este una şovăitoare): o mişcare ce se dovedeşte greşită poate fi
îndreptată. Mişcarea în spaţiul stărilor nu este inexorabilă. Dacă s-a ajuns într-un
punct mort pot să "iau urma îndărăt" pentru a face o altă mişcare dintr-o poziţie

121
Inteligenţă Artificială. Tehnici.

anterioară celei curente, în care am mai fost. Sensul de deplasare, (asigurat de


evaluarea estimatorului euristic care încorporează gradul de cunoaştere a soluţiei
problemei) este de tip cunoaştere globală ( găsirea drumului într-un labirint privit
dintr-un balon) faţă de cunoaştere locală (labirintul privit de un om aflat în el). Un
sistem de IA care lucrează cu o strategie tentativă are o cunoaştere locală a
problemei, el aplicând o manieră generală de comportament în toate situaţiile
similare.

Algoritmii euristici aferenți strategiilor de căutare, sunt algoritmi care lucrează


pe grafuri care se construiesc pe măsură ce spațiul stărilor se dezvoltă și care
folosesc o informație suplimentara, neconținuta în definirea problemei, prin care se
accelerează procesul de găsirea a unei soluții.

In cadrul explorării stărilor fiecare algoritm generează un arbore, care în


rădăcina va conține starea inițială. Fiecare nod al arborelui va conține următoarele
informații:

 Starea conținută - stare(nod)

 Părintele nodului – π(nod)

 Cost cale – costul drumului de la starea inițiala pana la nod – g(nod)

De asemenea, pentru fiecare nod definim și o funcție de evaluare

f (n)=g(n)+h(n)

care indica cat de promițător este un nod în perspectiva găsirii unui drum către
soluție.

Am menționat mai sus ca algoritmii de căutare euristica utilizează o


informative suplimentara referitoare la găsirea soluției problemei. Aceasta informație
este reprezentata de o funcție h(nod) care specifică cât de promițător este drumul
estimat, de la nod la cea mai apropiata nod soluție.

Întrucât funcționează prin alegerea, la fiecare pas, a nodului pentru care


f(nod) este cel mai promițător, algoritmii euristici de căutare sunt cunoscuți sub
denumire de Best-First (nodul cel mai promițător este explorat mereu primul).
122
Inteligenţă Artificială. Tehnici.

Presupunem ca am definit o funcţie de costuri pentru arcurile din spaţiul de


reprezentare a problemei.
Notam cu:
 c(n,n’) costul deplasării din nodul n în nodul succesor n’.
 f(n) funcţie care estimează cât de promiţător este nodul n. Rezultă
imediat că cea mai promiţătoare configuraţie n’ care poate fi obţinută
plecând din n, este aceea care minimizează funcţia f(n). Funcţia f(n) va
trebui astfel construita încât să estimeze costul căii ce reprezintă cea mai
buna soluţie, pornind de la nodul de Start pana la un nod soluţie, cu
constrângerea ca nodul n să aparţină căii în discuţie. să presupunem ca
exista o astfel de cale și ca un nod soluţie care minimizează costul există.
Atunci estimarea f(n) poate fi construita ca o suma de termini (vezi figura
următoare) de forma:
f(n) = g(n)+h(n)
unde:
- g(n) reprezintă costul unei cai optime de la Start (s) la Ţinta (t),
- h(n) este o estimare a unei cai optime de la n la t.

Când un nod n este întâlnit în procesul de căutare avem următoarea situaţie:


- o cale de la s la n trebuie să fi fost deja găsita;
- costul trebuie să fie calculat ca suma costurilor arcurilor ce aparţin caii.
Aceasta cale nu este neapărat calea optima de la s la n ( ar putea exista

123
Inteligenţă Artificială. Tehnici.

o cale mai buna încă nedescoperita), dar costul sau poate servi ca o
estimare g(n) a costului minim de la s la n.
 Celălalt termen h(n), este cel mai problematic, pentru ca spaţiul de la n la
t nu a fost explorat pana în acel moment. De aceea h(n) reprezintă o
adevărată presupunere euristică, bazata pe cunoştinţele generale despre
problema respectiva și a tehnicilor utilizate în cadrul acesteia. Cum h
depinde de domeniul problemei nu exista o metodă universală de
construire a acestuia.

Procesul de căutare în care se utilizează o strategie de alegere a celei mai


promiţătoare configuraţii care se poate genera din configuraţia curentă e compus
dintr-un set de sub procese concurente, fiecare dintre acestea explorând propriul
SubArbore de alternative. La un moment dat, numai unul din aceste procese este
activ, cel care tratează alternativa cea mai promiţătoare (cea mai mică / mare
valoare a lui f(n)). Celelalte procese trebuie să aştepte până când estimarea curentă
se modifică şi altă alternativă devine mai promiţătoare. Procesul de activare-
dezactivare al alternativei poate fi imaginat astfel:
Procesului care lucrează cu alternativa cu cea mai mare prioritate i se alocă
un anumit buget, procesul rămânând activ până la epuizarea acestui buget. În timpul
acestei activităţi procesul continuă expandarea arborelui său şi dă o soluţie dacă se
atinge ţinta.
Bugetul pentru proces este definit de estimarea euristică a celei mai apropiate
alternative. De exemplu dându-se o hartă se pune problema găsirii celei mai scurte
rute intre S şi T. Harta prezintă aspectul:

124
Inteligenţă Artificială. Tehnici.

Observaţii: Pe hartă sunt trecute distanţele dintre localităţi. Valorile din pătrate
reprezintă distanţele în linie dreaptă până la oraşul T. Ordinea în care este explorată
harta este următoarea. Linia punctata arată ordinea în care nodurile sunt expandate,
nu ordinea în care au fost generate. Acest aspect apare în următoarea figură de mai
jos.
Pentru estimarea costului distantei ramase de la nodul X pana la nodul soluţie
vom folosi pur și simplu distanta în linie dreapta dintre X și t data de dist(X,t) astfel
că:
f(X) = g(X)+h(X) = g(X)+dist(X,t)

În acest exemplu ne putem imagina căutarea euristică ca fiind definită de 2


procese, fiecare corespunzând celor 2 căi alternative de atingere a ţintei,
 procesul 1 prin a,
 procesul 2 prin e.
In primele etape, Procesul 1 este mai activ pentru că valoarea lui f de-a lungul căii
este mai mică decât valoarea furnizată de procesul 2, situaţia schimbându-se în
momentul în care se ajunge în e în care este activat procesul 2. Operaţia de
basculare continuă până la atingerea ţintei.

125
Inteligenţă Artificială. Tehnici.

In concluzie

căutarea euristică alege o direcţie de căutare în funcţie de valoarea unui estimator


definit de o funcţie f(n). La calculul acesteia se ţine cont de istoricul drumului parcurs
până în acel punct definit de termenul g(n) şi de cât de promiţătoare este direcţia de
urmat (această alegere se face prin intermediul unui estimator euristic care este
caracteristic pentru fiecare problema în parte) definit de termenul h(n)

Vom discuta în continuare două strategii de căutare euristică. Vom folosi pentru
exemplificare, următoarea problema: data fiind o harta rutiera a României, sa se
găsească o cale (de preferința de cost minim) între Arad și București. Pentru aceasta
problema:
 starea inițiala indica ca ne aflam în orașul Arad,
 starea finala este data de București,
 funcția succesor va furniza toate orașele în care putem ajunge dintr-un oraș
dat, iar funcția de cost indica numărul de km al fiecărui drum intre doua orașe,
presupunând ca viteza de deplasare este constanta.
 Ca euristica vom utiliza pentru fiecare oraș distanta geometrica (in linie
dreapta) până la București.

Fig. 1: Graful stărilor

126
Inteligenţă Artificială. Tehnici.

Fig. 2 : Funcția euristică

13.2. Greedy Best-First.

În cadrul acestei strategii se consider că nodul care merită să fie expandat în pasul
următor este cel mai apropiat de soluție. Din acest considerent funcția de evaluare a
cât de promițător este nodul va ține cont numai de component euristică h(n), costul
drumului până la starea curentă finală. ignorant.

f(n)=h(n),  n

Este cunoscută și sub denumirea de Metoda ascensiunii – strategia alpinistului (hill


climbing). Numele metodei este dat de analogia cu maniera de căţărare pe un deal a
unui alpinist. El nu e capabil a vedea vârful dealului unde trebuie să ajungă dar poate
găsi, încercând la fiecare pas în jurul lui, permanent direcţia care-l face să urce.

Fig. 3: Urcarea dealului (hill climbing)

Strategia Greedy Best-First este o generalizare a strategiei de căutare în adâncime


cu particularitatea ca dintre toţi succesorii posibili ai unei configuraţii, este aleasa
aceea a cărui estimator euristic prezintă valoarea cea mai mică (sau cea mai mare).

Metoda ascensională caută să atingă starea caracterizată de valoarea maximă /


minimă a funcţiei euristice. Metoda garantează găsirea unei soluţii chiar dacă
anumite probleme pot avea maxime locale sau platouri, după cum se sugerează în
Figura 4.

127
Inteligenţă Artificială. Tehnici.

Fig. 4: Maximele locale şi platourile opresc temporar înaintarea spre soluţie

Se aduce aminte că în cazul căutării în adâncime clasice, explorarea alternativelor


(configuraţiilor) se face cu cele mai din stânga noduri din arborele alternativelor
posibile. Similar, funcţionează şi strategia Greedy Best-First principiul fiind redat
în figura de mai jos.

Fig. 5 Principiul metodei Gredyy Best-First

Pentru a implementa metoda, vom lua în considerare următoarele aspecte:

 Structura unei configuraţii (alternative) din spaţiul stărilor, este data de un obiect
compus unde apar doua elemente: configuraţia propriu zisa şi valoarea
estimatorului euristic corespunzătoare configuraţiei respective. Ca urmare vom
avea:

128
Inteligenţă Artificială. Tehnici.

Configuratie = stare(nod, valoare estimator euristic)

 Se utilizează o tehnica de tip generează şi testează a cărei principale


componente sunt prezentate în continuare

1. solve_hill_climb(Istoric, Configuratie_Curenta, Solutie)


implementează generează şi testează prin aceea, că plecând de la o
configuraţie curentă propune (conform regulilor impuse de problemă) o nouă
configuraţie care prezintă un estimator euristic cu valoare maxima (sau
minimă). Pentru a reţine drumul până la configuraţia curentă se utilizează
variabila Istoric. Aceasta este utilizată pentru implementarea mecanismului de
detecţie de ciclu ( o configuraţie propusa este sau nu prezentă în secvenţa de
configuraţii generate până în momentul curent).

2. hill_climb(Stare, Stare1)
are rolul de a genera o noua configuraţie (Stare1) plecând de la starea
curentă (Stare).

3. evalueaza_şi_ordonează (Noduri, Manevra, Stări_ordonate)


are rolul de a prelucra succesorii configuraţiei curente prezenţi în lista Noduri,
de a găsi pentru fiecare valoarea estimatorului euristic şi de a crea în final o
lista cu noile configuraţii procedând la ordonarea lor conform valorii
estimatorului euristic asociat.. Utilizează o procedura de forma însert(Stare,
Manevra, Stari_ordonate) cu rolul de a însera o stare într-o lista de stări
ordonate crescător (sau descrescător) după valoarea estimatorului euristic h.

4. Se utilizează o procedură de tip aparţine cu un dublu rol:

- aparţine(Stare, Istoric) testează dacă o configuraţie definite de Stare este


sau nu prezentă în Istoric ( implementez practice secvenţa de testare din
generează şi testează);

- aparţine(Stare, Stari_ordonate) cu rolul de a oferi o alta alternative de


configuraţie (un alt drum de ascensiune în arborele alternativelor posibile)
în cazul în care s-a ajuns la capătul unui drum de unde nu se mai poate
continua.

Strategia de tip Greedy Best-First va prezentă următorul aspect:


129
Inteligenţă Artificială. Tehnici.

domains
nod = symbol drum = nod*
element = stare(symbol,integer) stări= element*

predicates
rezolva(nod,drum)
solve_hil_climb(stări, element, drum) hil_climb(element, element)
aparţine(nod, drum) aparţine(element, stări)
evalueaza_si_ordoneaza(drum,stări,stări) insert(element,stări,stări)
s(nod,nod) h(nod,integer)

goal
rezolva(a,R),write(R).

clauses

rezolva(Nod,Solutie) :-
solve_hil_climb([ ],stare(Nod,0), Solutie).

solve_hil_climb( _, stare(Nod, _ ), [Nod]) :- Nod="j".

solve_hil_climb(Istoric,stare(Nod,V),[Nod|Sol]) :-
hil_climb(stare(Nod,V),stare(Nod1,V1)),
not(aparţine(stare(Nod1,V1),Istoric)),
solve_hil_climb([stare(Nod,V)|Istoric],stare(Nod1,V1),Sol).

hil_climb(stare(Nod,_),Stare1) :-
findall(Nod1,s(Nod,Nod1),Noduri),
evalueaza_si_ordoneaza(Noduri,[ ],NVa),
aparţine(Stare1,NVa).

evalueaza_si_ordoneaza([Nod|Noduri],NVa,NVa_ordonat) :-
h(Nod,Valoare),
insert(stare(Nod,Valoare),NVa,NVa1),
evalueaza_si_ordoneaza(Noduri,NVa1,NVa_ordonat).

evalueaza_si_ordoneaza([],NVa,NVa).

insert(stare(N,V),[ ],[stare(N,V)]).
insert(stare(N,V),[stare(N1,V1)|NVa],[stare(N,V),stare(N1,V1)|NVa]) :-
V<=V1.
insert(stare(N,V),[stare(N1,V1)|NVa],[stare(N1,V1)|NVa1]) :-
V>V1,
insert(stare(N,V),NVa,NVa1).

aparţine(X,[X|_]). aparţine(X,[_|R]) :- aparţine(X,R).

130
Inteligenţă Artificială. Tehnici.

s(a,b). s(a,c). s(a,n). s(b,d). s(b,e). s(d,h). s(d,i). s(e,j).


s(c,f). s(c,g). s(c,j). s(f,k). s(f,l). s(g,m).

h(b,7). h(c,4). h(n,3). h(d,18). h(e,9). h(h,4). h(i,6). h(e,9). h(j,5).


h(f,8). h(g,9). h(j,10). h(k,11). h(l,12). h(m,13).

Observaţii

Pentru a putea urmări modul de funcţionare a strategiei s-a inclus un arbore al


alternativelor posibile definit prin axiome (în doua variante) cât şi valorile pentru
estimatorul euristic ataşat fiecărei alternative definite prin nodurile (configuraţii
definite de axiome). Este evident faptul că pentru o problema practică, se va defini o
procedura succesor şi un estimator euristic corespunzător.

Comentarii legate de strategia Greedy Best-First

1. Greedy Best-First urmărește mereu soluția care pare cea mai apropiată de
țintă. Strategia propune în acest context o tehnica de înaintare funcţie de
valoarea unei estimaţii euristice fiind aleasa prima stare “mai bună” din cele
posibile de a fi urmate. A decide când o stare este „mai bună” decât alta
presupune existenţa unui criteriu de comparare a stărilor între ele. Acesta este
dat de o funcţie euristică (sau de evaluare a stării). Deci primul lucru ce
trebuie avut în vedere atunci când se apelează la metoda Greedy Best-First
este construirea unei astfel de funcţii. Acest lucru nu este întotdeauna uşor.

2. Faptul că Greedy Best-First urmărește mereu soluția care pare cea mai
aproape de sursa nu se vor analiza stări care deși par mai depărtate de soluție
produc o cale către soluție mai scurta. De asemenea, întrucât nodurile din
listele intermediare create (vezi Fig. 5.) nu sunt niciodată reexplorate se va găsi
calea cea mai scurta către scop doar dacă se întâmplă ca această cale să fie
analizată înaintea altor căi către aceiași stare scop. Din acest motiv, algoritmul
nu este optim. De asemenea, pentru grafuri infinite e posibil ca algoritmul să
ruleze la infinit, chiar dacă exista o soluție.

In figura de mai jos se prezintă rularea algoritmului Greedy Best-First pe exemplul


dat mai sus. în primul pas algoritmul expandează nodul Arad, iar ca nod următor de

131
Inteligenţă Artificială. Tehnici.

explorat se alege Sibiu, întrucât are valoarea h(n) minima. Se alege în continuare
Făgăraș după care urmează București, care este un nod final. Se observa însă ca
acest drum nu este minimal. Deși Făgăraș este mai aproape ca distanta geometrica
de București, în momentul în care starea curenta este Sibiu alegerea optimala este
Râmnicu-Vâlcea. în continuare ar fi urmat Pitești și apoi București obținându-se un
drum cu 32 km mai scurt.

Fig. 6 : Rulare Greedy Best-First

132
Inteligenţă Artificială. Tehnici.

13.3 A* (A Star)

A* reprezintă cel mai cunoscut algoritm de căutare euristică. Metoda combină


metodele de căutare în adâncime şi de căutare în lăţime în sensul că avansează pe
direcția celei mai promițătoare stări (căutare în adâncime) în contextul unei frontiere
(căutare în lățime) care se actualizează în fiecare moment al construirii spațiului
stărilor.

A* nu suferă de aceleași defecte pe care le are Greedy Best-First prin faptul


că utilizează o funcție de evaluare complectă de:

f(n)=g(n)+h(n),  n

A* evaluează nodurile combinând distanta deja parcursa până la starea curentă cu


distanta estimata până la cea mai apropiata stare țintă. Cu alte cuvinte, pentru un
nod n oarecare, f(n) reprezintă costul estimat al celei mai bune soluții care trece
prin n.

Algoritmul evoluează în felul următor: la fiecare pas sortează toate nodurile ce nu au


fost încă vizitate în ordinea crescătoare sau descrescătoare a valorilor estimatorilor
euristici ataşaţi configuraţiilor (nodurilor) şi alege pentru expandare în continuare pe
cel mai bine plasat.

Pentru realizare acestui deziderat sunt menţinuţi constant în atenţie un set de


drumuri posibile a căror extremităţi care pot fi extinse în continuare, definesc o
frontieră. În fiecare pas de expandare, aceasta este împinsă mai departe de către
drumul a cărui nod prezent în frontieră, prezintă estimatorul euristic optim. Modul de
funcţionare este ilustrat în figura următoare, unde în dreptul unui nod s-a trecut
valoarea estimatorului euristic.

133
Inteligenţă Artificială. Tehnici.

Pentru a implementa metoda vom lua în considerare următoarele aspecte:

 Structura unei configuraţii (alternative) din spaţiul stărilor este data de un obiect
compus unde apar trei elemente:

- configuraţia propriu zisa, urmata de

- drumul de la nodul de start la configuraţia definite de nod şi

- valoarea estimatorului euristic corespunzătoare configuraţiei respective.

Ca urmare vom avea:

Configurație = stare(nod, drum, valoare estimator euristic)

Este de menţionat faptul că nod defineşte extremitatea drumului care se găseşte în


frontieră. Pentru exemplul dat, un element al acestei frontiere va fi de forma:

stare(x, [e, c, a ], 11)

 Strategia care are la baza tehnica generează şi testează, face apel la


următoarele componente:

134
Inteligenţă Artificială. Tehnici.

1. solve_best(Frontiera, Istoric, Solutie)

cu rolul de a selecta un nod (configuraţie) cu cea mai bună valoare a


estimatorului euristic, de a genera succesorii acestuia în conformitate cu
regulile problemei. Ca urmare se împinge cu un pas mai departe
Frontiera. Aceasta este o lista în care sunt prezente frunzele arborelui
alternativelor posibile care se pot dezvolta sau nu în continuare, lista fiind
ordonata după valoarea estimatorului euristic h. În Istoric se păstrează
secvenţa de configuraţii care apar între nodul de Start şi configuraţia
curenta prezentă în frontieră.

2. update_frontier (Noduri, Nod, Drum, Istoric, Frontiera_curenta,


Frontiera_actualizata).
Are rolul de a actualiza frontiera curenta cu configuraţiile noi generate
de configuraţia optima aleasa definita de Nod. Pentru fiecare
configuraţie astfel obţinuta, reţinuta în lista Noduri, se calculează
estimatorul euristic şi se procedează la înserarea acestuia în
Frontiera_iniţiala funcţie de valoarea estimatorului euristic pe care îl
prezintă, rezultatul fiind o Frontiera_actualizata. În momentul actualizării
acesteia se procedează inclusiv la actualizarea variabilei Drum în care
se reţine drumul de la Start la configuraţia curenta cu configuraţia
curenta care a generat succesorul şi transferarea ei în obiectul compus
care este elementul ce se înserează propriu zis în noua frontiera.
Variabila Istoric reţine istoricul configuraţiilor care merg de la nodul de
Start la nodul care a generat succesorii fiind utilizat pentru
implementarea mecanismului de detecţie de ciclu.

3. insert(Stare, Manevra, Stari_ordonate).


Are rolul de a insera o stare de forma :

stare(nod, drum, valoare estimator euristic)

într-o lista de stări ordonate după valoarea estimatorului euristic, crescător


sau descrescător.

135
Inteligenţă Artificială. Tehnici.

4. Pentru detectarea ciclurilor se utilizează o procedura de forma aparţine(


Nod, Drum), care verifică dacă configuraţia generata este sau nu
prezentă în secvenţa de stări de la Start la starea care a generat
configuraţia respectiva.

Strategia de tip best-first prezintă aspectul:


domains
nod = symbol drum = nod*
element = stare(nod,drum,integer) frontiera=element*

predicates
rezolva(nod,drum) solve_best(frontiera,drum,drum)
aparţine(nod,drum) insert(element,frontiera,frontiera)
update_frontier(drum,nod,drum,drum,frontiera,frontiera)
s(nod,nod) h(nod,integer)
mai_mic(element,element) egal(element,element)

goal
rezolva(a,R),write(R).

clauses
rezolva(Nod,Solutie) :-
solve_best([stare(Nod,[ ],0)],[ ],Solutie).

solve_best([stare(Nod,Drum, _ )| _], _ ,[Nod|Drum]) :-


Nod = "j".

solve_best([stare(Nod,Drum,_)|Frontiera],Istoric,Sol) :-
findall(Nod1,s(Nod,Nod1),Noduri),
update_frontier(Noduri,Nod,Drum,Istoric,Frontiera,Frontiera1),
solve_best(Frontiera1,[Nod|Istoric],Sol),!;
solve_best(Frontiera,Istoric,Sol).

update_frontier([Nod1|Noduri],Nod,Drum,Istoric,F,F1) :-
h(Nod1,Value),
not(aparţine(Nod1,Istoric)),
insert(stare(Nod1,[Nod|Drum],Value),F,F0),
update_frontier(Noduri,Nod,Drum,Istoric,F0,F1).
update_frontier([ ],_,_,_,F,F).

insert(Stare,[ ],[Stare]).
insert(Stare,[Stare1|Stari],[Stare,Stare1|Stari]) :-
mai_mic(Stare1,Stare).
insert(Stare,[Stare1|Stari],[Stare|Stari]) :-
egal(Stare,Stare1).

136
Inteligenţă Artificială. Tehnici.

insert(Stare,[Stare1|Stari],[Stare1|Stari1]) :-
mai_mic(Stare,Stare1),insert(Stare,Stari,Stari1).

egal(stare(S,_,V),stare(S,_,V)).

mai_mic(stare(S1,_,V1),stare(S2,_,V2)) :-
S1<>S2,V1<V2.
aparţine(X,[X|_]).
aparţine(X,[_|R]) :- aparţine(X,R).

s(a,b). s(a,c). s(a,n). s(b,d). s(b,e). s(d,h). s(d,i). s(e,j).


s(c,f). s(c,g). s(c,j). s(f,k). s(f,l). s(g,m).

h(b,7). h(c,4). h(n,3). h(d,10). h(e,2). h(h,4). h(i,6). h(e,9). h(j,5).


h(f,8). h(g,9). h(j,10). h(k,11). h(l,12). h(m,13).

Observaţii

Pentru a putea urmări modul de funcţionare a strategiei s-a inclus un arbore al


alternativelor posibile definit prin axiome (în doua variante) cât şi valorile pentru
estimatorul euristic ataşat fiecărei alternative definite prin nodurile (configuraţiei
definite de axiome). Este evident faptul că pentru o problema practică se va defini o
procedura succesor şi un estimator euristic corespunzător.

In figura de mai jos se prezintă rularea algoritmului A* pentru următoarea problema:


dată fiind o harta rutiera a României, să se găsească o cale (de preferința de cost
minim) între Arad și București.

Se observă că în pasul (e), după expandarea nodului Făgăraș deși există o soluție în
mulțimea open aceasta nu este aleasă pentru explorare. Se va alege Pitești, întrucât
f(nod(București)) = 450 > f(nod(Pitești)) = 417, semnificația acestei inegalități fiindcă
e posibil sa existe prin Pitești un drum mai bun către București decât cel descoperit
până acum.

137
Inteligenţă Artificială. Tehnici.

Fig.7. Rulare A*

138
Inteligenţă Artificială. Tehnici.

Comentarii legate de strategia A*

1. Algoritmul va găsi calea optima către soluție, dacă o soluție există. Singurul
inconvenient fata de Greedy Best-First este ca sunt necesare reevaluările
nodurilor din frontieră.

2. În practica, însă, A* poate fi de multe ori imposibil de rulat datorita dimensiunii


prea mari a spațiului de căutare. Singura modalitate prin care spațiul de
căutare poate fi redus este prin găsirea unei euristici foarte bune – cu cât
euristica este mai apropiata de distanta reala fata de stare soluție cu atât
spațiul de căutare este mai strâns (vezi figura de mai jos).

Fig. 8. Volumul spațiului de căutare în funcție de euristica aleasa

3. Pentru reducerea spațiului de memorie utilizat, alte abordări presupun


sacrificarea timpului de execuție. Aceste alternative sunt prezentate în
continuare:

139
Inteligenţă Artificială. Tehnici.

13.4 IDA*
Iterative Deepening A* utilizează conceptul de adâncime iterativă în procesul de
explorare a nodurilor. La un anumit pas se vor explora doar noduri pentru care
funcția de evaluare are o valoare mai mica decât o limita dată. Limita este dată de
valoarea maximă a funcției euristice f. Această limită este incrementata treptat până
se găsește o soluție. Căutarea este de tip depth-first, funcția euristică fiind utilizată
numai pentru limitarea expansiunii în spațiul stărilor.
 În prima iterație se determină “f-cost limit” – cut-off value
f(n0) = g(n0) + h(n0) = h(n0), unde n0 este nodul de start.
 Se expandează nodurile a căror funcție euristică f(n) nu depășește valoare
funcției de cost limită . Expandarea utilizează o strategie de tip depth-first
 Daca căutarea nu are succes se determină cea mai mică valoare f(n) a
nodurilor care au fost vizitate dar nu au fost expandate.
 Se utilizează această valoare pentru noua limită de tip “f-cost limit” – cut-off
value și se reinițializează o altă căutare de tip dept-first
 S repetă această procedură până în momentul găsirii nodului țintă.

140
Inteligenţă Artificială. Tehnici.

Caracteristici IDA*
 Este completă (garantează găsirea unei soluții)
 Nu este optimă (nu garantează găsirea unei soluții optime)
 Cere mai puțină memorie comparativ cu A* deoarece nu mai necesita
utilizarea unor mulțimi pentru reținerea nodurilor explorate.

141
Inteligenţă Artificială. Tehnici.

 Se comporta bine în cazul în care toate acțiunile au același cost. Din


păcate, devine ineficient în momentul în care costurile sunt variabile.

RBFS (Recursive Best-First Search) funcționează intr-un mod asemănător cu


DFS, explorând la fiecare pas nodul cel mai promițător fără a retine informații despre
nodurile deja explorate. Spre deosebire de DFS, se retine în orice moment cea mai
buna alternativa sub forma unui pointer către un nod neexplorat. Daca valoarea
funcției de evaluare (f = g + h) pentru nodul curent devine mai mare decât valoarea
caii alternative, drumul curent este abandonat și se începe explorarea nodului reținut
ca alternativa. RBFS are avantajul ca spațiul de memorie creste doar liniar în raport
cu lungimea caii analizate. Marele dezavantaj este ca se ajunge de cele mai multe ori
la re expandări și re explorări repetate ale acelorași noduri, lucru care poate fi
dezavantajos mai ales daca exista multe cai prin care se ajunge la aceiași stare sau
funcția expand este costisitoare computațional.

MA* (Memory-bounded A*) este o varianta a A* în care se limitează cantitatea


de memorie folosita pentru reținerea nodurilor. Exista doua versiuni – MA* și SMA*
(Simple Memory-Bounded A*), ambele bazându-se pe același principiu. SMA*
rulează similar cu A* pana în momentul în care cantitatea de memorie devine
insuficienta. în acest moment spațiul de memorie necesar adăugării unui nod nou
este obținut prin ștergerea celui mai puțin promițător nod deja explorat. în cazul în
care exista o egalitate în privința valorii funcției de evaluare se șterge nodul cel mai
vechi. Pentru a evita posibilitatea în care nodul șters este totuși un nod care conduce
la o cale optimala către soluție valoarea f a nodului șters este reținuta la nodul părinte
intr-un mod asemănător felului în care în RBFS se retine cea mai buna alternativa la
nodul curent. și în acest caz vor exista reexplorări de noduri, dar acest lucru se va
întâmpla doar când toate căile mai promițătoare vor eșua. Deși exista probleme în
care aceste regenerări de noduri au o frecventa care face ca algoritmul sa devina
intratabil, MA* și SMA* asigura un compromis bun intre timpul de execuție și limitările
de memorie.

142
Inteligenţă Artificială. Tehnici.

13.5 Utilizarea arborilor pentru reprezentarea soluţiilor


Aşa cum s-a văzut în contextual căutării de tip best-first multitudinea de drumuri
între configuraţia Start şi Ţinta sunt reţinute în liste ataşate fiecărui element din
frontiera. Acest aspect face ca sa apăra configuraţii similare care se reţin de doua
sau mai multe ori în fiecare din drumurile ataşate elementelor prezente în frontiera.,
ceea ce are ca rezultat direct mărirea cantităţii de memorie solicitata. Din acest punct
de vedere problema este similara cu cea ridicata de procedura standard de căutare
în lăţime. Ca urmare se ridică problema optimizării reprezentării şi reţinerii drumurilor
alternative posibile – aspect care poate fi rezolvat făcând apel la o structura de tip
arbore pentru reţinerea acestei informaţii. Structura utilizează doua tipuri de obiecte
compuse:
1. l(Nod, F,G) structura va defini o frunza unde Nod reprezintă configuraţia
curenta F funcţii de estimare euristică f(n)=g(n)+h(n), iar G costul căi de la
start la configuraţia curenta Nod.
2. t(Nod, F, G, SubArbori), structura reprezintă un arbore a cărei rădăcina este
data de configuraţia Nod şi care prezintă funcţia euristică F de cost G.
Subarbori definesc o lista de arbori ce reprezintă ramuri ale lui t (frunze şi /
sau arbori) ordonata în sensul crescător a lui F.
3. Este de făcut remarca că structura poate fi simplificata dacă costul căi G este
constant astfel că cele doua elemente vor apare de forma: l(Nod, H) şi
respective t(Nod, H, SubArbori), unde H este estimatorul euristic.

Strategia care implementează în fapt o strategie de tip generează şi testează


face apel la următoarele proceduri:
1. expand(Drum, Arbore, Arbore_expandat, Rezolvat, Solutie)
unde
 Arbore reprezintă arborele care se dezvolta pe direcţia cea mai
promiţătoare (direcţie care este data de frunza (configuraţia) a cărui
estimator euristic este cel mai promiţător. Frunza devin rădăcina unui nou
subarbore care extinde arborele iniţial a cărui rădăcina este configuraţia
iniţiala definita de nodul Start. În urma creşterii rezulta un nou arbore
reţinut în Arbore_expandat.

143
Inteligenţă Artificială. Tehnici.

 Drum reţine secvenţa de configuraţii de la nodul Start la frunza selectata.


Este utilizat pentru implementarea unui mecanism de detecţie a ciclurilor.
 Rezolvat reprezintă un indicator care poate lua valorile:
nu – dacă nu s-a găsit Soluția şi arborele poate creste în continuare
da – soluţia s-a găsit şi creşterea se opreşte;
never – frunza selectata nu poate deveni rădăcina unui sub arbore
deoarece nu mai are succesori .
 Solutie reprezintă o lista în care se reţine drumul – secvenţa de configuraţii
– între Start şi Ţinta.
Modul de funcţionare a strategiei este ilustrata de figura următoare.

2. continue(Drum, Arbore, Arbore_expandat, Rezolvat, Rezolvat1, Rezolvat, Solutie)


Are rolul de a selecta din lista de subarbori, subarborele cel mai promiţător
(amintim că lista de subarbori este ordonata funcţie de valoarea funcţiei euristice
ataşata fiecărui nod rădăcina care ii defineşte) cu condiţia ca acesta sa poate
creste (semaforul care specifică acest lucru este dat de Rezolvat1 şi valoarea sa
trebuie sa fie nu Rezolvat1=nu). Subarborele selectat este cel care va expanda.

Important
Trebuie reţinut faptul că pe fiecare nivel al arborelui de căutare în spaţiul
configuraţiilor fiecare lista de subarbori este ordonata după valoarea estimatorului

144
Inteligenţă Artificială. Tehnici.

euristic. . Se va lua în considerare nivel cu nivel arborele cel mai promiţător până
când se ajunge la ultimul subarbore aflat pe ultimul nivel de unde se ia în
considerare frunza cea mai promiţătoare. Aceasta dezvoltă un nou sub arbore
care se înserează într-o noua lista dacă se coboară un nivel mai jos sau în una
din listele de subarbori prezente pe unul din nivele funcţie de valoarea funcţiei
euristice.

3. adaug(Arbore, Manevra, Arbori_ordonati)


cu rolul de a însera un arbore nou creat în lista de subarbori existenta (
corespunzătoare nivelului la care s-a creat subarborele sau într-o lista noua
dacă s-a avansat un nivel ( creste înălţimea arborelui alternativelor care se
explorează)
Strategia de căutare este ilustrata în continuare

domains
arbore = t(nod, integer, integer, frunze); l(nod, integer, integer)
frunze = arbore* nod = symbol
drum = nod* drumuri = drum*
rezolvat = da; nu; never

predicates
bestf(nod,drum)
expand(drum, arbore, arbore, rezolvat, drum)
continue(drum, arbore, arbore, rezolvat, rezolvat, drum)
adaug(drum,drum,frunze,frunze,nod,integer)
insert(arbore, frunze, frunze)
f(arbore, integer) aparţine(nod, drum)
s(nod,nod) h(nod,integer)
c(nod,nod,integer)

goal
clearwindow,
bestf(a,R),bound(R),write(R),!;
write("\n Fara solutie").

clauses
bestf(N,Solutie) :-
expand([ ],l(N, 0, 0), _ , _ , Solutie).

145
Inteligenţă Artificială. Tehnici.

expand(P, l(N, _ , _ ), _ ,da, [N|P]) :- N = "j".

expand(P, l(N, F, G), Tree, Rez, Sol) :-


findall(N1,
s(N,N1),
NoiNoduri),
adaug(NoiNoduri,P,[ ],Ramuri,N,G),
expand(P,t(N,F,G,Ramuri),Tree,Rez,Sol);
Rez is never.

expand(P,t(R,F,G,[T|Subs]),Tree,Rez,Sol) :-
expand([R|P],T,T1,Rez1,Sol),
continue(P,t(R,F,G,[T1|Subs]),Tree,Rez1,Rez,Sol).

expand(_,t(_,_,_,[ ]),_,never,_) :- !.

continue(_,_,_,da,da,_).

continue(P,t(R,F,G,[T|Subs]),Tree,Rez1,Rez,Sol) :-
Rez1 = nu,
insert(T,Subs,NTs),
expand(P,t(R,F,G,NTs),Tree,Rez,Sol);
Rez1 = never,
expand(P,t(R,F,G,Subs),Tree,Rez,Sol).

adaug([N|R],Drum,Ramuri,Ramuri_ordonat,N1,G) :-
not(aparţine(N,Drum)),
h(N,H),
c(N1,N,Cost),
G1 is G+Cost,
F1 is G1+H,
insert(l(N,F1,G1),Ramuri,Ramuri1),
adaug(R,Drum,Ramuri1,Ramuri_ordonat,N1,G),!.
adaug([ ], _, [ ], _ , _ , _ ) :- fail.
adaug([ ], _ , R, R, _ , _ ).

insert(l(N,F,G),[ ],[l(N,F,G)]).
insert(T,[T1|Tree],[T,T1|Tree]) :-
f(T,F),f(T1,F1),F<=F1,!.
insert(T,[T1|Tree],[T1|Tree1]) :-
insert(T,Tree,Tree1).
f(l( _ , F, _ ), F).
f(t(_, F, _ , _ ), F).

aparţine(X,[X|_]).
aparţine(X,[_|R]) :-
aparţine(X,R).

146
Inteligenţă Artificială. Tehnici.

s(a,b). s(a,c). s(a,n). s(b,d). s(b,e). s(d,h). s(d,i). s(e,j). s(c,f). s(c,g).
s(f,k). s(f,l). s(g,m). s(e,j). s(l,j).

h(b,7). h(c,4). h(n,3). h(d,1). h(e,2). h(h,4). h(i,6). h(j,5).


h(f,8). h(g,9). h(j,10). h(k,11). h(l,12). h(m,13).

c(a,b,2). c(a,c,3). c(a,n,4). c(b,d,1). c(b,e,1). c(c,f,10). c(c,g,10). c(c,j,10).


c(f,k,3). c(f,l,4). c(e,j,1). c(g,m,5). c(l,j,10).

Observaţie
Ca şi în exemplele date anterior, pentru a putea urmări modul de funcţionare
s-a considerat un spaţiu al configuraţiilor definit prin axiome, la care s-au adăugat
estimatorii euristici ai configuraţiilor ca şi costul mişcării între doua configuraţii ( de
ex. c(a,b,2) costul treceri din configuraţia a în b este 2)

Concluzii

1. Deseori singura modalitate de rezolvare a problemelor combinatoriale este de


a explora graful stărilor acelei probleme. Algoritmii clasici pe grafuri nu sunt
potriviți pentru căutarea in aceste grafuri fie pentru ca nu garantează un
rezultat fie pentru ca sunt ineficienți. Algoritmii euristici sunt algoritmi care
explorează astfel de grafuri folosindu-se de o informație suplimentara despre
modul in care se poate ajunge la o stare scop mai rapid. A* este, teoretic, cel
mai eficient algoritm de explorare euristica. În practica, însă, pentru probleme
foarte dificile, A* implica un consum prea mare de memorie. În acest caz se
folosesc variante de algoritmi care încearcă sa minimizeze consumul de
memorie in defavoarea timpului de execuție.

2. În multe cazuri algoritmul A* consumă o cantitate de timp semnificativă cu


încercările de a alege între diverse căi al căror cost nu diferă semnificativ.
Acest aspect poate deveni o limitare serioasa și poate duce la creșterea
timpului de rezolvare a problemei. Există probleme pentru care s-ar putea sa
intereseze mai puțin obținerea unei soluții de cost minim și scopul urmărit să
fie mai ales minimizarea efortului de căutare. Motivul includerii în funcția de

147
Inteligenţă Artificială. Tehnici.

evaluare f a funcției g este acela de a adăuga căutării o componentă de


căutare pe nivel și de a ghida astfel căutarea spre descoperirea soluției
optime. Fără funcția g, f(S) ar estima tot timpul, pentru fiecare nod S, distanța
rămasa până la starea finala. Daca scopul este acela de a minimiza efortul de
căutare și nu costul soluției, atunci ponderea funcției h trebuie sa fie cât mai
mare. Pentru a ajusta ponderile intre aceste doua tendințe, cost optim și avans
rapid spre soluție, s-a propus următoarea definiție ponderată a funcției f:

f (S) (1p) g(S) p h(S) ,

unde p este o constanta pozitiva. Daca p = 0 atunci algoritmul de căutare


devine o strategie de căutare de cost uniform, daca p = 1/ 2 atunci se obține
varianta standard a algoritmului A*, iar daca p = 1 atunci se obține o căutare
de tip "best-first" care urmărește numai minimizarea efortului de căutare.

Pentru o altă categorie de probleme este posibil să intereseze soluția de cost


minim dar problema sa fie atât de grea încât un algoritm A * admisibil sa fie
practic imposibil de executat până la sfârșit din criterii de eficienta. Într-o astfel
de situație se urmărește găsirea unei soluții suficient de apropiate de soluția
de cost minim intr-un interval de timp acceptabil. Funcția f poate fi definita
printr-o ponderare dinamica a componentei h

f (S) g(S) c(S) h(S),

unde c(S) este o funcție de ponderare a cărei valoare depinde de nodul S. In


1973, s-a propus următoarea varianta de funcție ponderata dinamic:

 d S  
f  S   g  S   h  S    1   hS 
 N 

148
Inteligenţă Artificială. Tehnici.

unde d(S) este adâncimea nodului asociat stării S și N este adâncimea


estimata a nodului stare finala. Daca funcția h este admisibila atunci un
algoritm A* care utilizează aceasta definiție a funcției f va găsi o soluție
suboptimala al cărei cost diferă cu cel mult de costul soluției optime.
Utilizând aceasta abordare s-a încercat rezolvarea problemei comis-voiajorului
pentru cazul a 20 de orașe. Un algoritm A* nu a produs soluția optimă nici
după expandarea a 500 de noduri. Cu definiția funcției de evaluare dată mai
sus s-a găsit o soluție de cost 260 după expandarea a numai 53 de noduri.

149
Inteligenţă Artificială. Tehnici.

13.6. Tehnici de construire a estimatorilor euristici


In principal sunt prezente doua tipuri de tehnici utilizate pentru construirea
estimatorilor euristici. Le vom exemplifica succesiv plecând de la două exemple.

(TEHNICA I) Problema barcagiului: Un barcagiu doreşte să treacă un lup, o capra


și o varza de pe malul stâng a unui râu pe malul drept, cu ajutorul unei bărci care
poate transporta o data numai doi pasageri ( sau nici unul). Lupul și capra nu pot
rămâne împreuna singuri nesupravegheaţi, la fel capra și varza.

In contextul acestei situaţii, deoarece se doreşte ca toate cele 3 elemente să


fie prezente pe malul drept al râului, estimatorul este dat de numărul de elemente
de pe malul drept, alternativa care prezintă un număr maxim de elemente pe
dreapta va fi preferată. Costul arcului va fi dat de numărul de elemente prezente în
barca prin intermediul căreia acestea sunt transportate peste râu.

In aceste condiţii , dintre aceste alternative, se va alege prima pentru care


h=2. Alegând aceasta alternativa putem determina costul drumului din starea
iniţiala în care am ajuns. în cazul dat acesta este egal cu Cost=2, deoarece se
doreşte a fi transportate cat mai multe elemente.
Cele două procese care calculează estimatorul şi costul drumului dintre 2
stări alternative va fi definit de:

150
Inteligenţă Artificială. Tehnici.

 h(Nod,H) unde H este estimatorul pe care îl oferă alternativa Nod


si
 c(Nod,Nod1,Cost) unde Cost este costul drumului dintre
configuraţia curenta și cea următoare. Pentru exemplul dat
procedura c prezintă o simplificare deoarece este suficienta
cunoaşterea structurii lui Nod1 pentru a determina costul drumului.
Procedura prezintă aspectul:

domains
element=lup; varza; capra; alone stare=element*
mal=stanga; dreapta nod=Ivc (mal,stare,stare)
predicates
h(nod, integer) c(nod, nod, integer)
numar(stare, integer) scad(integer, integer)

clauses
c(Ivc(_,S,D),C) :- numar(S,Hs),
numar(D,Hd),
scad(Hs,Hd,C).
numar ([ ], 0 ).
numar ([ _ |R], H) :- C=B-A,
C>=0,!,
C is A-B.
h(Ivc(_,_,D),H) :- numar(D,H).

Se observă că în această condiţie pot fi utilizate 2 strategii. Fie se


minimizează elementele de pe malul stâng fie se maximizează elementele de pe
malul drept.

(TEHNICA II) Problema 8-puzzle: Există o tablă 3x3 pe care se găsesc 8 piese
pătrate. La un moment dat o singură piesă se poate mişca cu o poziţie, pe
orizontală sau verticală, în limitele cadrului tablei, în locul rămas liber. Plecând de la
o configuraţie iniţială a tablei trebuie să se ajungă într-alta, ce este de asemenea
dată

151
Inteligenţă Artificială. Tehnici.

Iniţial vom construi procedura succesor în contextul regulilor de joc (moment în care
vom specifica și structura de date utilizată), după care vom trece la prezentarea
modului I care se construieşte estimatorul euristic.

Construirea procedurii succesor


Situaţia curenta pe tabla apare ca o lista de poziţii a pieselor în care primul
element corespunde pătratului liber, iar poziţia elementului în listă corespunde
numărului piesei. Pentru situaţia din figura de mai jos vom avea astfel:

Configuratie

[ [3, 3], [1, 3], [2, 2], [2, 3], [3, 2], [3, 1], [2, 1], [1, 1], [1, 2] ]

Pentru a vedea care piese se pot mişca se introduce o relaţie de distanta


definita astfel
D(S1, S2, D)
Unde D este distanta intre pătratele S1 și S2 ceea ce reprezintă distanta
dintre S1 și S2 în direcţia orizontala, plus distanta intre S1 și S2 în direcţia verticala.
Este evident în aceste condiţii ca numai piesele aflate la o distanta egala cu
1 fata de spaţiul liber se pot mişca. Ca urmare apare un predicat de tip
swap(E, T, P, P1)
Unde: E este poziţia elementului liber
T este elementul fata de care se calculează distanta
P este lista de poziţii iniţiale
P1 este lista de poziţii finale în care s-a interschimbat locul dintre
elementul liber și cel care se poate mişca
Procedura succesor va apare de forma:

152
Inteligenţă Artificială. Tehnici.

domains
poz=integer* tabl=poz*
predicates
s(tabl, tabl, tabl) swap(poz, poz, tabl, tabl)
d(poz, poz, integer) dif(intefer, integer, integer)

clauses
s([Empty | L], [T | L1], 1) :-
swap(Empty, T, L L1).
swap(E, T, [T | L], [E | L]) :-
d(E, T,1).
swap(E, T, [T1 | L], [T1 | L1]) :-
swap(E, T, L, L1).

d([X, Y], [X1, Y1], D) :-


dif(X, X1, Dx),
dif(Y, Y1, Dy),
D=Dx+Dy.
dif(A, b, D) :-
D=A-B,
D>=0,!;
D=B-A.

153
Inteligenţă Artificială. Tehnici.

Construirea estimatorului euristic


Modul de construire va fi ilustrat pentru situaţia de mai jos în care s-a luat în
considerare o poziţie intermediara și poziţia finala care se doreşte a fi atinsa.
După cum s-a specificat o configuraţie se reprezintă printr-o lista de poziţii a
pieselor în care prima poziţie corespunde pătratului liber. Pentru configuraţia final
avem:
Configuraţie finala=[ [2, 2], [1, 3], [2, 3], [3, 3], [3, 2], [3, 1], [2, 1], [1, 1], [1, 2] ]
Se face observaţia ca:
 poziţia unui element în lista corespunde numărului piesei;
 poziţia libera poate fi ocupata de oricare din vecini. Pentru a determina care
piese pot ocupa poziţia liber s-a definit o procedura de forma:
d(S1, S2, D)
unde:
 D este distanta dintre pătratele S1 și S2 ( distanta fiind definita de
suma dintre distanta în direcţia orizontala dintre S1 și S2, plus
distanta intre S1 și S2 în direcţia verticala ( este evident ca în aceste
condiţii pot fi mişcate piesele aflate la o distanta egala cu 1 fata de
pătratul liber).

 Din modul în care se defineşte un succesor rezultă că între 2 stări


alternative din spaţiul stărilor costul arcului asociat distanţei dintre
acestea este întotdeauna egal cu 1. Ca urmare componenta g(n)
poate fi omisă din calculul funcţiei f(n). Rămâne de luat în considerare
numai funcţia euristică definită de h(Poziţia,H) în care Poziţie este
configuraţia pentru care se calculează estimatorul euristic H.
La calculul componentei H intervin 2 aspecte.
1. Primul ia în considerare depărtarea unei piese faţă de poziţia finală iar
2. Al doilea aspect gradul de ordonare a pieselor pe tablă.
Pentru a ilustra acest caz consideram situaţia:

154
Inteligenţă Artificială. Tehnici.

1) Calculul distanţei totale a celor 8 piese din poziţia curentă faţă de poziţia
acasă . Distanța (pe orizontală și verticală) a patratului nevid în starea curentă față
de pozitia lui în starea finala se mai numește si "distanța Manhattan". Pentru
exemplul dat este dată de:

PIESA Distanţa faţă de poziţia


finală
2 2
3 1
4 1
Distanta totala = 4

2) Gradul de ordonare a pieselor din poziţia curenta raportata la poziţia finala


dorita se calculează ca o suma de scoruri pentru fiecare piesa conform
următoarelor reguli
- o piesa în centru scor 1
- o piesa aflata pe o poziţie care nu e centrala scor 0 daca apare în sensul
orar și este urmata de succesorul sau
- o piesa care nu este urmata de succesorul sau scor 2
Pentru exemplul dat avem:

PIESA Scor
1 2
4 2
2 2
Grad de ordonare = 6

Estimatorul euristic va prezenta aspectul:

h = total dist.+ 3*grad_de_ordonare

Este de remarcat faptul ca funcţia cumulează doua aspecte: distanta fata de


poziţia Ţinta și gradul de ordonare. Acest din urmă care are o contribuţie mult mai
mare în determinarea configuraţiei optime în raport cu criteriul distanta.
Experimental s-a demonstrat ca funcţia lucrează bine pentru un coeficient 3 de

155
Inteligenţă Artificială. Tehnici.

amplificare a gradului de ordonare în directarea căutării către ţintă.

Procedura de calcul este:

domains
poz=integer* tabl=poz*

predicates
h(tabl,integer) seq(tabl,integer)
tinta(tabl) s(tabl,tabl,integer)
d(poz,poz,integer) totdist(tabl,tabl,integer)
seq1(tabl,poz,integer) scor(poz,poz,integer)
swap(poz,poz,tabl,tabl) div(integr,integer,integer)

goal
p=[[3,3],[1,3],[2,2],[2,3],[3,2],[3,1],[2,1],[1,1],[1,2]],
h(P,D),write("Estimator euristic=",D),nl,
s(P,P1,1),write("Succesor\n",P1).

clauses
h([ _ | L], H) :-
ţinta([ _ | G]),
totdist(L, G, D),
seq(L,S),
H=D+3*S.
totdist( [ ], [ ], 0).
totdist( [T | L], [T1 | L1 ], D) :-
d(T, T1, D1),
totdist(L, L1, D2),
D=D1+D2.
seq( [ First |L ], S) :-
seq1([ First | L ], First, S).
swq1( [T1,T2 | L ], First, S) :-
scor(T1,T2,S1),
seq1( [ T2 | L ], First, S2),

156
Inteligenţă Artificială. Tehnici.

S=S1+S2.
seq1( [ Last ], First, S) :-
scor(Last, First, S).
scor( [2, 2], _ , 1) :- !.
scor( [1, 3], [2, 3], 0 ) :- !.
scor( [2, 3], [3, 3], 0 ) :- !.
scor( [3, 3], [3, 2], 0 ) :- !.
scor( [3, 2], [3, 1], 0 ) :- !.
scor( [3, 1], [2, 1], 0 ) :- !.
scor( [2, 1], [1, 1], 0 ) :- !.
scor( [1, 1], [1, 2], 0 ) :- !.
scor( [1, 2], [1, 3], 0 ) :- !.
scor( _ , _ , 2 ).
tinta( [ [2,2], [1,3], [2,3], [3,3], [3,2], [3,1], [2,1], [1,1], [1,2] ] ).
s( [Empty |L], [T |L1], 1) :-
swap( Empty,T, L, L1 ).
swap( E, T, [T |L], [E | L ] ) :-
d(E,T,1).
swap( E, T, [T1 |L], [T1 |L1] ) :-
swap(E,T,L,L1).
d( [X,Y], [X1,Y1], D ) :-
dif( X, X1, Dx),
dif( Y, Y1, Dy),
D=Dx+Dy.
dif(A,B,D) :-
D=A-B,
D>=0,!;
D=B-A.

Concluzii:
Pot fi definite două mari categorii de estimatori euristici.
(I) În prima categorie intră cei care definesc un număr de elemente sau
poziţii care deja sau atins. Este cel mai simplu criteriu și este aplicabil atunci când
interesează obţinerea unui număr de componente în care configuraţia nu contează.

157
Inteligenţă Artificială. Tehnici.

(II) în a 2-a categorie intră cei în care se defineşte o funcţie ce


caracterizează din mai multe puncte de vedere configuraţia curenta în raport faţă
de poziţia finală dată. în cazul generala aceasta funcţie poate avea mai multe
componente și anume:
- distanța la care se afla elementele din configuraţia curenta faţă de
elementele prezente în configuraţia finală dorită
- gradul de ordonare a elementelor configuraţiei curente comparativ cu
poziţia elementelor prezente în poziţia finală. Din experienţă rezultă ca ponderea
ordonării e mai importantă decât prima componentă. Coeficientul acestei variabile
variază în general intre [0, 4] fiind de obicei stabilit experimental.
- relaţia existentă între elementele poziţiei curente în cazul aplicaţiilor în care
regulile prezintă și componente de conflict (in sensul ca o piesa poate ataca sau nu
alta piesa – acest aspect se va discuta în contextul jocurilor strategice)

EXEMPLE
(1) Trei misionari si trei canibali ajung la un râu. Exista o barca de doua locuri cu
care se poate traversa râul. Daca numărul canibalilor este mai mare decât
numărul misionarilor pe unul din malurile râului, misionarii vor fi mâncați de
canibali. Cum pot trece toți râul fără ca misionarii sa fie mâncați? Starea
inițiala sistarea finala a acestei probleme sunt descrise in figura următoare.

158
Inteligenţă Artificială. Tehnici.

Unde
nmE  S   număr de misionari pe malul de EST in starea S
nmV  S   număr de misionari pe malul de VEST in starea S
ncE  S   număr de canibali pe malul de EST in starea S
ncV  S   număr de canibali pe malul de VEST in starea S
n  S   n  S   n  S   număr
E E
m
E
c de persoane pe malul de EST in starea S
nV  S   nmV  S   ncV  S   număr de persoane pe malul de VEST in starea S

Se propune o funcție de evaluare euristică de forma


f(S)=g(S)+h(S)
 Funcția g(S) este definita ca fiind egala cu numărul de tranziții de stări
efectuate din starea inițiala până in starea curentă S.
 Funcția h(s) este de forma

n E  S   1 dacă barca este pe malul de VEST si n E  S   0



h  S    nE  S  1 dacă barca este pe malul de EST si n E  S   0
 0 dacă n E  S   0

(2) Definiți funcții de evaluare euristică pentru problema N-puzzle altele decât
cea discutată anterior. Problema N-puzzle prezintă două variante 8-puzzle (o
tablă de joc de 3x3) și 15-puzzle (o tablă de joc de 4x4). Funcțiile de
evaluare euristică se vor discuta pentru varianta 15-puzzle.

a) Funcția euristică este de forma


h = Numărul de piese care nu sunt pe linia poziției acasă +
Numărul de piese care nu sunt pe coloana poziției acasă

Pentru exemplul din figură funcția euristică are valoare:


h = 2 piese care nu sunt pe linia poziției acasă +
1 piesă care nu este pe coloana poziției acasă
=3

159
Inteligenţă Artificială. Tehnici.

b) Funcția euristică este de forma


h = Numărul de piese care nu sunt în poziția corespunzătoare stării
fnale (nu se contorizează poziția liberă).

Pentru exemplul din figură funcția euristică are valoare:


h = 1+1 două mutări.

Exerciţiu
1. Construiţi o procedura de calcul a estimatorului euristic în problema celor 6
comutatoare.

2. Construiţi o procedura de calcul a estimatorului euristic în problema mutării


a 3 blocuri.

160
Inteligenţă Artificială. Tehnici.

14. Jocuri strategice


14.1 Definiţie caracteristici.
Tipurile de jocuri pe care le avem în vedere mai poartă denumirea de jocuri
informație perfecta, sau jocuri de doua persoane. Din categoria acestor jocuri fac parte
șahul, damele, moara, GO, etc.. Cu alte cuvinte, sunt luate în considerare acele jocuri în
care doi jucători fac mişcările alternativ, ambii având informaţie complectă despre situaţia
jocului. Se observă, în acest context, că definiţia exclude marea majoritate a jocurilor de
cărți. Jocul se termină, când se atinge o poziţie definite ca terminală de regulile jocului –
de ex. matul în șah. Aceleaşi reguli vor specifica şi care este rezultatul jocului când se
atinge aceasta poziţie terminala.
Un astfel de joc poate fi reprezentat printr-un arbore de tip joc în care nodurile se
identifică cu situațiile care apar în joc, iar arcele corespund mişcărilor pe care le
efectuează jucătorii. Într-un arbore te tip joc fiecare ramura (arc), va purta denumirea de
atac. Situația iniţiala din joc corespunde nodului rădăcina, iar frunzele acestuia vor fi
corespondentele poziţiilor terminale din joc.
În cele mai multe jocuri de acest tip rezultatul jocului poate fi : câștigă, pierde sau meci
nul. În cele ce urmează se vor lua în considerare numai jocurile cu doua rezultate:
câștigă şi pierde, deoarece cazurile de meci nul pot fi reduse la cele doua cazuri mai sus
menționate. Cei doi jucători, vor purta în continuare denumirea de noi şi ei. Noi poate
câștiga într-un nod care nu este terminal de tipul “Noi la mutare” dacă exista o mutare
autorizata care conduce la o poziţie câștigătoare. Pe de alta parte un nod care nu este
terminal de tipul “Ei la mutare” este câștigătoare pentru “Noi” dacă toate mişcările
autorizate din aceasta poziţie conduc la o poziţie câștigătoare. Aceste reguli au stat la
baza stabilirii tehnicilor de căutare în spatiile de configuraţii mari definite de jocurile de
doua persoane (de exemplu se ia în considerare un număr de aproximativ 30 mutări
autorizate din fiecare poziţie atunci arborele de joc pentru o adâncime de 40 mutări = 80
atacuri în jocul de șah prezintă un număr de 100040 poziţii terminale)
În cadrul acestor strategii se impune utilizarea unor funcţii de evaluare care au
rolul de a atribui o valoare pentru fiecare poziţie care apare în joc.

160
Inteligenţă Artificială. Tehnici.

Strategiile pe care le vom lua în considerare sunt alegerea celei mai bune mutări,
minimax şi alfa-beta.

14.2 Structura unui program de tip joc.


Structura este impusa de ceea ce se întâmplă când jucăm un joc.
(A) Începutul jocului înseamnă mutarea unei piese şi în general efectuarea primei
mişcări. O Data ce s-a stabilit cine joacă primul, jucătorul așteaptă sa facă
mutarea. După fiecare mutare poziţia de joc se actualizează. Ca urmare la nivelul
cel mai înalt, acest stil de efectuare a mutărilor apare de forma:

start (Joc, Rezultat) :-


initializeaza (Joc, Pozitie, Jucator),
afiseaza (Pozitia, Jucator),
play(Pozitia, Jucator, Rezultat).
În care:
- initializeaza determina Poziţia iniţiala de Joc şi specifică Jucătorul care începe
jocul;
- afiseaza are rolul de a afișa Poziţia iniţiala şi Jucătorul la start.
(B) Un joc este o secvenţă de transformări, unde fiecare transformare este
determinată de efectuarea unei mişcări de către jucător. Cel mai potrivit mod de a
reprezenta acest mod de joc, este de a utiliza o procedura recursivă play cu trei
argumente
a. Poziţie care specifică poziţia curenta de joc
b. Jucator care defineşte jucătorul la mutare
c. Rezultat care specifica rezultatul final al jocului.
Se recomanda ca alegerea mutării sa fie separată de efectuarea propriu zisa a
mutării. Ca urmare, vor apare doua predicate separate: alege_mutare şi muta care
implementează cele doua situații. În aceste condiţii procedura play prezintă
următorul aspect:
play( Pozitia, Jucator, Rezultat) :-
alege_mutarea( Pozitia, Jucator, Mutare),

161
Inteligenţă Artificială. Tehnici.

muta(Mutare, Pozitia, NouaPozitie),


urmatorul_jucator(Jucator, Urmatorul_Jucator),
play(NouaPozitie, Urmatorul_Jucator, Rezultat).
urmatorul_jucator(calculator, eu).
urmatorul_jucator(eu, calculator,).

14.3 Strategii de joc.


14.3.1 Alegerea celei mai bune mutări
Aceasta strategie sta la baza strategiilor de joc şi prezintă următorul principiu:

Găsește toate stările de joc posibile care pot fi obţinute într-o singură mutare.
Calculează valorile stărilor, utilizând o funcţie de evaluare. Alege mutarea care
conduce la poziţia cu scorul cel mai mare.

Pentru a implementa metoda, vom lua în considerare următoarele aspecte:

 Structura unei configuraţii (alternative) din spaţiul stărilor, este data de un obiect
compus, unde apar două elemente: configuraţia propriu zisa şi valoarea estimatorului
euristic corespunzătoare configuraţiei respective. Ca urmare vom avea:

Configuraţie de joc = p( Mutare, Valoare)


cu rolul de a asocia unei Mutări, Valoarea poziţiei la care conduce mutarea în cauză
definită de estimatorul utilizat.
 Se utilizează o procedura similară celei de tip generează şi testează, modificata prin
aceea că se propun toate configuraţiile posibile a fi generate din starea curenta, şi se
alege cea care prezintă cel mai bun estimator (alegerea este similara cu testarea din
tehnica generează şi testează) – implicit în acest mod se alege mutarea optimă de a fi
efectuată. În acest scop se utilizează următoarele predicate:
(a) valoare(Pozitie, Valoare) care implementează funcţia de evaluare ce
calculează o Valoare a unei Poziții curente de joc.
(b) muta(Mutare, Pozitie, Pozitie_Noua) cu rolul de a efectua o mutare din poziţia
curenta rezultatul fiind o poziţie noua de joc.

162
Inteligenţă Artificială. Tehnici.

(c) evalueaza_si_alege(Mutări, Pozitie, Record, Record1, Mutare_Aleasa) cu


rolul de a alege cea mai bună mutare din toate mutările posibile care decurg
dintr-o poziţie data. Operația presupune construirea pentru fiecare mutare a
perechii p(mutare, valoare) definite prin Record şi menținerea în atenție a
celei mai bune perechi găsite prin intermediul lui Record1
(d) mut(Pozitie, Mutare) este echivalentul procedurii succesor având rolul de a
determina o mutare posibila plecând de la o poziţie data.
(e) valoare(Pozitie, valoare) pe baza funcţiei de evaluare calculează valoarea
poziţiei curente.
(f) Strategia în acest context va avea următorul aspect:

alege_mutarea(Pozitia,computer,Mutare) :-
findall(M,
mut(Pozitia,M),
Mutări),
evalueaza_si_alege(Mutări, Pozitia, p( _, 1000), Mutare).

evalueaza_si_alege([Mutare|Mutări],Pozitia,Record,Mutare_aleasa) :-
muta(Mutare,Pozitia,Pozitia1),
valoare(Pozitia1,Valoare),
actualizez(Mutare,Valoare,Record,Record1),
evalueaza_si_alege(Mutări,Pozitia,Record1,Mutare_aleasa).

evalueaza_si_alege([ ], _ , p(Mutare, _ ), Mutare).

actualizez(_,Valoare,p(Mutare1,Valoare1),p(Mutare1,Valoare1)) :-
Valoare >= Valoare1.

actualizez(Mutare,Valoare,p( _, Valoare1),p(Mutare,Valoare)) :-
Valoare < Valoare1.

Comentarii
(a) Dacă “noi” sunt la mutare, procedura alege_mutare va conţine un dialog cu
utilizatorul în care se va solicită mutarea pe care partenerul umana
intenționează să o efectueze. Se observa în acest caz că “ei” reprezintă
“calculatorul” care specifică în contextul acestei strategii ce intenționează sa
mute.

163
Inteligenţă Artificială. Tehnici.

(b) Pentru a amorsa procedura evaluează_si_alege este necesara specificarea


unei valori iniţiale pentru valoarea acordata celei mai nefavorabile mutări. Vom
considera că cea mai nefavorabila prezintă valoarea -1000. Este evident că
aceasta se calibrează funcţie de jocul concret care este în discuţie.
(c) Procedurile mut şi valoare sunt specifice pentru fiecare joc. Vom exemplifica
strategia în contextul jocului NIM.

Aplicație
Jocul NIM (Marienbad-game) se defineşte astfel: Sunt prezente un număr de N rânduri
de câte M chibrit, aranjate în ordinea 1, 3, 5, 7, 9, … Regulile jocului sunt foarte simple:
cei doi jucători iau pe rând unul sau mai multe beţe de chibrit cu condiţia ca toate
chibritule luate să se afle prezente pe acelaşi rând. Este declarat câștigător al jocului cel
care ia ultimul chibrit.

O configuraţie de joc este data în figura


alăturată

164
Inteligenţă Artificială. Tehnici.

Un joc Nim care plecă de la o


configurație 3, 4, 5.
Jucătorul A câștigă

Unul dintre primele calculatoare


dedicate pentru jocuri,
numit Nimrod,
a fost conceput pentru
a juca jocul de Nim
și a fost expus
în 1951 la
expozitia de Calculatoare
Marea Britanie.

165
Inteligenţă Artificială. Tehnici.

Cea mai importanta descoperire cu privire la joc s-a făcut în 1901 de Charles
Bouton care a generalizat jocul pentru N linii cu orice număr de poziţii pe fiecare linie şi a
demonstrat prezenta unei strategii simple care da posibilitatea unui joc perfect. Acesta a
arătat că în cazul jocului apar doua combinații de linii protejate şi neprotejate. O mişcare,
este protejata dacă după ce jucătorul a făcut mişcarea sa garantează câștigul şi
neprotejata în caz contrar. Rezultă de aici că un joc inteligent şi rațional consta în aceea
că jucătorul care doreşte sa-şi asigure câștigul trebuie sa efectueze mutările de așa
natura, încât orice poziţie neprotejata pe care a preluat-o de la partenerul sau să o
transforme într-una protejata. Regula după care se determină dacă o poziţie este sau nu
protejata este: numerele de pe fiecare linie se scriu binar şi se face sau exclusiv pe
fiecare coloana. Dacă valoarea care se obţine, este 0 poziţia este protejata (sau para) şi
neprotejata în caz contrar. De exemple poziţia 1,3,5,7, este protejata deoarece avem

POZIŢIA POZIŢIA
1, 3, 5, 7 2, 6
1 10
11 110
101 100
111
000
Protejata Neprotejata

Prin urmare poate fi determinată o funcţie de evaluare exacta a poziţiei ceea ce


conduce la utilizarea optima a strategiei de tip cea mai buna mutare
Jocul NIM în acest context apare de forma:
/* Jocuri Strategice - NIM */
domains
stiva=mutare*
jucator=computer;noi
mutare=m(integer,integer)
record=p(mutare,integer)
lista_mutări=mutare*

predicates
start nim_sum(stiva,integer,integer)

166
Inteligenţă Artificială. Tehnici.

initializeaza(stiva,jucator) play(stiva,jucator)
sfirsit_joc(stiva,jucator) anunta(jucator)
muta(mutare,stiva,stiva) mutări(stiva,lista_mutări)
urmatorul_jucator(jucator,jucator) valoare(stiva,integer)
alege_mutarea(stiva,jucator,mutare) afiseaza(stiva,jucator)
actualizez(mutare,integer,record,record)
evalueaza_si_alege(lista_mutări,stiva,record,mutare)

goal
makewindow(3,7,0,"",0,0,25,80),
makewindow(2,7,7,"NOI la mutare",1,41,12,30),
makewindow(1,7,7,"Pozitie",1,1,12,40),
start.

clauses
start :-
initializeaza(Pozitia,Jucator),
afiseaza(Pozitia,Jucator),
play(Pozitia,Jucator).

initializeaza([m(1,1),m(2,3),m(3,5),m(4,7)], noi).

play(Pozitia,Jucator) :-
sfirsit_joc(Pozitia,Jucator),!,
anunta(Jucator).

play(Pozitia,Jucator) :-
alege_mutarea(Pozitia,Jucator,Mutare),
muta(Mutare, Pozitia, Pozitia1),
afiseaza(Pozitia1, Jucator),
urmatorul_jucator(Jucator, Jucator1), !,
play(Pozitia1, Jucator1).

alege_mutarea(_,noi,m(S,M)) :-
shiftwindow(2),
write("\n Mut din stiva ="),readint(S),
write("\n Un numar de pozitii = "),readint(M).

alege_mutarea(Pozitia,computer,Mutare) :-
mutări(Pozitia,Mutări),
evalueaza_si_alege(Mutări,Pozitia,p( _,1000),Mutare).

mutări([ ],[ ]).


mutări([m(N,S)|RS],[m(N,S)|Mutare]) :-
S1 is S -1, S1>0, mutări([ m(N,S1) | RS ], Mutare),!;
mutări(RS,Mutare).

167
Inteligenţă Artificială. Tehnici.

evalueaza_si_alege([Mutare|Mutări],Pozitia,Record,Mutare_aleasa) :-
muta(Mutare,Pozitia,Pozitia1),
valoare(Pozitia1,Valoare),
actualizez(Mutare, Valoare, Record, Record1),
evalueaza_si_alege(Mutări, Pozitia, Record1, Mutare_aleasa).

evalueaza_si_alege([ ], _ , p(Mutare, _ ), Mutare).

actualizez( _ ,Valoare, p(Mutare1,Valoare1),p(Mutare1,Valoare1)) :-


Valoare >= Valoare1.

actualizez(Mutare,Valoare,p(_,Valoare1),p(Mutare,Valoare)) :-
Valoare < Valoare1.

muta(m(K,M), [m(K1,N)|Ns], [m(K1,N)|Ns1] ) :-


K <> K1,muta(m(K,M),Ns,Ns1).
muta(m(K,M),[m(K,N)|Ns],[m(K,N1)|Ns]) :-
N>=M,N1=N-M.

afiseaza(Pozitia,_) :-
shiftwindow(1),
write(Pozitia),nl.

urmatorul_jucator(computer,noi). urmatorul_jucator(noi,computer).

sfirsit_joc([m(1,0),m(2,0),m(3,0),m(4,0)],_).

anunta(computer) :-
write("Eu am cistigat"),nl.
anunta(noi) :-
write("Computerul a cistigat"),nl.

valoare(Pozitia,Valoare) :- nim_sum(Pozitia,0,Valoare).

nim_sum([ ],S,S).
nim_sum([m(_,N)|Ns],Nb,Sum) :-
bitxor(N,Nb,Nb1),
nim_sum(Ns,Nb1,Sum).

Observații
1. O poziţie din configuraţia de joc se reprezintă sub forma unui obiect compus cu
aspectul
n(numar linie, numar poziţii din linie)

168
Inteligenţă Artificială. Tehnici.

Ca urmare configuraţia de joc de N linii cu un număr variabil de elemente pe linie se


va reprezenta printr-o lista cu elemente de acest tip. Deoarece numărul de elemente
care se iau dintr-o linie se pot reprezenta ca o poziţie din stiva se utilizează aceeaşi
structură pentru o mutare. O poziţie se va defini de asemenea ca un obiect compus
de forma
p(mutare, integer)
in care mutare este mutarea aplicata poziţiei curente iar valoare, valoarea funcţiei de
evaluare pentru noua poziţie care rezulta din mutarea efectuata.
2. Calculul funcţiei de evaluare a poziţiei se face cu predicatul
nim_sum(Pozitie, Manevra, Nim_Sum)
unde, Nim_sum este valoarea obţinută în urma evaluării configuraţiei de joc definite
de Poziţie. Se utilizează predicatul standard bitxor(Nr1, Nr2, XorNr1Nr2) care
efectuează un sau exclusiv între poziţiile binare a celor doua numere Nr1, Nr2.
3. Mutarea este realizată de
muta(Mutare, Pozitie, Noua_Pozitie)
Unde după identificarea liniei se face scăderea elementelor luate.
4. Pentru exemplul dat în programul anterior exemplificarea este făcută pentru
configuraţia prezentă în figura din acest paragraf cu observația că prima mutare
revine partenerului uman.
5. Se face de asemenea observaţia că fata de procedura clasică a celei mai bune
mutări s-a înlocuit
findall(M, mutare(Pozitia, M), Mutări)
Cu un predicat de forma
mutări(Pozitia, Mutări)
Deoarece acesta este mai uşor de construit în cazul acestui joc.

169
Inteligenţă Artificială. Tehnici.

14.3.2 Alegerea minimax


Pentru strategia celei mai bune mutări, discutată anterior, se observă că
alegerea mutării se face privind înainte o mutare. Dacă funcţia de evaluare a
poziţiei este corect aleasa atunci sensul este de a ne îndrepta spre un nod
terminal câștigător din arborele de joc, scorul reflectând de fiecare dată, care
poziţie conduce la un câștig şi care la o pierdere. Jocul devine interesant atunci
când nu este posibilă determinarea exacta a unei funcţii de evaluare. În acest caz
alegerea unei mutări pe baza strategiei de a anticipa înainte o mutare nu este cea
mai fericită. Rezultă imediat că este mai bine de anticipa câteva mutări înainte şi a
deduce din acestea cea mai buna mutare de efectuat
Strategia minimax poate fi rezumată astfel

Într-un joc strategic atunci când este confruntat cu câteva posibilități de


alegere, oponentul va alege cea mai buna mutare pentru el, ceea ce însemna
alegerea cea mai nefavorabila pentru mine. Ținta mea este deci de a face mutarea
care maximizează pentru mine valoarea poziţiei după ce oponentul face cea mai
buna mutare a sa, ceea ce înseamnă că se maximizează valoarea poziţiei pentru
el.

Precizări
(1) Trebuie făcuta distincţia dintre un “arbore de joc” şi un arbore de căutare. Un
arbore de căutare este în mod normal o parte a unui arbore de joc, mai exact
este partea care este explicit generate prin procesul de căutare. Este posibil ca
în acest caz poziţiile terminale ale arborelui de căutare sa conţină poziţii
terminale ale jocului.
(2) Funcţia de evaluare se transformă într-un estimator euristic, care evaluează
șansele de câștig din punctual de vedere al unuia dintre jucători. Astfel cea mai

170
Inteligenţă Artificială. Tehnici.

mare valoare va reprezenta șansa de a câștiga cea mai mare pentru un jucător
în timp ce cea mai mică valoare va defini şansa de a câștiga a oponentului.
(3) Deoarece unul din cei doi jucători va tinde sa obțină poziţia cu cea mai mare
valoare iar cel de al doilea poziţia cu valoarea cea mai mică, cei doi jucători pot
fi numiți MAX şi MIN. Ori de câte ori MAX este la mutare va alege mutarea
care maximizează valoarea obţinuta din evaluarea funcţiei euristice ce
caracterizează poziţia, iar în opoziţie MIN va alege mutarea care minimizează
valoarea
(4) Fiind date valorile de pe nivelul cel mai de jos al arborelui de căutare, strategia
minimax va determina valorile pentru toate celelalte poziţii din arborele de
căutare
Principiul este ilustrat de figura de mai jos cu următoarele observații:
- MAX poate fi identificat cu “Noi” (sau “Ei”) iar MIN cu “Ei” (sau “Noi”)
- Denumirea de valori statice provine din faptul că ele se obţin printr-o
evaluare statică a funcţiei de evaluare în contrast cu valorile care sunt
obţinute dinamic prin propagarea valorilor statice în sus în arbore.
- Valorile nodurilor interne pot fi calculate nivel cu nivel de jos în sus pana
când nodul rădăcina este atins. Valoarea ataşată nodului rădăcina este 4 şi în
concordanţă cu strategia minimax cea mai buna mutare a lui MAX aflat în
poziţia a este a – b. Cea mai buna mutare cu care poate replica MIN este b –
d s.a.m.d. Aceasta secvența de mişcări poarta denumirea de variațiunea
principala. Aceasta defineşte mişcările optimale minimax pentru ambele
tabere.

171
Inteligenţă Artificială. Tehnici.

Pentru a implementa metoda vom lua în considerare următoarele aspecte:

 Structura unei configuraţii (alternative) din spaţiul stărilor este data de un obiect
compus unde apar două elemente: configuraţia propriu zisa şi valoarea estimatorului
euristic corespunzătoare configuraţiei respective. Ca urmare vom avea:

Configuraţie de joc = p( Mutare, Valoare)


Cu rolul de a asocia unei Mutări, Valoarea poziţiei la care conduce mutarea în cauză
definită de estimatorul utilizat.
 Se utilizează o procedura similara celei de tip generează şi testează, modificata prin
aceea că se propun toate configuraţiile posibile a fi generate din starea curenta, şi se
alege cea care prezintă cel mai bun estimator (alegerea este similara cu testarea din
tehnica generează şi testează) – implicit în acest mod se alege mutarea optimă de a fi
efectuata. În acest scop se utilizează următoarele predicate:
(g) valoare(Pozitie, Valoare) care implementează funcţia de evaluare ce
calculează o Valoare a unei Pozitii curente de joc.
(h) muta(Mutare, Pozitie, Pozitie_Noua) cu rolul de a efectua o mutare din poziţia
curenta rezultatul fiind o poziţie noua de joc.
(i) evalueaza_si_alege(Mutări, Pozitie, Adancime, MaxMin, Record,
Mutare_Aleasa) cu rolul de a alege cea mai bună mutare din toate mutările
posibile care decurg dintr-o poziţie data. Operația presupune construirea
pentru fiecare mutare a perechii p(mutare, valoare) definite prin Record şi
menținerea în atenție a celei mai bune perechi găsite prin intermediul lui
Record1
(j) mut(Pozitie, M) este echivalentul procedurii succesor având rolul de a
determina o mutare posibila plecând de la o poziţie data.
(k) minmax(Adancime, Pozitie,MaxMin,Mutare,Valoare)
(l) Strategia în acest context va avea următorul aspect:

172
Inteligenţă Artificială. Tehnici.

evalueaza_si_alege([Mutare|RestMutări],Pozitie,Adancime,MaxMin,
Record,MutareSelectata):-
muta(Mutare,Pozitie,PozitieNoua),
minimax(Adancime, PozitieNoua,MaxMin,Mutare,Valoare),
actualizez(Mutare,Valoare,Record,Record1),
evalueaza_si_alege(Mutări,Pozitie,Adancime,MaxMin,Record1,MutareSelectata).

evalueaza_si_alege([ ] , _ , _ , _ , p(Mutare,_) , Mutare).

minimax(0,Pozitie,MaxMin,_,Valoare):-
estimeza_valoarea_pozitiei(Pozitie,ValoarePozitie),
Valoare = ValoarePozitie * MaxMin.

minimax(Adancime,Pozitie,MaxMin,Mutare,Valoare):-
Adancime >0,
findall(M,mut(Pozitie,M),ListaMutări),
Adancime1 = Adancime -1,
MinMax = -MaxMin,
evalueaza_si_alege(ListaMutări,Pozitie, Adancime1,MinMax,p(nil,-1000),Mutare).

actualizez(_,Val,p(Mutare1,Val1),p(Mutare1,Val1))) :-
Val<=Val1,!.
actualizez(Mutare,Val,p(_,Val1),p(Mutare,Val))) :-
Val>Val1,!.

173
Inteligenţă Artificială. Tehnici.

14.3.3 Alegerea alfa_beta


Strategia care implementează tehnica minimax explorează toate poziţii în arborele
de căutare, începând cu poziţiile terminale şi urcând în sus spre nodul de start nivel
cu nivel. În cursul acestui proces se evaluează toate poziţiile care sunt generate. Tot
acest efort de calcul poate fi optimizat prin aceea că nu toate aceste valori sunt
necesare de a fi calculate pentru a obţine o valoare corecta minimax pentru poziţia
curentă (rădăcina) şi deci o mutare corecta. Optimizarea se bazează pe următoare
idee. Presupunem că exista doua alternative de mutare din care trebuie sa alegem
una. Pentru a lua o decizie corectă nu este neapărat necesar sa cunoaștem valoarea
corecta a mutării pe care o lăsam de o parte, este suficient sa știm că valoarea sa
este inferioara (sau superioara) valorii mutării pe care am selectat-o pentru ca decizia
sa fie corecta. De exemplu se poate utiliza acest principiu pentru a reduce căutarea în
arborele analizat la căutarea minimax. Procesul de căutare se desfășoară utilizând
doua valori numite Alpha şi Beta pentru operații de taiere în arborele de joc.
Semnificația celor doua valori este:

- Alfa (α) este cea mai buna valoare pe care o poate alege MAX găsită pana

în momentul curent pentru orice alegere dea lungul căi de configuraţii,iar

Beta (β) este valoarea maximă pe care MAX o poate obţine. Cu alte cuvinte:

(α) Scorul minim pe care jucătorul MAX poate sa-l atingă garantat

(β ) Scorul maxim pe care jucătorul MAX spera sa-l poată obţine

împotriva adversarului.

- Din punct de vedere a lui MIN, Beta (β) este cea mai rea valoare pe care o

poate obţine pe care o poate alege MIN găsită pana în momentul curent

pentru orice alegere dea lungul căi de configuraţii, Beta (β)este cea mai

buna valoare pe care o poate alege MIN găsită pana în momentul curent

174
Inteligenţă Artificială. Tehnici.

pentru orice alegere dea lungul căi de configuraţii, iar Alpha (α) valoarea

maximă pe care MIN o poate obține. Cu alte cuvinte:

(α) Scorul cel mai bun pe care jucătorul MIN poate spera sa-l

atingă

(β ) Scorul cel mai rău pe care jucătorul MIN îl poată obţine

împotriva adversarului.
- cheia algoritmului Alpha-beta este găsirea unei mutări suficient de buna (nu
trebuie sa fie cea mai buna în mod necesar), pentru a lua o decizie corecta.
Astfel valoarea poziţiei curente (v) trebuie sa fie între Alpha şi Beta,

[ α =< v <= β].


Dacă valoarea depășește intervalul Alpha-Beta, este suficient sa știm că
poziţia nu este interesanta, fără a ști exact valoarea ei. Ceea ce trebuie sa
știm este numai dacă este în intervalul Alpha-Beta. Trebuie precizat în acest
punct că dacă găsim o valoare care nu este în intervalul [Alpha,Beta] putem
"sa tăiem" (sa nu luam în considerare următoarele mutări posibile) în
următoarele cazuri:
- dacă la mutare este MAX, iar valoarea găsită este mai mare decât Beta

V >= β

- dacă la mutare este MIN, iar valoarea găsită este mai mică decât Alpha

V <= α

- Alfa şi Beta se iniţializează pe ultimul şi penultimul nivel impus de


adâncimea de căutare funcţie de secvența în care se efectuează MIN
urmat de MAX sau MAX urmat de MIN. Datorită acestei basculări pentru
nivelele următoare celui ultim şi penultim din arborele de joc se
procedează la interschimbarea valorilor corespunzătoare lui

α cu – β
β cu - α
MIN devine practic jucătorul maximizat iar MAX jucătorul minimizat
Principiul de funcţionare a strategiei poate fi ilustrat astfel:

175
Inteligenţă Artificială. Tehnici.

Principiul Alpha_Beta
 α este cea mai buna mutare
pentru MAX pe ramura curentă.
 Dacă v este o mutare mai
slaba pentru MAX comparativ,
cu α, MAX nu o va atinge
niciodata, ramura care conduce
la ea fiind tăiată
 Se defineste similar β pentru
MIN
 Operatia de taiere poate reduce
cu 40 % spaţiul de căutare

Pentru a explica modul de funcţionare cât şi modul de stabilire iniţiala a acestora


vom lua în considerare următoarea secvența de trei exemple

(1)

Se generează toți succesorii pentru nodul cel mai din stânga şi se calculează
funcţia de evaluare., obţinându-se 5 respectiv 7. Deoarece MIN este la mutare se

alege 5 care se translatează în sus, Alpha va primi valoare 5 ( α=5). Se generează

176
Inteligenţă Artificială. Tehnici.

succesorii următorului nod şi se obţine prin evaluarea configuraţiilor 3 respectiv 9.


Deoarece MIN este la mutare se translatează în sus 3. Succesorul a cărei valoare

de poziţie este 9 se observa că nu mai este era necesar de a fi generat (3 <= α)

(2)

Se generează toți succesorii pentru nodul cel mai din stânga şi se calculează
funcţia de evaluare. obţinându-se 6 respectiv 3. Deoarece MAX este la mutare se

alege 6 care se translatează în sus, Beta va primi valoare 6, (β =6). Se generează

succesorii următorului nod şi se obţine prin evaluarea configuraţiilor valori 9


respectiv 2. Deoarece MAX este la mutare se translatează în sus 9. Succesorul a

cărei valoare de poziţie este 2 nu mai era necesar de a fi generat (9 ≥ β),


(deoarece pe următorul nivel oricum indiferent de valoarea nodului în discuție
deoarece MIN este la mutare se va alege 6), comparația din paranteză
reprezentând condiţia de taiere a acestei ramuri şi deci a unei ramuri în cazul
general
Exemple

(A)

177
Inteligenţă Artificială. Tehnici.

(B)

(C)
Pentru exemplul dat la strategia minimax, utilizarea lui Alpha_Beta conduce la
următoarele operații de tăiere în arborele de joc:

178
Inteligenţă Artificială. Tehnici.

Pentru a implementa metoda vom lua în considerare următoarele aspecte:

 Structura unei configuraţii (alternative) din spaţiul stărilor este data de un obiect
compus unde apar doua elemente: configuraţia propriu zisa şi valoarea estimatorului
euristic corespunzătoare configuraţiei respective. Ca urmare vom avea:

Configuraţie de joc = p( Mutare, Valoare)


Cu rolul de a asocia unei Mutări, Valoarea poziţiei la care conduce mutarea în cauză
definită de estimatorul utilizat.
 Se utilizează o procedura similara celei de tip generează şi testează, modificata prin
aceea că se propun toate configuraţiile posibile a fi generate din starea curenta, şi se
alege cea care prezintă cel mai bun estimator (alegerea este similară cu testarea din
tehnica generează şi testează) – implicit în acest mod se alege mutarea optimă de a fi
efectuata. În acest scop se utilizează următoarele predicate:
(a) valoare(Pozitie, Valoare) care implementează funcţia de evaluare ce
calculează o Valoare a unei Poziţii curente de joc.
(b) muta(Mutare, Pozitie, Pozitie_Noua) cu rolul de a efectua o mutare din poziţia
curentă, rezultatul fiind o poziţie nouă de joc.
(c) evalueaza_si_alege(Mutări, Pozitie, Adancime, Alfa, Beta, Record,
Mutare_Aleasa) cu rolul de a alege cea mai buna mutare din toate mutările
posibile care decurg dintr-o poziţie dată. Căutarea se face pe o Adancime dată
de atacuri. Operația presupune construirea pentru fiecare mutare a perechii
p(mutare, valoare) definite prin Record şi menținerea în atenție a celei mai
bune perechi găsite care se va reţine în final în Mutare_Aleasa atunci când se
ajunge la nivelul nodului de start din arbore.
(d) mut(Pozitie, M) este echivalentul procedurii succesor având rolul de a
determina o mutare posibila plecând de la o poziţie data.
(e) alfa_beta(Adancime, Pozitie, Alfa, Beta, Mutare, Valoare)
(f) Strategia în acest context va avea următorul aspect:

179
Inteligenţă Artificială. Tehnici.

evalueaza_si_alege([Mutare | Mutări], Pozitie, Adancime, Alfa, Beta, Record,


Mutare_selectata) :-
muta(Mutare, Pozitie, Pozitie1),
alfa_beta(Adancime, Pozitie, Alfa, Beta, Mutare, Valoare),
Valoare= - Valoare,
taie(Mutare, Valoare1, Adancime, Alfa, Beta, Mutări, Pozitie, Record,
Mutare_selectata).

evalueaza_si_alege([ ], _ , _ , _ , _ , Mutare, p(Mutare, _ )).

alfa_beta(0 , Pozitie, _ , _ , Mutare, Valoare) :-


valoare(Pozitie, Valoare).

alfa_beta(Adancime, Pozitie, Alfa, Beta, Mutare, Valoare) :-


findall(M, muta(Pozitie, M), Mutări),
Alfa1 = -Beta,
Beta1 = - Alfa,
Adancime1 = Adancime – 1,
evalueaza_si_alege(Mutări, Pozitie, Adancime1, Alfa1, Beta1, nil,
p(Mutare,Valoare)).

taie(Mutare, Val, _ , _, Beta, _ , _ , _ , p(Mutare,Valoare)) :-


Val > Beta.

taie(Mutare, Val, Adancime, Alfa, Beta, Mutări, Pozitie, Record, Mutare_selectata) :-


Alfa < Val, Val < Beta,
evalueaza_si_alege(Mutări, Pozitie, Adancime, Val, Beta, Mutare,
Mutare_selectata).

taie(Mutare, Val, Adancime, Alfa, Beta, Mutări, Pozitie, Record, Mutare_selectata) :-


Val < Alfa,
evalueaza_si_alege(Mutări, Pozitie, Adancime, Alfa, Beta, Record,
Mutare_selectata).

180
Inteligenţă Artificială. Tehnici.

14.4. Construirea funcției de estimare a poziției de joc

Ca și în cazul jocurilor de tip combinatorial și în cazul jocurilor strategice se


generează un spațiu al stărilor în care o stare reprezintă o poziție de joc. Deosebirea
constă în faptul că acest spațiu este generat de către ambii jucători care utilizează un
set de reguli de joc pe care le cunosc în contextul cunoașterii exacte a pozitiei de joc.
Aducem aminte că în cazul problemelor de tip combinatorial există un singur jucător
care prin faptul că încearcă să atingă o țintă definită de o stare a jocului în cauză cu
efectul generării spațiului de joc.
Clasificarea jocurilor strategice funcție de natura probabilistică sau nu a jocului cât
și a nivelului informațional la care au acces cei doi jucători este dată în tabelul de mai
jos:

Deterministic Șansă

Informație Dame, Șah, Table,


perfectă Go, Othello Monopoly

Informație Bridge, Poker,


imperfectă Scrabble

Indiferent de natura jocului în prezent funcția de evaluare a poziției de joc este dat
de o funcție de forma

181
Inteligenţă Artificială. Tehnici.

f (n)  w1F1 (n)  w2 F2 (n) K  wM FM (n)


în care Fi(n) definește o caracteristică a poziției de joc n ca de exemplu în cazul
jocului de șah poate reprezenta numărul de pioni, nebuni, ture etc., valoarea acestor
piese, evaluarea poziției pătratului pe care se află piesele respective sau a relațiilor
existente între piese de același tip sau tip diferit. Un aspect important care se ia în
considerare este cel relativ la faptul că se consideră că variabilele de tip Fi(n) sunt
independente (o variabilă nu este corelată cu altă variabilă). Componenta wi
reprezintă un factor de ponderare a aspectului definit de caracteristica Fi(n).

În cele ce urmează vom prezenta câteva jocuri și vom arăta modul în care se
construiește funcția de evaluare a poziției curente a jocului în cauză.

14.4.1 Jocul TICKTACKTOE


Forma cea mai simpla a jocului, răspândit la chinezi, greci şi romani (menționat de
Ovidiu în cartea a III din Ars amatoria) folosește o tabla alcătuită din 9 pătrate şi 6 fise ( 3
albe şi 3 negre). Cei doi jucători primesc câte 3 fise fiecare de aceeași culoare pe care
urmeze sa le așeze pe tabla una câte una, rând pe rând, pana le așează pe toate 6. Este
socotit câștigător acela care reușește sa așeze fisele sale fie într-un rând orizontal, într-
un rând vertical sau pe una din diagonale. Dacă toate cele 6 fise au fost așezate pe tabla
şi nici un grup de 3 nu se află în situaţiile menționate mai sus jocul ar trebui sa se termine
nedecis. El se continuă însa, jucătorul care urmează la mutare deplasând una din fisele
sale într-o căsuţă rămasă liberă numai în sus sau în jos, respectiv la dreapta sau la
stânga; sunt interzise mutările în diagonală. Din punct de vedere al teoriei jocurilor
ticktacktoe reprezintă un joc strategic cu doua persoane finit. El nu cuprinde nici un
element de noroc şi se joacă cu informaţie complecta, întrucât toate mutările sunt
cunoscute jucătorilor.

182
Inteligenţă Artificială. Tehnici.

Observații
(1) Deşi pare un joc simplu spaţiul stărilor este foarte mare. La prima mutare sunt 9
răspunsuri posibile, la cea de a doua 8 răspunsuri posibile, samd. Ca urmare arborele
de joc are 9 x 8 x 7 x …. ..x 2 x 1 = 9! Deci 15120 stări.
Faptul că apare un fenomen de simetrie ( de exemplu în prima mișcare pot pune în
colt, în mijloc, sau în centrul unei laturi) spaţiul stărilor are un număr mai mic de stări,
dar care este încă considerabil. De exemplu:

În acest moment spaţiul s-a redus la 12 x 7!


(2) Dacă primul jucător face prima mutare în centru câștigă sigur. Din acest
considerent deschiderea aceasta este interzisa.
(3) În cadrul acestui joc poate fi definit un estimator euristic al şansei de a câștiga.
Estimatorul pentru poziţiile iniţiale se calculează astfel:
- pentru jucătorul X șansele de a câștiga pentru configuraţiile din figura
următoare sunt: 3, 4, şi respectiv 2.
-

183
Inteligenţă Artificială. Tehnici.

- Sa presupunem că jucătorul cu piese O este la mutare. Pentru el șansa de a


câștiga este de forma:
H = G(O)- G(X)
unde G(O) sunt posibilitățile de a câștiga a lui O ia
G(X) sunt posibilitățile de a câștiga a lui X.
De exemplu:

Jucătorul O are trei şanse de câștig


pentru poziția curentă, în timp ce
jucătorul X are un numar de 5 şanse de
câștig din aceeași pozitie. Estimatorul
euristic H în aceasta situație are
valoarea -2

În continuare este reprezentat o


secvența din arborelui de joc cu valorile
estimatorilor euristici pentru jucătorul X

184
Inteligenţă Artificială. Tehnici.

Procedura de generare a succesorilor pentru acest joc apare de forma:


/*
Structura de date
piesa=o;x;l
element=p(piesa,integer,integer)
poziţie=[element,....]

Predicate
poziţie(pozitie,pozitie) mut(pozitie,piesa,pozitie)
apartine(element,poziţie) update(element,poziţie,poziţie)

Tinta

? P is [p(o,1,1),p(l,2,1),p(l,3,1),
p(l,1,2),p(l,2,2),p(l,3,2),
p(l,1,3),p(x,2,3),p(l,3,3)],
pozitie(P,P1),write(P1).

*/
pozitie(P,P1) :-
mut(P,x,Mutări),
apartine(Mutare,Mutări),
update(Mutare,P,P1).

mut([],_,[]).
mut([p(P,X,Y)|Rest],x,[p(x,X,Y)|Rx]) :-
P is l,
mut(Rest,x,Rx),!.
mut([_|Rest],x,Rx) :-
mut(Rest,x,Rx).

update(p(OX,X,Y),[p(P,X1,Y1)|Rp],[p(P,X1,Y1)|Rp1]) :-
X<>X1,
update(p(OX,X,Y),Rp,Rp1),!;
Y<>Y1,
update(p(OX,X,Y),Rp,Rp1),!.

185
Inteligenţă Artificială. Tehnici.

update(p(OX,X,Y),[p(l,X1,Y1)|Rp],[p(OX,X,Y)|Rp]) :-
X1 is X, Y1 is Y.

apartine(X,[X|_]).
apartine(X,[_|R]) :-
apartine(X,R).

14.4.2 Jocul Moara

A. Moara: Reguli de joc


Jocul se desfăşoară pe o tablă ca în figură. Intersecţiile reprezintă poziţii în care se pot
pune piese. Fiecare jucător are 9 piese.
1. În prima fază a jocului, cei doi jucători îşi aşează alternativ piesele pe tablă.

2. Apoi urmează faza 2, de mutare a pieselor. O piesă se poate muta doar pe poziţiile
vecine, adică poziţiile legate cu linie de poziţia curentă.

3. Când un jucător rămâne doar cu 3 piese pe tablă, trece în faza a treia a jocului. În
această fază, jucătorul are voie să mute oriunde, nu doar în poziţiile vecine.

 Când un jucător reuşeşte să-şi pună 3 piese în linie (poziţiile pieselor să fie legate
prin linii pe tabla de joc), se spune că acesta a închis o moară.
 Când un jucător închide o moară, are dreptul sa-i captureze celuilalt jucător o
piesă.
 Nu este voie să se captureze piese aflate în moară. Dacă un jucător închide o
moară şi toate piesele celuilalt jucător se află în câte o moară închisa, jocul se continuă,
nu se va scoate nici o piesă.
 Scopul final al jocului este capturarea pieselor adversarului până acesta rămâne
doar cu 2 piese.
 Un jucător câştigă atunci când adversarul rămâne cu numai 2 piese pe tablă sau
când toate piesele adversarului sunt blocate (când adversarul nu mai poate muta).

186
Inteligenţă Artificială. Tehnici.

B. Structura estimatorului
I. Este evident faptul că la calcularea punctajului unei configuraţii de joc trebuie privit
din prisma ambilor jucători. O configuraţie care este foarte bună pentru unul din
jucători, este, evident, nefavorabilă pentru celălalt jucător. Valoarea
estimatorului trebuie să indice în primul rând de partea cui este avantajul. De
aceea, în funcţiile de căutare în spaţiul soluţiilor, s-a recurs la notarea jucătorilor
cu Min şi Max. O valoare foarte mică (sau negativă, în funcţie de implementare)
este favorabilă pentru Min, iar una foarte mare (sau pozitivă) este favorabilă
pentru Max. Astfel, pentru fiecare jucător se va aplica aceeaşi funcţie de
evaluare a configuraţiei. Bineînţeles că pentru fiecare jucător în parte se va ţine
cont de piesele sale şi de relaţiile existente între piese. Calcularea punctajului
asociat unei configuraţii se face deci din două părţi. Să presupunem că primul
jucător este cel pentru care se doreşte găsirea unei mutări bune şi îl vom
considera pe acesta jucătorul Max. Prin urmare, se va calcula funcţia de
evaluare pentru Max (să o notăm EstimMax), iar apoi se calculează pentru Min
(notată EstimMin). Deoarece folosesc aceeaşi funcţie de estimare, este clar că
şi EstimMax şi EstimMin vor avea valori mari pozitive. Dacă EstimMax este mai
mare decât EstimMin, Max este în avantaj. Dacă EstimMin este mai mare,
atunci Min este în avntaj.

187
Inteligenţă Artificială. Tehnici.

Pentru ca estimatorul să arate clar de partea cui se află avantajul, valoare


estimatorului configuraţiei de joc se calculează ca diferenţa celor două valori.

ValEstimator = EstimMax – EstimMin


Prin urmare, dacă ValEstimator este pozitiv, Max este în avantaj, iar dacă este
negativ, Min este în avantaj.
II. De obicei, pentru un joc, estimatorul se compune dintr-o funcţie de evaluate
a configuraţiei de joc. Scorul obţinut trebuie să fie relevant pentru piesele şi
relaţiile (asociaţiile) ce există între piese. Dar, la majoritatea jocurilor, există
dependinţe mari ale valorilor pieselor şi asociaţiilor de piese şi momentul
jocului. Spre exemplu o relaţie poate fi importantă pentru începutul jocului,
dar spre sfârşit să nu mai aibă nici o valoare. De aceea, întotdeauna se vor
defini mai multe funcții de evaluare, fiecare va corespunde unei faze de joc
diferită. Moara se compune din 3 faze importante, prima de plasare a
pieselor, a doua de mutare (cu câte o poziţie) a pieselor şi a treia de mutare
fără restricţii (adică în orice poziţie liberă de pe tablă) când un jucător rămâne
cu 3 piese pe tabla. Modalitatea abordată în prezent este corela funcția de
estimare cu etapa de joc.. Acesta se va compune din 3 funcţii de estimare
(nu una singură), fiecare funcţie corespunzând unei etape a jocului.

III. În contextul jocului Moara sunt importante relațiile dintre piese.. Spre
exemplu o relaţie poate fi « «numărul de piese blocate », iar o altă relaţie
poate fi « moară închisă » reprezentând 3 piese ale aceluiaşi jucător aşezate
în linie. Ponderea unei relaţii este coeficientul sau punctajul asociat relaţiei
respective.
Prin urmare o funcţie de evaluare se stabileşte în doi paşi.
- În primul pas se aleg cu atenţie relaţiile considerate relevante pentru
jocul respectiv (pentru faza jocului) iar
- în pasul al doilea i se asociază un coeficient fiecărei relaţii.

Pentru jocul de moara, apar trei seturi de relaţii relevante, corespunzătoare


câte unei etape a jocului. Acestea sunt prezentate în de mai jos. Pe coloane
se găsesc relaţiile specifice fiecărei faze (etape) a jocului. Se poate observa

188
Inteligenţă Artificială. Tehnici.

că unele apar în două etape, unele apar chiar în toate trei etapele, dar vor
avea asociate punctaje (ponderi) diferite în funcţie de etapa jocului.

Relaţii faza 1 Relații faza 2 Relaţii faza 3


R1: Moară închisă R1: Moară închisă R1: Nr. de config.
R2: Numărul morilor R2: Numărul morilor cu 2 piese
R3: Numărul pieselor R3: Numărul pieselor R2: Nr. de config.
adverse blocate adverse blocate cu 3 piese
R4: Număr de piese (ale R4: Număr de piese (ale R3: Moară închisă
jucătorului curent) jucătorului curent) R4: Config. de
R5: Nr. de config. cu 2 piese R5: Moară deschisă câştig
R6: Nr. de config. cu 3 piese R6: Moară dublă
R7: Config. de câştig

Relaţiile la nivelul fazelor jocului

Relaţiile din tabel au următoarea semnificație


Moară închisă – la mutarea respectivă jucătorul închide o moară (poate lua
valoarea 0 pentru cazul în care nu s-a închis nici o moară sau 1 pentru cazul în care s-a
închis o moară)
Numărul de mori – numărul total de mori închise existente pe tabla de joc pentru un
jucător (de regulă între 0 şi 3)
Numărul pieselor blocate ale adversarului – câte piese ale adversarului sunt blocate
Numărul de piese – numărul total de piese pe care le are jucătorul curent pe tablă
(între 3 şi 9 deoarece la 2 piese jocul se încheie)
2 piese – numărul de configuraţii de 2 piese în linie şi a treia poziţie liberă
(posibilitate de închidere moara) sau 2 piese aşezate strategic pe linii perpendiculare.
Figura 14.1. (a) prezintă cele două cazuri, cu verde sunt piesele în linie şi cu portocaliu
structura din care se poate obţine la pasul următor o structură de trei piese (explicată în
continuare).
3 piese – 3 piese aşezate astfel încât să se permită închiderea a două mori (chiar
dacă adversarul blochează o poziţie, va rămâne o poziţie deschisă pentru închiderea
unei mori) – Figura 7.1.1 (b) prezintă două posibilităţi de aşezare a pieselor strategic, în
structură de trei.

189
Inteligenţă Artificială. Tehnici.

Moară deschisă – la acel pas se deschide moara; s-a dovedit important ca PC-ul să
ştie că este necesar să şi deschidă mori. Fără această relaţie, jucătorul calculator avea
tendinţa să nu mai deschidă o moară odată închisă, deoarece punctajul scădea. Nu este
în regulă să menţină morile închise deoarece astfel nu poate evolua. (relaţia poate lua
valoarea 0 – jucătorul nu a deschis o moară sau 1 – jucătorul a deschis o moară).
Moară dublă sau moară în vânt – două mori apropiate, iar o piesă poate face parte
din ambele astfel încât prin deschiderea unei mori, se închide cealaltă şi tot aşa. În
exemplul din Figura 7.1.1 (c), verdele are o structură de moară dublă.

(a) – structuri de 2 piese (b) – structuri de 3 piese

Figura 14.1. – Relaţii în jocul


moara

(c) – moară dublă (piesele verzi)

Configuraţie de câştig – jucătorul care primeşte punctajul asociat acestei relaţii este
câştigător; poate lua valoarea 0 sau 1.
Spre exemplu configuraţia de 3 piese (Number of 3 pieces configuraţion) apare şi în
faza întâi şi în faza a treia dar cel mai probabil vor avea asociate punctaje diferite.

190
Inteligenţă Artificială. Tehnici.

Relaţia Configuraţie de câştig reprezintă posibilitatea încheierii jocului, de aceea va


avea asociat un punctaj considerabil mai mare. Dacă punctajul asociat unei mori închise
este de ordinul zecilor, punctajul pentru configuraţia de final va fi în jur de 1000. Este
indicată folosirea unui punctaj cât mai mare pentru configuraţia de final de joc cu câştig,
deoarece fiecare jucător se îndreaptă spre un punctaj cât mai mare găsit în arborele de
configuraţii. Dacă configuraţiei de final nu i se asociază un punctaj suficient de mare,
jucătorul calculator poate rata posibilitatea de câştig mergând pe altă ramură care îi
indică un punctaj mai mare. Dacă pentru o moară se asociază spre exemplu 30 puncte
iar pentru câştig 60, jucătorul poate alege să meargă pe un drum pe care îşi face mai
multe mori în loc să meargă pe o ramură pe care nu-şi face mori dar spre exemplu poate
bloca piesele oponentului şi astfel să ajungă în configuraţia de câştig. În schimb dacă
pentru câştig avem asociat punctajul 1000, nici o altă configuraţie care nu este de câştig
nu va putea avea un punctaj aşa de ridicat. Astfel se diferenţiază clar scopul jocului,
acela de a atinge o configuraţie de victorie.
În tabel avem în total 17 relaţii, dar unele sunt comune pentru două sau chiar pentru
toate trei fazele. La generarea unei configuraţii următoare se vor calcula valorile pentru
toate relaţiile distincte, indiferent de fază. Alegerea fazei intervine doar în momentul
calculării estimatorului de joc. Avem în total 9 relaţii distincte: Moară închisă, Numărul
morilor, Numărul pieselor adverse blocate, Număr de piese (ale jucătorului curent), Nr. de
config. cu 2 piese, Nr. de config. cu 3 piese, Moară deschisă, Moară dublă, Config. de
câştig.

191
Inteligenţă Artificială. Tehnici.

Figura 14.1.2 Exemplu de relaţii existente.

Pentru fiecare jucător în parte este necesar să se cunoască ce relaţii există pe tabla
de joc, de aceea pentru o configuraţie se vor salva două seturi de variabile
corespunzătoare relaţiilor. Să luăm spre exemplu cazul din figura 14.1.2.
Pentru jucătorul verde vom avea valorile relaţiilor:
Numărul morilor = 1
Numărul pieselor adverse blocate = 1 (portocalie încercuită cu verde)
Nr. de config. cu 3 piese = 1
Număr de piese = 6 (ale jucătorului verde)
Restul relaţiilor pentru jucătorul verde vor avea valoarea 0.
Pentru jucătorul portocaliu vom avea valorile relaţiilor:
Numărul morilor = 1
Nr. de config. cu 2 piese = 1 (cele două piese în linie unde se poate închide o
moară prin plasarea unei piese)
Număr de piese = 5 (ale jucătorului portocaliu)
Restul relaţiilor pentru jucătorul portocaliu vor avea valoarea 0.

Figura 14.1.3 prezintă structura estimatorului, cu cele 3 funcţii de evaluare


obţinute ca sumă ponderată a relaţiilor prezentate în tabelul de mai înainte.

192
Inteligenţă Artificială. Tehnici.

Figura 14.1.3 – Structura estimatorului


În figură au fost notate cu R relaţiile, iar ponderile (coeficienţii) cu Cf. Relaţiile s-au
ales ca fiind asociaţii de piese reprezentative pentru joc. La alegerea lor se ține cont de
cunoştinţele jucătorilor experimentaţi de Moară. În alte cuvinte aceste relaţii reprezintă
pattern-uri după care se va conduce şi un jucător uman experimentat. Coeficienţii trebuie
aleşi cu mare atenţie, de asemenea pe baza experienţei jucătorilor umani.
IV. Trebuie ținut cont de modul de joc. Modurile clasice sunt
a) defensiv şi
b) ofensiv,
respectiv apărare şi atac. Sunt două abordări diferite întâlnite la jucătorii
umani. La jocul Moara, o abordare defensivă ar însemna să încerci să pierzi
cât mai puţine piese şi să încerci învingerea adversarului prin blocarea
pieselor acestuia. Şi un jucător defensiv va încerca să închidă mori, însă
probabil nu cu preţul pierderii pieselor. O abordare ofensivă implică
încercarea de a construi cât mai multe mori, structura de moară în vânt şi un
jucător ofensiv nu va încerca în mod deosebit să-şi protejeze piesele ci mai
degrabă să captureze cât mai multe piese.
La nivelul estimatorului nostru de joc, aceste abordări subiective se traduc
tocmai la nivelul coeficienţilor. În timp ce relaţiile reprezintă pattern-uri
valabile pentru toţi jucătorii, coeficienții sunt cei care diferenţiază modurile de
joc.

193
Inteligenţă Artificială. Tehnici.

Toţi jucătorii vor căuta asociaţii de genul blocarea pieselor adversarului sau
închiderea unei mori, însă importanța acestora diferă în ochii jucătorilor.
Importanța se traduce prin coeficienţi. Prin urmare, modul de joc al
calculatorului va fi influenţat în mod definitiv de aceşti coeficienţi.

În prima fază a jocului, se pot defini în mod logic două moduri de joc: ofensiv şi
defensiv, prin atribuirea de coeficienţi relaţiilor. Aceasta se realizează prin mai multe
încercări şi ajustări. Se plecă de la ideea că fiecare mod de joc se axează pe 2-3 relaţii
pe care le vede importante şi cărora li se atribuie un punctaj mare, iar celelalte relaţii au
asociat un punctaj mai mic, uneori chiar şi 0 (neutralizarea unei relaţii – nu se mai ţine
cont de ea). Pentru modul defensiv, se atribuie punctaj mare relaţiilor: număr total de
piese, piese oponent blocate şi moară închisă. Pentru modul ofensiv se atribuie punctaj
mare relaţiilor: moară închisă, moară dublă. O altă diferenţiere se face la nivelul
configuraţiei câştigătoare. Pentru modul defensiv se încearcă câştigarea meciului din
faza a doua (înainte ca jucătorul să rămână doar cu 3 piese pe tablă), în timp ce jucătorul
ofensiv cel mai probabil va ajunge în faza a treia, datorită modului de joc. Distincţia se
face astfel: relaţia de configuraţie câştigătoare în modul defensiv (de exemplu) are
asociată ponderea 1200 în faza doi şi 1000 în faza trei; în modul ofensiv are asociată
ponderea 1000 în faza doi şi 1200 în faza trei.

14.4.3 Jocul Șah

Una din cele mai utilizate funcții evaluare a poziției curente de joc este de forma
F(n) = c1 * valoare piese + c2 * mobilitate + c3 * siguranță rege +
c4 * control centru tablă + ...
de exemplu
F (n) = 9(Q-Q') + 5(R-R') + 3(B-B'+N-N') + (P-P') - 0.5(D-D'+S-S'+I-I') + 0.1(M-M') + ...
în care
 Q, R, B, N, P sunt numărul (sau valoarea ) pentru ture, nebuni, cai, și pioni de pe
tabla de șah. Cu Q se notează numărul de regine . Piesele au culoare albă Q, R,
B, N, P respectiv culoare neagră Q', R', B', N', P'. În prezent cea mai utilizată
contorizare a valorii pieselor este dată în continuare

194
Inteligenţă Artificială. Tehnici.

 D, S, I reprezintă numărul de pioni dublați , unul în spatele celuilalt , respectiv


izolați. În imagine apare conceptul de pion dublat.

 M reprezintă mobilitatea pieselor albe (măsurată de exemplu în numărul legal de


mutări pentru piesele albe).

 Un alt aspect care trebuie luat în considerare este legat de valoarea de schimb a
pieselor. Această valoare de schimb apare în momentul în care se iau piese (o
piesă sau se sacrifică 2 sau mai multe piese minore pentru eliminarea unei piese
de valoare mai mare de pe tablă) În această situație este necesar de cuantizat
dacă poziția care se obține în perspectivă ( după două sau mai multe mutări ) este
mai bună decât ca din momentul începerii schimbului ( mai bun însemnând o
funcție de evaluare a poziției de joc mai mare valoric).

Remarcă

195
Inteligenţă Artificială. Tehnici.

În10/5/1997, la New York în cadrul unui meci de 6 partide între (programul


DeepBlue) – Kasparov scorul a fost de 2 – 1 pentru DeepBlue ( dupa 3 partide campionul
mondial Kasparov a abandonat). În sistemul de evaluare a unui jucător de şah se
utilizează pentru a cuantifica forţa de joc unitatea de măsura numită punct Elo
Astfel:
– Categoria I: 500 puncte Elo
– Maestru International: 2.200 puncte Elo
– Campion mondial: 2.800 puncte Elo
– Deep Blue 3000 puncte Elo

S-a utilizat un calculator cu 32 procesoare paralele care a permis evaluarea a 200


milioane de pozitii pe secunda utilizând o strategie Alpha_Beta pana la o adâncime de
joc de 40 mutări pe direcții privilegiate.

196
With alpha-beta pruning (view
presentation for animation)
Minimax with Alpha-Beta pruning

No more branches,
so this is the value
alpha=3 3
Max
My turn
0< 2<
Min beta=3 3
alpha,
so
alpha,
so
prune prune
Opp turn
5>
beta,
Max 3 so
prune
0 2
My turn
Min 2 3 5 0 2 1
Minimax
with
Alpha Beta Pruning
Nod MAX. Obiectivul unui nod MAX este de a maximiza valoarea
subarborelui aferent. Pentru a face acest lucru, un nod MAX
alege subarborele cu cea mai mare valoare care devine valoarea
nodului MAX.

Nod MIN. Scopul unui nod MIN este de a minimiza valoarea


subarborelui înrădăcinat în acel nod. Pentru a face acest
lucru, un nod MIN alege subarborele cu cea mai mică valoare
care devine valoarea nodului MIN.

Denumirea de Alfa-beta pruning provine de la două limite care sunt


transmise în timpul calculului. Aceste limite restricționează setul de
soluții fiind definite de porțiunea din arborele de căutare, care a fost
deja văzut.

β reprezintă valoarea minimă a limitei superioare pentru soluțiile posibile


α reprezintă valoarea maximă a limitei inferioare pentru soluțiile posibile
Astfel un nod N poate fi luat în considerare ca o posibilă stare pe drumul spre
starea de tip soluție câștigătoare numai dacă

 N

unde N este estimarea valorii curente a nodului

Vizual acest interval apare de forma


Pe măsură ce se avansează în spațiul stărilor se pot pune restricții relative
la gama de soluții posibile bazate pe noduri

min (care se poate modifica o limită superioară), și


max (care poate modifica o limită inferioară).

Cu alte cuvinte
(α) Scorul minim pe care jucătorul MAX poate să-l atingă garantat
(β ) Scorul maxim pe care jucătorul MAX spera să-l poată obţine împotriva
adversarului.

(α) Scorul maxim pe care jucătorul MIN poate spera să-l atingă
(β ) Scorul minim pe care jucătorul MIN spera să-l poată obţine împotriva
adversarului.
Cheia algoritmului Alpha-beta este găsirea unei mutări suficient de bună (nu
trebuie sa fie cea mai buna în mod necesar), pentru a lua o decizie corecta.
Astfel valoarea poziţiei curente (v) trebuie sa fie între Alpha şi Beta, [ α =< v <=
β].

Dacă valoarea depășește intervalul Alpha-Beta, este suficient sa știm că poziţia nu


este interesanta, fără a ști exact valoarea ei. Ceea ce trebuie sa știm este numai
dacă este în intervalul Alpha-Beta. Trebuie precizat în acest punct că dacă găsim o
valoare care nu este în intervalul [Alpha,Beta] putem "să tăiem" (să nu luăm în
considerare următoarele mutări posibile) în următoarele cazuri:

- dacă la mutare este MAX, iar valoarea găsită este mai mare decât Beta
V >= β
- dacă la mutare este MIN, iar valoarea găsită este mai mică decât Alpha
V <= α
- după modifcarea valorilor α , β condiția de tăiere care cumulează cele două
cazuri de mai sus se va restrânge la α >= β
- Alfa şi Beta se iniţializează pe ultimul şi penultimul nivel impus de adâncimea de
căutare funcţie de secvența în care se efectuează MIN urmat de MAX sau MAX
urmat de MIN. Datorită acestei basculări pentru nivelele următoare celui ultim şi
penultim din arborele de joc se procedează la interschimbarea valorilor
corespunzătoare lui
α cu – β
β cu - α
MIN devine practic jucătorul maximizat iar MAX jucătorul minimizat

Principiul de funcţionare a strategiei poate fi ilustrat astfel:


Inteligenţă Artificială. Tehnici.

14. Jocuri strategice


14.1 Definiţie caracteristici.
Tipurile de jocuri pe care le avem în vedere mai poartă denumirea de jocuri
informație perfecta, sau jocuri de doua persoane. Din categoria acestor jocuri fac parte
șahul, damele, moara, GO, etc.. Cu alte cuvinte, sunt luate în considerare acele jocuri în
care doi jucători fac mişcările alternativ, ambii având informaţie complectă despre situaţia
jocului. Se observă, în acest context, că definiţia exclude marea majoritate a jocurilor de
cărți. Jocul se termină, când se atinge o poziţie definite ca terminală de regulile jocului –
de ex. matul în șah. Aceleaşi reguli vor specifica şi care este rezultatul jocului când se
atinge aceasta poziţie terminala.
Un astfel de joc poate fi reprezentat printr-un arbore de tip joc în care nodurile se
identifică cu situațiile care apar în joc, iar arcele corespund mişcărilor pe care le
efectuează jucătorii. Într-un arbore te tip joc fiecare ramura (arc), va purta denumirea de
atac. Situația iniţiala din joc corespunde nodului rădăcina, iar frunzele acestuia vor fi
corespondentele poziţiilor terminale din joc.
În cele mai multe jocuri de acest tip rezultatul jocului poate fi : câștigă, pierde sau meci
nul. În cele ce urmează se vor lua în considerare numai jocurile cu doua rezultate:
câștigă şi pierde, deoarece cazurile de meci nul pot fi reduse la cele doua cazuri mai sus
menționate. Cei doi jucători, vor purta în continuare denumirea de noi şi ei. Noi poate
câștiga într-un nod care nu este terminal de tipul “Noi la mutare” dacă exista o mutare
autorizata care conduce la o poziţie câștigătoare. Pe de alta parte un nod care nu este
terminal de tipul “Ei la mutare” este câștigătoare pentru “Noi” dacă toate mişcările
autorizate din aceasta poziţie conduc la o poziţie câștigătoare. Aceste reguli au stat la
baza stabilirii tehnicilor de căutare în spatiile de configuraţii mari definite de jocurile de
doua persoane (de exemplu se ia în considerare un număr de aproximativ 30 mutări
autorizate din fiecare poziţie atunci arborele de joc pentru o adâncime de 40 mutări = 80
atacuri în jocul de șah prezintă un număr de 100040 poziţii terminale)
În cadrul acestor strategii se impune utilizarea unor funcţii de evaluare care au
rolul de a atribui o valoare pentru fiecare poziţie care apare în joc.

160
Inteligenţă Artificială. Tehnici.

Strategiile pe care le vom lua în considerare sunt alegerea celei mai bune mutări,
minimax şi alfa-beta.

14.2 Structura unui program de tip joc.


Structura este impusa de ceea ce se întâmplă când jucăm un joc.
(A) Începutul jocului înseamnă mutarea unei piese şi în general efectuarea primei
mişcări. O Data ce s-a stabilit cine joacă primul, jucătorul așteaptă sa facă
mutarea. După fiecare mutare poziţia de joc se actualizează. Ca urmare la nivelul
cel mai înalt, acest stil de efectuare a mutărilor apare de forma:

start (Joc, Rezultat) :-


initializeaza (Joc, Pozitie, Jucator),
afiseaza (Pozitia, Jucator),
play(Pozitia, Jucator, Rezultat).
În care:
- initializeaza determina Poziţia iniţiala de Joc şi specifică Jucătorul care începe
jocul;
- afiseaza are rolul de a afișa Poziţia iniţiala şi Jucătorul la start.
(B) Un joc este o secvenţă de transformări, unde fiecare transformare este
determinată de efectuarea unei mişcări de către jucător. Cel mai potrivit mod de a
reprezenta acest mod de joc, este de a utiliza o procedura recursivă play cu trei
argumente
a. Poziţie care specifică poziţia curenta de joc
b. Jucator care defineşte jucătorul la mutare
c. Rezultat care specifica rezultatul final al jocului.
Se recomanda ca alegerea mutării sa fie separată de efectuarea propriu zisa a
mutării. Ca urmare, vor apare doua predicate separate: alege_mutare şi muta care
implementează cele doua situații. În aceste condiţii procedura play prezintă
următorul aspect:
play( Pozitia, Jucator, Rezultat) :-
alege_mutarea( Pozitia, Jucator, Mutare),

161
Inteligenţă Artificială. Tehnici.

muta(Mutare, Pozitia, NouaPozitie),


urmatorul_jucator(Jucator, Urmatorul_Jucator),
play(NouaPozitie, Urmatorul_Jucator, Rezultat).
urmatorul_jucator(calculator, eu).
urmatorul_jucator(eu, calculator,).

14.3 Strategii de joc.


14.3.1 Alegerea celei mai bune mutări
Aceasta strategie sta la baza strategiilor de joc şi prezintă următorul principiu:

Găsește toate stările de joc posibile care pot fi obţinute într-o singură mutare.
Calculează valorile stărilor, utilizând o funcţie de evaluare. Alege mutarea care
conduce la poziţia cu scorul cel mai mare.

Pentru a implementa metoda, vom lua în considerare următoarele aspecte:

 Structura unei configuraţii (alternative) din spaţiul stărilor, este data de un obiect
compus, unde apar două elemente: configuraţia propriu zisa şi valoarea estimatorului
euristic corespunzătoare configuraţiei respective. Ca urmare vom avea:

Configuraţie de joc = p( Mutare, Valoare)


cu rolul de a asocia unei Mutări, Valoarea poziţiei la care conduce mutarea în cauză
definită de estimatorul utilizat.
 Se utilizează o procedura similară celei de tip generează şi testează, modificata prin
aceea că se propun toate configuraţiile posibile a fi generate din starea curenta, şi se
alege cea care prezintă cel mai bun estimator (alegerea este similara cu testarea din
tehnica generează şi testează) – implicit în acest mod se alege mutarea optimă de a fi
efectuată. În acest scop se utilizează următoarele predicate:
(a) valoare(Pozitie, Valoare) care implementează funcţia de evaluare ce
calculează o Valoare a unei Poziții curente de joc.
(b) muta(Mutare, Pozitie, Pozitie_Noua) cu rolul de a efectua o mutare din poziţia
curenta rezultatul fiind o poziţie noua de joc.

162
Inteligenţă Artificială. Tehnici.

(c) evalueaza_si_alege(Mutări, Pozitie, Record, Record1, Mutare_Aleasa) cu


rolul de a alege cea mai bună mutare din toate mutările posibile care decurg
dintr-o poziţie data. Operația presupune construirea pentru fiecare mutare a
perechii p(mutare, valoare) definite prin Record şi menținerea în atenție a
celei mai bune perechi găsite prin intermediul lui Record1
(d) mut(Pozitie, Mutare) este echivalentul procedurii succesor având rolul de a
determina o mutare posibila plecând de la o poziţie data.
(e) valoare(Pozitie, valoare) pe baza funcţiei de evaluare calculează valoarea
poziţiei curente.
(f) Strategia în acest context va avea următorul aspect:

alege_mutarea(Pozitia,computer,Mutare) :-
findall(M,
mut(Pozitia,M),
Mutări),
evalueaza_si_alege(Mutări, Pozitia, p( _, 1000), Mutare).

evalueaza_si_alege([Mutare|Mutări],Pozitia,Record,Mutare_aleasa) :-
muta(Mutare,Pozitia,Pozitia1),
valoare(Pozitia1,Valoare),
actualizez(Mutare,Valoare,Record,Record1),
evalueaza_si_alege(Mutări,Pozitia,Record1,Mutare_aleasa).

evalueaza_si_alege([ ], _ , p(Mutare, _ ), Mutare).

actualizez(_,Valoare,p(Mutare1,Valoare1),p(Mutare1,Valoare1)) :-
Valoare >= Valoare1.

actualizez(Mutare,Valoare,p( _, Valoare1),p(Mutare,Valoare)) :-
Valoare < Valoare1.

Comentarii
(a) Dacă “noi” sunt la mutare, procedura alege_mutare va conţine un dialog cu
utilizatorul în care se va solicită mutarea pe care partenerul umana
intenționează să o efectueze. Se observa în acest caz că “ei” reprezintă
“calculatorul” care specifică în contextul acestei strategii ce intenționează sa
mute.

163
Inteligenţă Artificială. Tehnici.

(b) Pentru a amorsa procedura evaluează_si_alege este necesara specificarea


unei valori iniţiale pentru valoarea acordata celei mai nefavorabile mutări. Vom
considera că cea mai nefavorabila prezintă valoarea -1000. Este evident că
aceasta se calibrează funcţie de jocul concret care este în discuţie.
(c) Procedurile mut şi valoare sunt specifice pentru fiecare joc. Vom exemplifica
strategia în contextul jocului NIM.

Aplicație
Jocul NIM (Marienbad-game) se defineşte astfel: Sunt prezente un număr de N rânduri
de câte M chibrit, aranjate în ordinea 1, 3, 5, 7, 9, … Regulile jocului sunt foarte simple:
cei doi jucători iau pe rând unul sau mai multe beţe de chibrit cu condiţia ca toate
chibritule luate să se afle prezente pe acelaşi rând. Este declarat câștigător al jocului cel
care ia ultimul chibrit.

O configuraţie de joc este data în figura


alăturată

164
Inteligenţă Artificială. Tehnici.

Un joc Nim care plecă de la o


configurație 3, 4, 5.
Jucătorul A câștigă

Unul dintre primele calculatoare


dedicate pentru jocuri,
numit Nimrod,
a fost conceput pentru
a juca jocul de Nim
și a fost expus
în 1951 la
expozitia de Calculatoare
Marea Britanie.

165
Inteligenţă Artificială. Tehnici.

Cea mai importanta descoperire cu privire la joc s-a făcut în 1901 de Charles
Bouton care a generalizat jocul pentru N linii cu orice număr de poziţii pe fiecare linie şi a
demonstrat prezenta unei strategii simple care da posibilitatea unui joc perfect. Acesta a
arătat că în cazul jocului apar doua combinații de linii protejate şi neprotejate. O mişcare,
este protejata dacă după ce jucătorul a făcut mişcarea sa garantează câștigul şi
neprotejata în caz contrar. Rezultă de aici că un joc inteligent şi rațional consta în aceea
că jucătorul care doreşte sa-şi asigure câștigul trebuie sa efectueze mutările de așa
natura, încât orice poziţie neprotejata pe care a preluat-o de la partenerul sau să o
transforme într-una protejata. Regula după care se determină dacă o poziţie este sau nu
protejata este: numerele de pe fiecare linie se scriu binar şi se face sau exclusiv pe
fiecare coloana. Dacă valoarea care se obţine, este 0 poziţia este protejata (sau para) şi
neprotejata în caz contrar. De exemple poziţia 1,3,5,7, este protejata deoarece avem

POZIŢIA POZIŢIA
1, 3, 5, 7 2, 6
1 10
11 110
101 100
111
000
Protejata Neprotejata

Prin urmare poate fi determinată o funcţie de evaluare exacta a poziţiei ceea ce


conduce la utilizarea optima a strategiei de tip cea mai buna mutare
Jocul NIM în acest context apare de forma:
/* Jocuri Strategice - NIM */
domains
stiva=mutare*
jucator=computer;noi
mutare=m(integer,integer)
record=p(mutare,integer)
lista_mutări=mutare*

predicates
start nim_sum(stiva,integer,integer)

166
Inteligenţă Artificială. Tehnici.

initializeaza(stiva,jucator) play(stiva,jucator)
sfirsit_joc(stiva,jucator) anunta(jucator)
muta(mutare,stiva,stiva) mutări(stiva,lista_mutări)
urmatorul_jucator(jucator,jucator) valoare(stiva,integer)
alege_mutarea(stiva,jucator,mutare) afiseaza(stiva,jucator)
actualizez(mutare,integer,record,record)
evalueaza_si_alege(lista_mutări,stiva,record,mutare)

goal
makewindow(3,7,0,"",0,0,25,80),
makewindow(2,7,7,"NOI la mutare",1,41,12,30),
makewindow(1,7,7,"Pozitie",1,1,12,40),
start.

clauses
start :-
initializeaza(Pozitia,Jucator),
afiseaza(Pozitia,Jucator),
play(Pozitia,Jucator).

initializeaza([m(1,1),m(2,3),m(3,5),m(4,7)], noi).

play(Pozitia,Jucator) :-
sfirsit_joc(Pozitia,Jucator),!,
anunta(Jucator).

play(Pozitia,Jucator) :-
alege_mutarea(Pozitia,Jucator,Mutare),
muta(Mutare, Pozitia, Pozitia1),
afiseaza(Pozitia1, Jucator),
urmatorul_jucator(Jucator, Jucator1), !,
play(Pozitia1, Jucator1).

alege_mutarea(_,noi,m(S,M)) :-
shiftwindow(2),
write("\n Mut din stiva ="),readint(S),
write("\n Un numar de pozitii = "),readint(M).

alege_mutarea(Pozitia,computer,Mutare) :-
mutări(Pozitia,Mutări),
evalueaza_si_alege(Mutări,Pozitia,p( _,1000),Mutare).

mutări([ ],[ ]).


mutări([m(N,S)|RS],[m(N,S)|Mutare]) :-
S1 is S -1, S1>0, mutări([ m(N,S1) | RS ], Mutare),!;
mutări(RS,Mutare).

167
Inteligenţă Artificială. Tehnici.

evalueaza_si_alege([Mutare|Mutări],Pozitia,Record,Mutare_aleasa) :-
muta(Mutare,Pozitia,Pozitia1),
valoare(Pozitia1,Valoare),
actualizez(Mutare, Valoare, Record, Record1),
evalueaza_si_alege(Mutări, Pozitia, Record1, Mutare_aleasa).

evalueaza_si_alege([ ], _ , p(Mutare, _ ), Mutare).

actualizez( _ ,Valoare, p(Mutare1,Valoare1),p(Mutare1,Valoare1)) :-


Valoare >= Valoare1.

actualizez(Mutare,Valoare,p(_,Valoare1),p(Mutare,Valoare)) :-
Valoare < Valoare1.

muta(m(K,M), [m(K1,N)|Ns], [m(K1,N)|Ns1] ) :-


K <> K1,muta(m(K,M),Ns,Ns1).
muta(m(K,M),[m(K,N)|Ns],[m(K,N1)|Ns]) :-
N>=M,N1=N-M.

afiseaza(Pozitia,_) :-
shiftwindow(1),
write(Pozitia),nl.

urmatorul_jucator(computer,noi). urmatorul_jucator(noi,computer).

sfirsit_joc([m(1,0),m(2,0),m(3,0),m(4,0)],_).

anunta(computer) :-
write("Eu am cistigat"),nl.
anunta(noi) :-
write("Computerul a cistigat"),nl.

valoare(Pozitia,Valoare) :- nim_sum(Pozitia,0,Valoare).

nim_sum([ ],S,S).
nim_sum([m(_,N)|Ns],Nb,Sum) :-
bitxor(N,Nb,Nb1),
nim_sum(Ns,Nb1,Sum).

Observații
1. O poziţie din configuraţia de joc se reprezintă sub forma unui obiect compus cu
aspectul
n(numar linie, numar poziţii din linie)

168
Inteligenţă Artificială. Tehnici.

Ca urmare configuraţia de joc de N linii cu un număr variabil de elemente pe linie se


va reprezenta printr-o lista cu elemente de acest tip. Deoarece numărul de elemente
care se iau dintr-o linie se pot reprezenta ca o poziţie din stiva se utilizează aceeaşi
structură pentru o mutare. O poziţie se va defini de asemenea ca un obiect compus
de forma
p(mutare, integer)
in care mutare este mutarea aplicata poziţiei curente iar valoare, valoarea funcţiei de
evaluare pentru noua poziţie care rezulta din mutarea efectuata.
2. Calculul funcţiei de evaluare a poziţiei se face cu predicatul
nim_sum(Pozitie, Manevra, Nim_Sum)
unde, Nim_sum este valoarea obţinută în urma evaluării configuraţiei de joc definite
de Poziţie. Se utilizează predicatul standard bitxor(Nr1, Nr2, XorNr1Nr2) care
efectuează un sau exclusiv între poziţiile binare a celor doua numere Nr1, Nr2.
3. Mutarea este realizată de
muta(Mutare, Pozitie, Noua_Pozitie)
Unde după identificarea liniei se face scăderea elementelor luate.
4. Pentru exemplul dat în programul anterior exemplificarea este făcută pentru
configuraţia prezentă în figura din acest paragraf cu observația că prima mutare
revine partenerului uman.
5. Se face de asemenea observaţia că fata de procedura clasică a celei mai bune
mutări s-a înlocuit
findall(M, mutare(Pozitia, M), Mutări)
Cu un predicat de forma
mutări(Pozitia, Mutări)
Deoarece acesta este mai uşor de construit în cazul acestui joc.

169
Inteligenţă Artificială. Tehnici.

14.3.2 Alegerea minimax


Pentru strategia celei mai bune mutări, discutată anterior, se observă că
alegerea mutării se face privind înainte o mutare. Dacă funcţia de evaluare a
poziţiei este corect aleasa atunci sensul este de a ne îndrepta spre un nod
terminal câștigător din arborele de joc, scorul reflectând de fiecare dată, care
poziţie conduce la un câștig şi care la o pierdere. Jocul devine interesant atunci
când nu este posibilă determinarea exacta a unei funcţii de evaluare. În acest caz
alegerea unei mutări pe baza strategiei de a anticipa înainte o mutare nu este cea
mai fericită. Rezultă imediat că este mai bine de anticipa câteva mutări înainte şi a
deduce din acestea cea mai buna mutare de efectuat
Strategia minimax poate fi rezumată astfel

Într-un joc strategic atunci când este confruntat cu câteva posibilități de


alegere, oponentul va alege cea mai buna mutare pentru el, ceea ce însemna
alegerea cea mai nefavorabila pentru mine. Ținta mea este deci de a face mutarea
care maximizează pentru mine valoarea poziţiei după ce oponentul face cea mai
buna mutare a sa, ceea ce înseamnă că se maximizează valoarea poziţiei pentru
el.

Precizări
(1) Trebuie făcuta distincţia dintre un “arbore de joc” şi un arbore de căutare. Un
arbore de căutare este în mod normal o parte a unui arbore de joc, mai exact
este partea care este explicit generate prin procesul de căutare. Este posibil ca
în acest caz poziţiile terminale ale arborelui de căutare sa conţină poziţii
terminale ale jocului.
(2) Funcţia de evaluare se transformă într-un estimator euristic, care evaluează
șansele de câștig din punctual de vedere al unuia dintre jucători. Astfel cea mai

170
Inteligenţă Artificială. Tehnici.

mare valoare va reprezenta șansa de a câștiga cea mai mare pentru un jucător
în timp ce cea mai mică valoare va defini şansa de a câștiga a oponentului.
(3) Deoarece unul din cei doi jucători va tinde sa obțină poziţia cu cea mai mare
valoare iar cel de al doilea poziţia cu valoarea cea mai mică, cei doi jucători pot
fi numiți MAX şi MIN. Ori de câte ori MAX este la mutare va alege mutarea
care maximizează valoarea obţinuta din evaluarea funcţiei euristice ce
caracterizează poziţia, iar în opoziţie MIN va alege mutarea care minimizează
valoarea
(4) Fiind date valorile de pe nivelul cel mai de jos al arborelui de căutare, strategia
minimax va determina valorile pentru toate celelalte poziţii din arborele de
căutare
Principiul este ilustrat de figura de mai jos cu următoarele observații:
- MAX poate fi identificat cu “Noi” (sau “Ei”) iar MIN cu “Ei” (sau “Noi”)
- Denumirea de valori statice provine din faptul că ele se obţin printr-o
evaluare statică a funcţiei de evaluare în contrast cu valorile care sunt
obţinute dinamic prin propagarea valorilor statice în sus în arbore.
- Valorile nodurilor interne pot fi calculate nivel cu nivel de jos în sus pana
când nodul rădăcina este atins. Valoarea ataşată nodului rădăcina este 4 şi în
concordanţă cu strategia minimax cea mai buna mutare a lui MAX aflat în
poziţia a este a – b. Cea mai buna mutare cu care poate replica MIN este b –
d s.a.m.d. Aceasta secvența de mişcări poarta denumirea de variațiunea
principala. Aceasta defineşte mişcările optimale minimax pentru ambele
tabere.

171
Inteligenţă Artificială. Tehnici.

Pentru a implementa metoda vom lua în considerare următoarele aspecte:

 Structura unei configuraţii (alternative) din spaţiul stărilor este data de un obiect
compus unde apar două elemente: configuraţia propriu zisa şi valoarea estimatorului
euristic corespunzătoare configuraţiei respective. Ca urmare vom avea:

Configuraţie de joc = p( Mutare, Valoare)


Cu rolul de a asocia unei Mutări, Valoarea poziţiei la care conduce mutarea în cauză
definită de estimatorul utilizat.
 Se utilizează o procedura similara celei de tip generează şi testează, modificata prin
aceea că se propun toate configuraţiile posibile a fi generate din starea curenta, şi se
alege cea care prezintă cel mai bun estimator (alegerea este similara cu testarea din
tehnica generează şi testează) – implicit în acest mod se alege mutarea optimă de a fi
efectuata. În acest scop se utilizează următoarele predicate:
(g) valoare(Pozitie, Valoare) care implementează funcţia de evaluare ce
calculează o Valoare a unei Pozitii curente de joc.
(h) muta(Mutare, Pozitie, Pozitie_Noua) cu rolul de a efectua o mutare din poziţia
curenta rezultatul fiind o poziţie noua de joc.
(i) evalueaza_si_alege(Mutări, Pozitie, Adancime, MaxMin, Record,
Mutare_Aleasa) cu rolul de a alege cea mai bună mutare din toate mutările
posibile care decurg dintr-o poziţie data. Operația presupune construirea
pentru fiecare mutare a perechii p(mutare, valoare) definite prin Record şi
menținerea în atenție a celei mai bune perechi găsite prin intermediul lui
Record1
(j) mut(Pozitie, M) este echivalentul procedurii succesor având rolul de a
determina o mutare posibila plecând de la o poziţie data.
(k) minmax(Adancime, Pozitie,MaxMin,Mutare,Valoare)
(l) Strategia în acest context va avea următorul aspect:

172
Inteligenţă Artificială. Tehnici.

evalueaza_si_alege([Mutare|RestMutări],Pozitie,Adancime,MaxMin,
Record,MutareSelectata):-
muta(Mutare,Pozitie,PozitieNoua),
minimax(Adancime, PozitieNoua,MaxMin,Mutare,Valoare),
actualizez(Mutare,Valoare,Record,Record1),
evalueaza_si_alege(Mutări,Pozitie,Adancime,MaxMin,Record1,MutareSelectata).

evalueaza_si_alege([ ] , _ , _ , _ , p(Mutare,_) , Mutare).

minimax(0,Pozitie,MaxMin,_,Valoare):-
estimeza_valoarea_pozitiei(Pozitie,ValoarePozitie),
Valoare = ValoarePozitie * MaxMin.

minimax(Adancime,Pozitie,MaxMin,Mutare,Valoare):-
Adancime >0,
findall(M,mut(Pozitie,M),ListaMutări),
Adancime1 = Adancime -1,
MinMax = -MaxMin,
evalueaza_si_alege(ListaMutări,Pozitie, Adancime1,MinMax,p(nil,-1000),Mutare).

actualizez(_,Val,p(Mutare1,Val1),p(Mutare1,Val1))) :-
Val<=Val1,!.
actualizez(Mutare,Val,p(_,Val1),p(Mutare,Val))) :-
Val>Val1,!.

173
Inteligenţă Artificială. Tehnici.

14.3.3 Alegerea alfa_beta


Strategia care implementează tehnica minimax explorează toate poziţii în arborele
de căutare, începând cu poziţiile terminale şi urcând în sus spre nodul de start nivel
cu nivel. În cursul acestui proces se evaluează toate poziţiile care sunt generate. Tot
acest efort de calcul poate fi optimizat prin aceea că nu toate aceste valori sunt
necesare de a fi calculate pentru a obţine o valoare corecta minimax pentru poziţia
curentă (rădăcina) şi deci o mutare corecta. Optimizarea se bazează pe următoare
idee. Presupunem că exista doua alternative de mutare din care trebuie sa alegem
una. Pentru a lua o decizie corectă nu este neapărat necesar sa cunoaștem valoarea
corecta a mutării pe care o lăsam de o parte, este suficient sa știm că valoarea sa
este inferioara (sau superioara) valorii mutării pe care am selectat-o pentru ca decizia
sa fie corecta. De exemplu se poate utiliza acest principiu pentru a reduce căutarea în
arborele analizat la căutarea minimax. Procesul de căutare se desfășoară utilizând
doua valori numite Alpha şi Beta pentru operații de taiere în arborele de joc.
Semnificația celor doua valori este:

- Alfa (α) este cea mai buna valoare pe care o poate alege MAX găsită pana

în momentul curent pentru orice alegere dea lungul căi de configuraţii,iar

Beta (β) este valoarea maximă pe care MAX o poate obţine. Cu alte cuvinte:

(α) Scorul minim pe care jucătorul MAX poate sa-l atingă garantat

(β ) Scorul maxim pe care jucătorul MAX spera sa-l poată obţine

împotriva adversarului.

- Din punct de vedere a lui MIN, Beta (β) este cea mai rea valoare pe care o

poate obţine pe care o poate alege MIN găsită pana în momentul curent

pentru orice alegere dea lungul căi de configuraţii, Beta (β)este cea mai

buna valoare pe care o poate alege MIN găsită pana în momentul curent

174
Inteligenţă Artificială. Tehnici.

pentru orice alegere dea lungul căi de configuraţii, iar Alpha (α) valoarea

maximă pe care MIN o poate obține. Cu alte cuvinte:

(α) Scorul cel mai bun pe care jucătorul MIN poate spera sa-l

atingă

(β ) Scorul cel mai rău pe care jucătorul MIN îl poată obţine

împotriva adversarului.
- cheia algoritmului Alpha-beta este găsirea unei mutări suficient de buna (nu
trebuie sa fie cea mai buna în mod necesar), pentru a lua o decizie corecta.
Astfel valoarea poziţiei curente (v) trebuie sa fie între Alpha şi Beta,

[ α =< v <= β].


Dacă valoarea depășește intervalul Alpha-Beta, este suficient sa știm că
poziţia nu este interesanta, fără a ști exact valoarea ei. Ceea ce trebuie sa
știm este numai dacă este în intervalul Alpha-Beta. Trebuie precizat în acest
punct că dacă găsim o valoare care nu este în intervalul [Alpha,Beta] putem
"sa tăiem" (sa nu luam în considerare următoarele mutări posibile) în
următoarele cazuri:
- dacă la mutare este MAX, iar valoarea găsită este mai mare decât Beta

V >= β

- dacă la mutare este MIN, iar valoarea găsită este mai mică decât Alpha

V <= α

- Alfa şi Beta se iniţializează pe ultimul şi penultimul nivel impus de


adâncimea de căutare funcţie de secvența în care se efectuează MIN
urmat de MAX sau MAX urmat de MIN. Datorită acestei basculări pentru
nivelele următoare celui ultim şi penultim din arborele de joc se
procedează la interschimbarea valorilor corespunzătoare lui

α cu – β
β cu - α
MIN devine practic jucătorul maximizat iar MAX jucătorul minimizat
Principiul de funcţionare a strategiei poate fi ilustrat astfel:

175
Inteligenţă Artificială. Tehnici.

Principiul Alpha_Beta
 α este cea mai buna mutare
pentru MAX pe ramura curentă.
 Dacă v este o mutare mai
slaba pentru MAX comparativ,
cu α, MAX nu o va atinge
niciodata, ramura care conduce
la ea fiind tăiată
 Se defineste similar β pentru
MIN
 Operatia de taiere poate reduce
cu 40 % spaţiul de căutare

Pentru a explica modul de funcţionare cât şi modul de stabilire iniţiala a acestora


vom lua în considerare următoarea secvența de trei exemple

(1)

Se generează toți succesorii pentru nodul cel mai din stânga şi se calculează
funcţia de evaluare., obţinându-se 5 respectiv 7. Deoarece MIN este la mutare se

alege 5 care se translatează în sus, Alpha va primi valoare 5 ( α=5). Se generează

176
Inteligenţă Artificială. Tehnici.

succesorii următorului nod şi se obţine prin evaluarea configuraţiilor 3 respectiv 9.


Deoarece MIN este la mutare se translatează în sus 3. Succesorul a cărei valoare

de poziţie este 9 se observa că nu mai este era necesar de a fi generat (3 <= α)

(2)

Se generează toți succesorii pentru nodul cel mai din stânga şi se calculează
funcţia de evaluare. obţinându-se 6 respectiv 3. Deoarece MAX este la mutare se

alege 6 care se translatează în sus, Beta va primi valoare 6, (β =6). Se generează

succesorii următorului nod şi se obţine prin evaluarea configuraţiilor valori 9


respectiv 2. Deoarece MAX este la mutare se translatează în sus 9. Succesorul a

cărei valoare de poziţie este 2 nu mai era necesar de a fi generat (9 ≥ β),


(deoarece pe următorul nivel oricum indiferent de valoarea nodului în discuție
deoarece MIN este la mutare se va alege 6), comparația din paranteză
reprezentând condiţia de taiere a acestei ramuri şi deci a unei ramuri în cazul
general
Exemple

(A)

177
Inteligenţă Artificială. Tehnici.

(B)

(C)
Pentru exemplul dat la strategia minimax, utilizarea lui Alpha_Beta conduce la
următoarele operații de tăiere în arborele de joc:

178
Inteligenţă Artificială. Tehnici.

Pentru a implementa metoda vom lua în considerare următoarele aspecte:

 Structura unei configuraţii (alternative) din spaţiul stărilor este data de un obiect
compus unde apar doua elemente: configuraţia propriu zisa şi valoarea estimatorului
euristic corespunzătoare configuraţiei respective. Ca urmare vom avea:

Configuraţie de joc = p( Mutare, Valoare)


Cu rolul de a asocia unei Mutări, Valoarea poziţiei la care conduce mutarea în cauză
definită de estimatorul utilizat.
 Se utilizează o procedura similara celei de tip generează şi testează, modificata prin
aceea că se propun toate configuraţiile posibile a fi generate din starea curenta, şi se
alege cea care prezintă cel mai bun estimator (alegerea este similară cu testarea din
tehnica generează şi testează) – implicit în acest mod se alege mutarea optimă de a fi
efectuata. În acest scop se utilizează următoarele predicate:
(a) valoare(Pozitie, Valoare) care implementează funcţia de evaluare ce
calculează o Valoare a unei Poziţii curente de joc.
(b) muta(Mutare, Pozitie, Pozitie_Noua) cu rolul de a efectua o mutare din poziţia
curentă, rezultatul fiind o poziţie nouă de joc.
(c) evalueaza_si_alege(Mutări, Pozitie, Adancime, Alfa, Beta, Record,
Mutare_Aleasa) cu rolul de a alege cea mai buna mutare din toate mutările
posibile care decurg dintr-o poziţie dată. Căutarea se face pe o Adancime dată
de atacuri. Operația presupune construirea pentru fiecare mutare a perechii
p(mutare, valoare) definite prin Record şi menținerea în atenție a celei mai
bune perechi găsite care se va reţine în final în Mutare_Aleasa atunci când se
ajunge la nivelul nodului de start din arbore.
(d) mut(Pozitie, M) este echivalentul procedurii succesor având rolul de a
determina o mutare posibila plecând de la o poziţie data.
(e) alfa_beta(Adancime, Pozitie, Alfa, Beta, Mutare, Valoare)
(f) Strategia în acest context va avea următorul aspect:

179
Inteligenţă Artificială. Tehnici.

evalueaza_si_alege([Mutare | Mutări], Pozitie, Adancime, Alfa, Beta, Record,


Mutare_selectata) :-
muta(Mutare, Pozitie, Pozitie1),
alfa_beta(Adancime, Pozitie, Alfa, Beta, Mutare, Valoare),
Valoare= - Valoare,
taie(Mutare, Valoare1, Adancime, Alfa, Beta, Mutări, Pozitie, Record,
Mutare_selectata).

evalueaza_si_alege([ ], _ , _ , _ , _ , Mutare, p(Mutare, _ )).

alfa_beta(0 , Pozitie, _ , _ , Mutare, Valoare) :-


valoare(Pozitie, Valoare).

alfa_beta(Adancime, Pozitie, Alfa, Beta, Mutare, Valoare) :-


findall(M, muta(Pozitie, M), Mutări),
Alfa1 = -Beta,
Beta1 = - Alfa,
Adancime1 = Adancime – 1,
evalueaza_si_alege(Mutări, Pozitie, Adancime1, Alfa1, Beta1, nil,
p(Mutare,Valoare)).

taie(Mutare, Val, _ , _, Beta, _ , _ , _ , p(Mutare,Valoare)) :-


Val > Beta.

taie(Mutare, Val, Adancime, Alfa, Beta, Mutări, Pozitie, Record, Mutare_selectata) :-


Alfa < Val, Val < Beta,
evalueaza_si_alege(Mutări, Pozitie, Adancime, Val, Beta, Mutare,
Mutare_selectata).

taie(Mutare, Val, Adancime, Alfa, Beta, Mutări, Pozitie, Record, Mutare_selectata) :-


Val < Alfa,
evalueaza_si_alege(Mutări, Pozitie, Adancime, Alfa, Beta, Record,
Mutare_selectata).

180
Inteligenţă Artificială. Tehnici.

14.4. Construirea funcției de estimare a poziției de joc

Ca și în cazul jocurilor de tip combinatorial și în cazul jocurilor strategice se


generează un spațiu al stărilor în care o stare reprezintă o poziție de joc. Deosebirea
constă în faptul că acest spațiu este generat de către ambii jucători care utilizează un
set de reguli de joc pe care le cunosc în contextul cunoașterii exacte a pozitiei de joc.
Aducem aminte că în cazul problemelor de tip combinatorial există un singur jucător
care prin faptul că încearcă să atingă o țintă definită de o stare a jocului în cauză cu
efectul generării spațiului de joc.
Clasificarea jocurilor strategice funcție de natura probabilistică sau nu a jocului cât
și a nivelului informațional la care au acces cei doi jucători este dată în tabelul de mai
jos:

Deterministic Șansă

Informație Dame, Șah, Table,


perfectă Go, Othello Monopoly

Informație Bridge, Poker,


imperfectă Scrabble

Indiferent de natura jocului în prezent funcția de evaluare a poziției de joc este dat
de o funcție de forma

181
Inteligenţă Artificială. Tehnici.

f (n)  w1F1 (n)  w2 F2 (n) K  wM FM (n)


în care Fi(n) definește o caracteristică a poziției de joc n ca de exemplu în cazul
jocului de șah poate reprezenta numărul de pioni, nebuni, ture etc., valoarea acestor
piese, evaluarea poziției pătratului pe care se află piesele respective sau a relațiilor
existente între piese de același tip sau tip diferit. Un aspect important care se ia în
considerare este cel relativ la faptul că se consideră că variabilele de tip Fi(n) sunt
independente (o variabilă nu este corelată cu altă variabilă). Componenta wi
reprezintă un factor de ponderare a aspectului definit de caracteristica Fi(n).

În cele ce urmează vom prezenta câteva jocuri și vom arăta modul în care se
construiește funcția de evaluare a poziției curente a jocului în cauză.

14.4.1 Jocul TICKTACKTOE


Forma cea mai simpla a jocului, răspândit la chinezi, greci şi romani (menționat de
Ovidiu în cartea a III din Ars amatoria) folosește o tabla alcătuită din 9 pătrate şi 6 fise ( 3
albe şi 3 negre). Cei doi jucători primesc câte 3 fise fiecare de aceeași culoare pe care
urmeze sa le așeze pe tabla una câte una, rând pe rând, pana le așează pe toate 6. Este
socotit câștigător acela care reușește sa așeze fisele sale fie într-un rând orizontal, într-
un rând vertical sau pe una din diagonale. Dacă toate cele 6 fise au fost așezate pe tabla
şi nici un grup de 3 nu se află în situaţiile menționate mai sus jocul ar trebui sa se termine
nedecis. El se continuă însa, jucătorul care urmează la mutare deplasând una din fisele
sale într-o căsuţă rămasă liberă numai în sus sau în jos, respectiv la dreapta sau la
stânga; sunt interzise mutările în diagonală. Din punct de vedere al teoriei jocurilor
ticktacktoe reprezintă un joc strategic cu doua persoane finit. El nu cuprinde nici un
element de noroc şi se joacă cu informaţie complecta, întrucât toate mutările sunt
cunoscute jucătorilor.

182
Inteligenţă Artificială. Tehnici.

Observații
(1) Deşi pare un joc simplu spaţiul stărilor este foarte mare. La prima mutare sunt 9
răspunsuri posibile, la cea de a doua 8 răspunsuri posibile, samd. Ca urmare arborele
de joc are 9 x 8 x 7 x …. ..x 2 x 1 = 9! Deci 15120 stări.
Faptul că apare un fenomen de simetrie ( de exemplu în prima mișcare pot pune în
colt, în mijloc, sau în centrul unei laturi) spaţiul stărilor are un număr mai mic de stări,
dar care este încă considerabil. De exemplu:

În acest moment spaţiul s-a redus la 12 x 7!


(2) Dacă primul jucător face prima mutare în centru câștigă sigur. Din acest
considerent deschiderea aceasta este interzisa.
(3) În cadrul acestui joc poate fi definit un estimator euristic al şansei de a câștiga.
Estimatorul pentru poziţiile iniţiale se calculează astfel:
- pentru jucătorul X șansele de a câștiga pentru configuraţiile din figura
următoare sunt: 3, 4, şi respectiv 2.
-

183
Inteligenţă Artificială. Tehnici.

- Sa presupunem că jucătorul cu piese O este la mutare. Pentru el șansa de a


câștiga este de forma:
H = G(O)- G(X)
unde G(O) sunt posibilitățile de a câștiga a lui O ia
G(X) sunt posibilitățile de a câștiga a lui X.
De exemplu:

Jucătorul O are trei şanse de câștig


pentru poziția curentă, în timp ce
jucătorul X are un numar de 5 şanse de
câștig din aceeași pozitie. Estimatorul
euristic H în aceasta situație are
valoarea -2

În continuare este reprezentat o


secvența din arborelui de joc cu valorile
estimatorilor euristici pentru jucătorul X

184
Inteligenţă Artificială. Tehnici.

Procedura de generare a succesorilor pentru acest joc apare de forma:


/*
Structura de date
piesa=o;x;l
element=p(piesa,integer,integer)
poziţie=[element,....]

Predicate
poziţie(pozitie,pozitie) mut(pozitie,piesa,pozitie)
apartine(element,poziţie) update(element,poziţie,poziţie)

Tinta

? P is [p(o,1,1),p(l,2,1),p(l,3,1),
p(l,1,2),p(l,2,2),p(l,3,2),
p(l,1,3),p(x,2,3),p(l,3,3)],
pozitie(P,P1),write(P1).

*/
pozitie(P,P1) :-
mut(P,x,Mutări),
apartine(Mutare,Mutări),
update(Mutare,P,P1).

mut([],_,[]).
mut([p(P,X,Y)|Rest],x,[p(x,X,Y)|Rx]) :-
P is l,
mut(Rest,x,Rx),!.
mut([_|Rest],x,Rx) :-
mut(Rest,x,Rx).

update(p(OX,X,Y),[p(P,X1,Y1)|Rp],[p(P,X1,Y1)|Rp1]) :-
X<>X1,
update(p(OX,X,Y),Rp,Rp1),!;
Y<>Y1,
update(p(OX,X,Y),Rp,Rp1),!.

185
Inteligenţă Artificială. Tehnici.

update(p(OX,X,Y),[p(l,X1,Y1)|Rp],[p(OX,X,Y)|Rp]) :-
X1 is X, Y1 is Y.

apartine(X,[X|_]).
apartine(X,[_|R]) :-
apartine(X,R).

14.4.2 Jocul Moara

A. Moara: Reguli de joc


Jocul se desfăşoară pe o tablă ca în figură. Intersecţiile reprezintă poziţii în care se pot
pune piese. Fiecare jucător are 9 piese.
1. În prima fază a jocului, cei doi jucători îşi aşează alternativ piesele pe tablă.

2. Apoi urmează faza 2, de mutare a pieselor. O piesă se poate muta doar pe poziţiile
vecine, adică poziţiile legate cu linie de poziţia curentă.

3. Când un jucător rămâne doar cu 3 piese pe tablă, trece în faza a treia a jocului. În
această fază, jucătorul are voie să mute oriunde, nu doar în poziţiile vecine.

 Când un jucător reuşeşte să-şi pună 3 piese în linie (poziţiile pieselor să fie legate
prin linii pe tabla de joc), se spune că acesta a închis o moară.
 Când un jucător închide o moară, are dreptul sa-i captureze celuilalt jucător o
piesă.
 Nu este voie să se captureze piese aflate în moară. Dacă un jucător închide o
moară şi toate piesele celuilalt jucător se află în câte o moară închisa, jocul se continuă,
nu se va scoate nici o piesă.
 Scopul final al jocului este capturarea pieselor adversarului până acesta rămâne
doar cu 2 piese.
 Un jucător câştigă atunci când adversarul rămâne cu numai 2 piese pe tablă sau
când toate piesele adversarului sunt blocate (când adversarul nu mai poate muta).

186
Inteligenţă Artificială. Tehnici.

B. Structura estimatorului
I. Este evident faptul că la calcularea punctajului unei configuraţii de joc trebuie privit
din prisma ambilor jucători. O configuraţie care este foarte bună pentru unul din
jucători, este, evident, nefavorabilă pentru celălalt jucător. Valoarea
estimatorului trebuie să indice în primul rând de partea cui este avantajul. De
aceea, în funcţiile de căutare în spaţiul soluţiilor, s-a recurs la notarea jucătorilor
cu Min şi Max. O valoare foarte mică (sau negativă, în funcţie de implementare)
este favorabilă pentru Min, iar una foarte mare (sau pozitivă) este favorabilă
pentru Max. Astfel, pentru fiecare jucător se va aplica aceeaşi funcţie de
evaluare a configuraţiei. Bineînţeles că pentru fiecare jucător în parte se va ţine
cont de piesele sale şi de relaţiile existente între piese. Calcularea punctajului
asociat unei configuraţii se face deci din două părţi. Să presupunem că primul
jucător este cel pentru care se doreşte găsirea unei mutări bune şi îl vom
considera pe acesta jucătorul Max. Prin urmare, se va calcula funcţia de
evaluare pentru Max (să o notăm EstimMax), iar apoi se calculează pentru Min
(notată EstimMin). Deoarece folosesc aceeaşi funcţie de estimare, este clar că
şi EstimMax şi EstimMin vor avea valori mari pozitive. Dacă EstimMax este mai
mare decât EstimMin, Max este în avantaj. Dacă EstimMin este mai mare,
atunci Min este în avntaj.

187
Inteligenţă Artificială. Tehnici.

Pentru ca estimatorul să arate clar de partea cui se află avantajul, valoare


estimatorului configuraţiei de joc se calculează ca diferenţa celor două valori.

ValEstimator = EstimMax – EstimMin


Prin urmare, dacă ValEstimator este pozitiv, Max este în avantaj, iar dacă este
negativ, Min este în avantaj.
II. De obicei, pentru un joc, estimatorul se compune dintr-o funcţie de evaluate
a configuraţiei de joc. Scorul obţinut trebuie să fie relevant pentru piesele şi
relaţiile (asociaţiile) ce există între piese. Dar, la majoritatea jocurilor, există
dependinţe mari ale valorilor pieselor şi asociaţiilor de piese şi momentul
jocului. Spre exemplu o relaţie poate fi importantă pentru începutul jocului,
dar spre sfârşit să nu mai aibă nici o valoare. De aceea, întotdeauna se vor
defini mai multe funcții de evaluare, fiecare va corespunde unei faze de joc
diferită. Moara se compune din 3 faze importante, prima de plasare a
pieselor, a doua de mutare (cu câte o poziţie) a pieselor şi a treia de mutare
fără restricţii (adică în orice poziţie liberă de pe tablă) când un jucător rămâne
cu 3 piese pe tabla. Modalitatea abordată în prezent este corela funcția de
estimare cu etapa de joc.. Acesta se va compune din 3 funcţii de estimare
(nu una singură), fiecare funcţie corespunzând unei etape a jocului.

III. În contextul jocului Moara sunt importante relațiile dintre piese.. Spre
exemplu o relaţie poate fi « «numărul de piese blocate », iar o altă relaţie
poate fi « moară închisă » reprezentând 3 piese ale aceluiaşi jucător aşezate
în linie. Ponderea unei relaţii este coeficientul sau punctajul asociat relaţiei
respective.
Prin urmare o funcţie de evaluare se stabileşte în doi paşi.
- În primul pas se aleg cu atenţie relaţiile considerate relevante pentru
jocul respectiv (pentru faza jocului) iar
- în pasul al doilea i se asociază un coeficient fiecărei relaţii.

Pentru jocul de moara, apar trei seturi de relaţii relevante, corespunzătoare


câte unei etape a jocului. Acestea sunt prezentate în de mai jos. Pe coloane
se găsesc relaţiile specifice fiecărei faze (etape) a jocului. Se poate observa

188
Inteligenţă Artificială. Tehnici.

că unele apar în două etape, unele apar chiar în toate trei etapele, dar vor
avea asociate punctaje (ponderi) diferite în funcţie de etapa jocului.

Relaţii faza 1 Relații faza 2 Relaţii faza 3


R1: Moară închisă R1: Moară închisă R1: Nr. de config.
R2: Numărul morilor R2: Numărul morilor cu 2 piese
R3: Numărul pieselor R3: Numărul pieselor R2: Nr. de config.
adverse blocate adverse blocate cu 3 piese
R4: Număr de piese (ale R4: Număr de piese (ale R3: Moară închisă
jucătorului curent) jucătorului curent) R4: Config. de
R5: Nr. de config. cu 2 piese R5: Moară deschisă câştig
R6: Nr. de config. cu 3 piese R6: Moară dublă
R7: Config. de câştig

Relaţiile la nivelul fazelor jocului

Relaţiile din tabel au următoarea semnificație


Moară închisă – la mutarea respectivă jucătorul închide o moară (poate lua
valoarea 0 pentru cazul în care nu s-a închis nici o moară sau 1 pentru cazul în care s-a
închis o moară)
Numărul de mori – numărul total de mori închise existente pe tabla de joc pentru un
jucător (de regulă între 0 şi 3)
Numărul pieselor blocate ale adversarului – câte piese ale adversarului sunt blocate
Numărul de piese – numărul total de piese pe care le are jucătorul curent pe tablă
(între 3 şi 9 deoarece la 2 piese jocul se încheie)
2 piese – numărul de configuraţii de 2 piese în linie şi a treia poziţie liberă
(posibilitate de închidere moara) sau 2 piese aşezate strategic pe linii perpendiculare.
Figura 14.1. (a) prezintă cele două cazuri, cu verde sunt piesele în linie şi cu portocaliu
structura din care se poate obţine la pasul următor o structură de trei piese (explicată în
continuare).
3 piese – 3 piese aşezate astfel încât să se permită închiderea a două mori (chiar
dacă adversarul blochează o poziţie, va rămâne o poziţie deschisă pentru închiderea
unei mori) – Figura 7.1.1 (b) prezintă două posibilităţi de aşezare a pieselor strategic, în
structură de trei.

189
Inteligenţă Artificială. Tehnici.

Moară deschisă – la acel pas se deschide moara; s-a dovedit important ca PC-ul să
ştie că este necesar să şi deschidă mori. Fără această relaţie, jucătorul calculator avea
tendinţa să nu mai deschidă o moară odată închisă, deoarece punctajul scădea. Nu este
în regulă să menţină morile închise deoarece astfel nu poate evolua. (relaţia poate lua
valoarea 0 – jucătorul nu a deschis o moară sau 1 – jucătorul a deschis o moară).
Moară dublă sau moară în vânt – două mori apropiate, iar o piesă poate face parte
din ambele astfel încât prin deschiderea unei mori, se închide cealaltă şi tot aşa. În
exemplul din Figura 7.1.1 (c), verdele are o structură de moară dublă.

(a) – structuri de 2 piese (b) – structuri de 3 piese

Figura 14.1. – Relaţii în jocul


moara

(c) – moară dublă (piesele verzi)

Configuraţie de câştig – jucătorul care primeşte punctajul asociat acestei relaţii este
câştigător; poate lua valoarea 0 sau 1.
Spre exemplu configuraţia de 3 piese (Number of 3 pieces configuraţion) apare şi în
faza întâi şi în faza a treia dar cel mai probabil vor avea asociate punctaje diferite.

190
Inteligenţă Artificială. Tehnici.

Relaţia Configuraţie de câştig reprezintă posibilitatea încheierii jocului, de aceea va


avea asociat un punctaj considerabil mai mare. Dacă punctajul asociat unei mori închise
este de ordinul zecilor, punctajul pentru configuraţia de final va fi în jur de 1000. Este
indicată folosirea unui punctaj cât mai mare pentru configuraţia de final de joc cu câştig,
deoarece fiecare jucător se îndreaptă spre un punctaj cât mai mare găsit în arborele de
configuraţii. Dacă configuraţiei de final nu i se asociază un punctaj suficient de mare,
jucătorul calculator poate rata posibilitatea de câştig mergând pe altă ramură care îi
indică un punctaj mai mare. Dacă pentru o moară se asociază spre exemplu 30 puncte
iar pentru câştig 60, jucătorul poate alege să meargă pe un drum pe care îşi face mai
multe mori în loc să meargă pe o ramură pe care nu-şi face mori dar spre exemplu poate
bloca piesele oponentului şi astfel să ajungă în configuraţia de câştig. În schimb dacă
pentru câştig avem asociat punctajul 1000, nici o altă configuraţie care nu este de câştig
nu va putea avea un punctaj aşa de ridicat. Astfel se diferenţiază clar scopul jocului,
acela de a atinge o configuraţie de victorie.
În tabel avem în total 17 relaţii, dar unele sunt comune pentru două sau chiar pentru
toate trei fazele. La generarea unei configuraţii următoare se vor calcula valorile pentru
toate relaţiile distincte, indiferent de fază. Alegerea fazei intervine doar în momentul
calculării estimatorului de joc. Avem în total 9 relaţii distincte: Moară închisă, Numărul
morilor, Numărul pieselor adverse blocate, Număr de piese (ale jucătorului curent), Nr. de
config. cu 2 piese, Nr. de config. cu 3 piese, Moară deschisă, Moară dublă, Config. de
câştig.

191
Inteligenţă Artificială. Tehnici.

Figura 14.1.2 Exemplu de relaţii existente.

Pentru fiecare jucător în parte este necesar să se cunoască ce relaţii există pe tabla
de joc, de aceea pentru o configuraţie se vor salva două seturi de variabile
corespunzătoare relaţiilor. Să luăm spre exemplu cazul din figura 14.1.2.
Pentru jucătorul verde vom avea valorile relaţiilor:
Numărul morilor = 1
Numărul pieselor adverse blocate = 1 (portocalie încercuită cu verde)
Nr. de config. cu 3 piese = 1
Număr de piese = 6 (ale jucătorului verde)
Restul relaţiilor pentru jucătorul verde vor avea valoarea 0.
Pentru jucătorul portocaliu vom avea valorile relaţiilor:
Numărul morilor = 1
Nr. de config. cu 2 piese = 1 (cele două piese în linie unde se poate închide o
moară prin plasarea unei piese)
Număr de piese = 5 (ale jucătorului portocaliu)
Restul relaţiilor pentru jucătorul portocaliu vor avea valoarea 0.

Figura 14.1.3 prezintă structura estimatorului, cu cele 3 funcţii de evaluare


obţinute ca sumă ponderată a relaţiilor prezentate în tabelul de mai înainte.

192
Inteligenţă Artificială. Tehnici.

Figura 14.1.3 – Structura estimatorului


În figură au fost notate cu R relaţiile, iar ponderile (coeficienţii) cu Cf. Relaţiile s-au
ales ca fiind asociaţii de piese reprezentative pentru joc. La alegerea lor se ține cont de
cunoştinţele jucătorilor experimentaţi de Moară. În alte cuvinte aceste relaţii reprezintă
pattern-uri după care se va conduce şi un jucător uman experimentat. Coeficienţii trebuie
aleşi cu mare atenţie, de asemenea pe baza experienţei jucătorilor umani.
IV. Trebuie ținut cont de modul de joc. Modurile clasice sunt
a) defensiv şi
b) ofensiv,
respectiv apărare şi atac. Sunt două abordări diferite întâlnite la jucătorii
umani. La jocul Moara, o abordare defensivă ar însemna să încerci să pierzi
cât mai puţine piese şi să încerci învingerea adversarului prin blocarea
pieselor acestuia. Şi un jucător defensiv va încerca să închidă mori, însă
probabil nu cu preţul pierderii pieselor. O abordare ofensivă implică
încercarea de a construi cât mai multe mori, structura de moară în vânt şi un
jucător ofensiv nu va încerca în mod deosebit să-şi protejeze piesele ci mai
degrabă să captureze cât mai multe piese.
La nivelul estimatorului nostru de joc, aceste abordări subiective se traduc
tocmai la nivelul coeficienţilor. În timp ce relaţiile reprezintă pattern-uri
valabile pentru toţi jucătorii, coeficienții sunt cei care diferenţiază modurile de
joc.

193
Inteligenţă Artificială. Tehnici.

Toţi jucătorii vor căuta asociaţii de genul blocarea pieselor adversarului sau
închiderea unei mori, însă importanța acestora diferă în ochii jucătorilor.
Importanța se traduce prin coeficienţi. Prin urmare, modul de joc al
calculatorului va fi influenţat în mod definitiv de aceşti coeficienţi.

În prima fază a jocului, se pot defini în mod logic două moduri de joc: ofensiv şi
defensiv, prin atribuirea de coeficienţi relaţiilor. Aceasta se realizează prin mai multe
încercări şi ajustări. Se plecă de la ideea că fiecare mod de joc se axează pe 2-3 relaţii
pe care le vede importante şi cărora li se atribuie un punctaj mare, iar celelalte relaţii au
asociat un punctaj mai mic, uneori chiar şi 0 (neutralizarea unei relaţii – nu se mai ţine
cont de ea). Pentru modul defensiv, se atribuie punctaj mare relaţiilor: număr total de
piese, piese oponent blocate şi moară închisă. Pentru modul ofensiv se atribuie punctaj
mare relaţiilor: moară închisă, moară dublă. O altă diferenţiere se face la nivelul
configuraţiei câştigătoare. Pentru modul defensiv se încearcă câştigarea meciului din
faza a doua (înainte ca jucătorul să rămână doar cu 3 piese pe tablă), în timp ce jucătorul
ofensiv cel mai probabil va ajunge în faza a treia, datorită modului de joc. Distincţia se
face astfel: relaţia de configuraţie câştigătoare în modul defensiv (de exemplu) are
asociată ponderea 1200 în faza doi şi 1000 în faza trei; în modul ofensiv are asociată
ponderea 1000 în faza doi şi 1200 în faza trei.

14.4.3 Jocul Șah

Una din cele mai utilizate funcții evaluare a poziției curente de joc este de forma
F(n) = c1 * valoare piese + c2 * mobilitate + c3 * siguranță rege +
c4 * control centru tablă + ...
de exemplu
F (n) = 9(Q-Q') + 5(R-R') + 3(B-B'+N-N') + (P-P') - 0.5(D-D'+S-S'+I-I') + 0.1(M-M') + ...
în care
 Q, R, B, N, P sunt numărul (sau valoarea ) pentru ture, nebuni, cai, și pioni de pe
tabla de șah. Cu Q se notează numărul de regine . Piesele au culoare albă Q, R,
B, N, P respectiv culoare neagră Q', R', B', N', P'. În prezent cea mai utilizată
contorizare a valorii pieselor este dată în continuare

194
Inteligenţă Artificială. Tehnici.

 D, S, I reprezintă numărul de pioni dublați , unul în spatele celuilalt , respectiv


izolați. În imagine apare conceptul de pion dublat.

 M reprezintă mobilitatea pieselor albe (măsurată de exemplu în numărul legal de


mutări pentru piesele albe).

 Un alt aspect care trebuie luat în considerare este legat de valoarea de schimb a
pieselor. Această valoare de schimb apare în momentul în care se iau piese (o
piesă sau se sacrifică 2 sau mai multe piese minore pentru eliminarea unei piese
de valoare mai mare de pe tablă) În această situație este necesar de cuantizat
dacă poziția care se obține în perspectivă ( după două sau mai multe mutări ) este
mai bună decât ca din momentul începerii schimbului ( mai bun însemnând o
funcție de evaluare a poziției de joc mai mare valoric).

Remarcă

195
Inteligenţă Artificială. Tehnici.

În10/5/1997, la New York în cadrul unui meci de 6 partide între (programul


DeepBlue) – Kasparov scorul a fost de 2 – 1 pentru DeepBlue ( dupa 3 partide campionul
mondial Kasparov a abandonat). În sistemul de evaluare a unui jucător de şah se
utilizează pentru a cuantifica forţa de joc unitatea de măsura numită punct Elo
Astfel:
– Categoria I: 500 puncte Elo
– Maestru International: 2.200 puncte Elo
– Campion mondial: 2.800 puncte Elo
– Deep Blue 3000 puncte Elo

S-a utilizat un calculator cu 32 procesoare paralele care a permis evaluarea a 200


milioane de pozitii pe secunda utilizând o strategie Alpha_Beta pana la o adâncime de
joc de 40 mutări pe direcții privilegiate.

196
15. Calcul evoluționist. Algoritmi genetici.

15.1. Istoric
Ideea de calcul evolutiv a fost introdus în 1960 de către I. Rechenberg în
lucrarea sa "Evolution strategies" (Evolutionsstrategie: Optimierung technischer
Systeme nach Prinzipien der biologischen Evolution). Ideea a reprezentat un alt
punct de vedere în tehnologia informației, prin aceea că la construirea strategiilor
specifice tehnologiei calculatoarelor se pleacă de la exemplele pe care lumea
biologică le prezintă.
Genetic Algorithms (GA) a fost inventat de John Holland și dezvoltat de el și
colegii săi. În 1975 acesta publică cartea "Adaption in Natural and Artificial
Systems".
În 1992 John Koza a folosit conceptul de algoritm genetic pentru a construi
programe care să poată evolua. Metoda propusă a numit-o "Genetic Programming"
(GP).

Concepte biologice
Toate organismele vii constau din celule. In fiecare celulă există același set de
cromozomi. Cromozomii sunt șiruri de ADN (DNA - Deoxyribonucleic acid) și
servesc ca model pentru întregul organism.

Structura AND Celulele umane conțin 23 de perechi de cromozomi

Un cromozom constă din gene, blocuri de ADN. O genă este o secvenţă a ADN-ului
care conţine instrucţiunile necesare sintezei unei anumite proteine. Practic se poate
spune, că fiecare genă codifică o trăsătură, de exemplu culoarea ochilor. Fiecare genă
195
are propria poziție în cromozom. Setul complet de material genetic (toți cromozomi)
este numit genom. Un set specific de gene în genomul este numit genotip. Genotipul
asociat cu dezvoltarea organismului (influența mediului în care se dezvoltă
organismul), după naștere definește phenotype organismului, respectiv
caracteristicile sale fizice și psihice, (cum ar fi culoarea ochilor, inteligență etc.). S-a
constatat că "setul de instrucţiuni" uman nu conţine decât în jur de 35000 de gene.
Genomul uman reprezintă practic totalitatea informației genetice stocată în ADN.

Definiție CROMOZOM, Unitate genetică, structurală, constantă, a nucleului, cu


organizare și funcții proprii, cu însușire de autoreproducere și care deține informația
ereditară specifică.

15.2. Specificul calculului evolutiv


Spațiul stărilor
Atunci când se rezolvă o problemă în marea majoritate a cazurilor nu există o
singură soluție. Sunt prezente mai multe soluții, fiecare fiind mai bună sau mai puțin
bună. Acestea sunt prezente printre alte numeroase situații care nu reprezintă soluții.

 Spațiul tuturor soluțiilor posibile sau nu poartă numele de search space sau
spațiul stărilor. În acest spațiu o soluție posibilă este reprezentată de un
punct.
 Fiecare soluție posibilă este caracterizată de o valoare care spune cât de bună
este soluția respectivă. Această valoare poartă numele de fitness.
 Operația de căutare presupune găsirea unui extrem (minim sau maxim) în
spațiul stărilor. Spațiul stărilor poate fi cunoscut în totalitate (situație mai rar
întâlnită) sau numai parțial, situație care este cea care apare în majoritatea
cazurilor. Practic spațiul se generează pe măsură ce se avansează cu procesul
de căutare.

Exemplu de search
space

196
Problemele de căutare în spațiul stărilor pot fi foarte complicate deoarece nu se
cunoaște unde este prezentă soluția și de asemenea nu cunoaștem care este cel mai
bun punct din spațiul stărilor de unde putem începe operația de căutare. Există multe
metode de căutare care încearcă să optimizeze acest proces. Acestea vor găsi cea
mai adecvată soluție într-un context dat și în foarte puține cazuri se obține cea mai
bună soluție. Dintre acești algoritmi amintim hill climbing, A* și algoritmi genetici.
Soluțiile găsite prin aceste metode sunt adesea considerate ca fiind cea mai bună
soluție, deoarece în mod real este imposibil de cunoscut care este optimul real.

Un algoritm evolutiv este o metodă de căutare prin analogie cu evoluţia


biologică (de tip darwinist). Pentru găsirea soluţiei se utilizează o populaţie de soluţii
potenţiale care evoluează prin aplicarea iterativă a unor operatori stohastici.
Elementele populaţiei reprezintă soluţii potenţiale ale problemei.

Un algoritm genetic este un model informatic care emulează modelul


biologic evoluționist pentru a rezolva probleme de optimizare ori căutare. Acesta
cuprinde:
- un set de elemente individuale reprezentate sub forma unor șiruri
binare (populația) și
- un set de operatori de natură biologică definiți asupra populației. Cu
ajutorul operatorilor, algoritmii genetici manipulează cele mai
promițătoare șiruri, evaluate conform unei funcții obiectiv, căutând
soluții mai bune.

Algoritmii genetici codifică o soluţie posibilă la o problemă specifică


într-o singură structură de date numită „cromozom” şi aplică operatori genetici
la aceste structuri astfel încât să menţină informaţiile critice.

Algoritmii genetici pornesc de la o mulţime iniţială de soluţii (de obicei


aleasă aleator) numită în literatură „populaţie”. În această populaţie fiecare
individ este numit „cromozom” şi reprezintă o soluţie posibilă a problemei. În
aproape toate cazurile cromozomul este un şir de simboluri (de obicei reprezentat
ca un şir de biţi). Aceşti cromozomi evoluează pe durata iteraţiilor succesive
numite generaţii. În fiecare generaţie, cromozomii sunt evaluaţi utilizând unele

197
măsuri de potrivire (fitness). Pentru crearea următoarei populaţii cei mai buni
cromozomi din generaţia (populaţia) curentă sunt selectaţi şi noii cromozomi
sunt formaţii folosind unul dintre cei trei operatori genetici esenţiali: selecţia,
crossover şi mutaţia.

Pentru a ghida căutarea către soluţia problemei asupra populaţiei se aplică


transformări specifice evoluţiei naturale:

Selecţia. Indivizii din populaţie care se apropie de soluţia problemei sunt


considerați adecvați şi sunt favorizați în sensul ca au mai multe şanse de a supravieţui
în generaţia următoare precum şi de a participa la generarea viitorilor copii.
Încrucişarea. La fel ca la înmulţirea din natură pornind de la două sau mai
multe elemente ale populaţiei (numite părinţi) se generează noi elemente (numite
urmaşi). În funcţie de calitatea acestora (apropierea de soluţia problemei) urmaşii îşi
pot înlocui părinţii.
Mutaţia Pentru a asigura diversitatea populaţiei se aplică, transformări cu
caracter aleator asupra indivizilor din populaţie permiţând apariţia unor trăsături
(gene) care nu ar fi apărut în cadrul populaţiei doar prin încrucişare şi selecţie.

Terminologie.
Algoritmii evolutivi utilizează un vocabular împrumutat din genetica:
 soluția candidat poarta numele de cromozom și este reprezentată ca un șir
de gene;
 Un cromozom este compus din gene – variabile a problemei de optimizat

 evoluția este simulata printr-o succesiune de generații ale unei populații de


soluții candidat;
 populația evoluează prin aplicarea operatorilor genetici: mutația și
încrucișarea;

198
 cromozomul asupra căruia se aplica un operator genetic se numește părinte
iar cromozomul rezultat se numește descendent (copil);
 selecția este procedura prin care sunt aleși cromozomii ce vor supraviețui in
generația următoare; indivizilor mai bine adaptați li se vor da șanse mai mari;
 gradul de adaptare la mediu este măsurat de funcția fitness. Practic funcția
fitness este utilizata pentru a măsura calitatea cromozomilor. Este formulata
plecând de la funcția numerica de optimizat. Este cunoscută și sub denumirea
de funcție de adaptare;
 soluția returnata de un algoritm genetic este cel mai bun individ din ultima
generație.

Majoritatea algoritmilor evolutivi au un caracter iterativ. Structura generală este

199
Start
generație=0
GENEREAZĂ populația inițială
EVALUEAZĂ indivizii din populația inițială
REPETĂ
ÎMPERECHEAZĂ părinții
RECOMBINĂ părinții și generează moștenitori
APLICĂ MUTAȚII cu o probabilitate predefinită
EVALUEAZĂ indivizii
SELECTEAZĂ indivizii pentru generația următoare
generație = generație + 1
PÂNĂ CÂND condiția de terminare este satisfăcută
Stop

Pseudocod pentru implementarea generală a AG

200
15.3. Exemplu numeric

Presupunem că avem ecuația


a +2 b +3 c +4 d = 30.
Vom utiliza un algoritm genetic pentru a găsi valorile a, b, c, și d care satisfac această
ecuație.
 Funcția obiectiv pentru această problem este dată de minimizarea valorii
funcției f(x) unde
f (x) = ((a + 2b + 3c + 4d) - 30)
 Deoarece sunt prezente 4 variabile în această ecuație a, b, c și d, se va putea
defini un cromozom de forma:

a b c d

Pentru a mări viteza de calcul se vor restricționa valorile pe care le pot lua aceste variabile a,
b, c, și d la intervalul [0, 30]. Vom considera că în acest interval se iau numai valori întregi.

Pasul 1. Inițializare
Presupunem că populația inițială are un număr de 6 cromozomi. Vom genera
valori aleatoare pentru genele a, b, c, d pentru un număr de 6 cromozomi. Se va utiliza
un generator de numere aleatoare, uniform distribuite în intervalul [0, 30]. Obținem:

Chromozom [1] = [a;b;c;d] = [12;05;23;08]


Chromozom [2] = [a;b;c;d] = [02;21;18;03]
Chromozom [3] = [a;b;c;d] = [10;04;13;14]
Chromozom [4] = [a;b;c;d] = [20;01;10;06]
Chromozom [5] = [a;b;c;d] = [01;04;13;19]
Chromozom [6] = [a;b;c;d] = [20;05;17;01]

Pasul 2. Evaluare
Se calculează funcția obiectiv pentru fiecare cromozom definit în
pasul de inițializare:

F _ obj 1  abs  12  2*05  3*23  4*08  30   abs 123  30  93

F _ obj  2  abs   02  2*21  3*18  4*03  30   abs 110  30   80


201
F _ obj 3  abs  10  2*04  3*13  4*14  30  abs 113  30  83

F _ obj  4  abs   20  2*01  3*10  4* 06  30  abs  76  30   46

F _ obj 5  abs   01  2*04  3*13  4*19  30  abs 124  30  94

F _ obj 6  abs   20  2*05  3*17  4* 01  30   abs 85  30   55

Pasul 3. Selecție
1. În acest pas se selectează cei mai buni cromozomi pentru următoarea generație. Cei
mai buni înseamnă că respectivii cromozomi sunt cel mai bine adaptați la mediu..Acest
aspect care este măsurat de funcția de fitness care va defini probabilitatea de
adaptare la mediu. Pentru acest caz funcția de fitness este de forma

1
Fitness i   i  1,6
1  F _ obj i 

1 1 1 1
Fitness 1    0.0106 Fitness  2    0.0123
1  F _ obj 1 94 1  F _ obj  2 81
1 1 1 1
Fitness 3    0.0119 Fitness  4    0.0213
1  F _ obj 3 84 1  F _ obj  4 47
1 1 1 1
Fitness 5    0.0105 Fitness  6    0.0179
1  F _ obj 5 95 1  F _ obj 6 56

Total  0.0106  0.0123  0.0119  0.0213  0.0105  0.0179


Total  0.0845

Probabilitatea pentru fiecare cromozom este de forma:

Fitness i 
P i   i  1,6
Total

202
0.0106 0.0123
P 1   0.1254 P  2   0.1456
0.0845 0.0845
0.0119 0.0213
P 3   0.1408 P  4   0.2521
0.0845 0.0845
0.0105 0.0179
P 5   0.1243 P  6   0.2118
0.0845 0.0845

Din probabilitățile calculate mai sus se observă că Cromozomul 4 prezintă cea mai
mare funcție fitness, deci acest cromozom prezintă cea mai mare probabilitate de a fi
selectat pentru următoarea generație de cromozomi. Pentru procesul de selecție se va
utiliza o ruletă. Pentru inițializarea acestui proces se va calcula probabilitatea
cumulativă. Vom avea:

c 1  0.1254
c  2  0.1254  0.1456  0.2710
c 3 = 0.1254  0.1456  0.1408  0.4118
c  4  0.1254  0.1456  0.1408  0.2521  0.6639
c 5  0.1254  0.1456  0.1408  0.2521  0.1243  0.7882
c  6  0.1254  0.1456  0.1408  0.2521  0.1243  0.2118  1.0

Având calculate probabilitățile cumulative se poate trece la un proces de selecție în


care se va utiliza o selecție de tip ruletă.

Cromozom C[1] C[2] C[3] C[4] C[5] C[6]


Fitness 0.1254 0.1456 0.1408 0.2521 0.1243 0.2118
Probabilitatea 0.1254 0.2710 0.4118 0.6639 0.7882 1.0
Cumulativă

203
În acest scop se procedează la generarea unor numere uniform repartizate în
intervalul [0, 1]. Presupunem că s-au generat numerele R[1] = 0.201, R[2] = 0.284 ,
R[3] = 0.099 , R[4] = 0.822 , R[5] = 0.398 , R[6] = 0.501

Dacă numărul aleator apare în intervalul


 c[1] < R[1] < c[2] se va selecta cromozomul [2] ca nou cromozom pentru
următoarea generație.
 c[2] < R[2] < c[3] se va selecta cromozomul [3] ca nou cromozom pentru
următoarea generație.
 0 < R[3] < c[1] se va selecta cromozomul [1] ca nou cromozom pentru
următoarea
generație
 Se procedează similar pentru R[4], R[5], R[6] fiind obținută în final noua
configurație de cromozomi.

NewChromosome[1] = Chromosome[2]
NewChromosome[2] = Chromosome[3]
NewChromosome[3] = Chromosome[1]
NewChromosome[4] = Chromosome[6]
NewChromosome[5] = Chromosome[3]
NewChromosome[6] = Chromosome[4]

Cromozomii din noua populație vor fi:


Chromosome[1] = [02;21;18;03]
Chromosome[2] = [10;04;13;14]
Chromosome[3] = [12;05;23;08]
Chromosome[4] = [20;05;17;01]
Chromosome[5] = [10;04;13;14]
Chromosome[6] = [20;01;10;06]

Pasul 4. Crossover
În această etapă se vor genera noi cromozomi plecând de la 2 cromozomi
părinți. Tehnica utilizată este crossover cu un singur punct de tăiere (vezi figura
următoare).

204
Cromozomii părinți care sunt implicați în procesul de generare a noi cromozomi vor fi
selectați aleator din setul de cromozomi părinți existenți, utilizând un parametru de tip
crossover_rate (ρc) parameters. Pseudo codul pentru procesul de selecție este
următorul:

begin
k  0;
while  k  population  do
R  k   random  0  1 ;
if ( R  k   ρc) then select
Chromosome  k  as parent;
end ;
k  k  1;
end ;
end ;

Cromozomul k va fi selectat ca părinte dacă R [k] <ρc. Presupunem că rata de


crossover este de 25%, ceea ce însemnă că cromozomul cu numărul k va fi selectat
dacă valoarea aleatoare generată pentru cromozomul k este mai mică decât 0.25.
Procesul se desfășoară astfel: Se generează inițial un set de numere aleatoare R a
căror număr este egal cu mărimea populației de cromozomi.

R[1] = 0.191 , R[2] = 0.259 , R[3] = 0.760 , R[4] = 0.006 , R[5] = 0.159 , R[6] = 0.340

Pentru numerele aleatoare de mai sus părinții sunt Chromosome [1], Chromosome [4]
și Chromosome [5] care vor fi selectați pentru crossover

Chromosome[1] >< Chromosome[4]


Chromosome[4] >< Chromosome[5]
Chromosome[5] >< Chromosome[1]

După selecția cromozomilor se trece la determinarea poziției punctului de crossover.


Aceasta se va face prin generarea unui număr uniform repartizat între 1 și lungimea
cromozomului - 1. În cazul acesta se va genera un număr între [1, 3]. După generarea
punctului de tăiere se va proceda la tăierea acestora și la inter schimbarea genelor ,
aspect care va conduce la apariția unor noi urmași.
205
Pentru cazul dat vom genera 3 numere aleatoare. Presupunem că acestea sunt
C[1] = 1 , C[2] = 1 , C[3] = 2
Pentru primul crossover și cel de al doilea crossover tăierea se va face la nivelul genei
1 iar pentru cel de al treilea tăierea se va face la nivelul genei 2. Se va obține

Chromosome[1] = Chromosome[1] >< Chromosome[4]


= [02;21;18;03] >< [20;05;17;01]
= [02;05;17;01]
Chromosome[4] = Chromosome[4] >< Chromosome[5]
= [20;05;17;01] >< [10;04;13;14]
= [20;04;13;14]
Chromosome[5] = Chromosome[5] >< Chromosome[1]
= [10;04;13;14] >< [02;21;18;03]
= [10;04;18;03]

Populația de cromozomi după efectuarea operației de crossover este :

Chromosome[1] = [02;05;17;01]
Chromosome[2] = [10;04;13;14]
Chromosome[3] = [12;05;23;08]
Chromosome[4] = [20;04;13;14]
Chromosome[5] = [10;04;18;03]
Chromosome[6] = [20;01;10;06]

Pasul 5. Mutație
Numărul de cromozomi care au mutații din populație este determinată de rata
( frecvența ) de mutație. O notăm cu rate(pm). Procesul de mutație presupune
înlocuirea valorii unei gene cu o altă valoare. Procesul se desfășoară astfel: În
primul pas se calculează lungimea genelor din populație. În acest caz lungimea totală a
genelor este

total_gen = numărul_de_gene_in_Chromozom * mărimea populației


=4*6
= 24
Procesul de mutație este inițiat prin generarea unei valori numerice, întregi, uniform
distribuite între 1 și total_gen (1 la 24). Dacă numărul generat este mai mic decât
rate(pm) se trece la definirea genei din cromozom care urmează să fie modificată.
Presupunem că definim o rată de mutație de 10%, aspect care specific faptul că
206
ne așteptăm ca 10% (0.1) din populația de gene să fie rezultatul unei mutații. Pentru
cazul în discuție vom avea
Numărul de mutații = 0.1 * 24 = 2.4  2

Generăm un număr de 2 poziții de gene care vor prezenta valori mutante.


Generarea a 2 valori uniform repartizate în intervalul 1 – 24 presupunem că ne
conduce la valorile 12 și respective 18. Pozițiile 12 și respective 18 corespund
cromozomilor 3 și respective 5. Genele din pozițiile respective se vor înlocui printr-o
valoare obținută prin generarea unei valori numerice din intervalul 0-30. Presupunem că
valorile generate sunt 2 și 5. După înlocuirea genelor care sunt supuse procesului de
mutație populația de cromozomi va fi de forma:

Chromosome[1] = [02;05;17;01]
Chromosome[2] = [10;04;13;14]
Chromosome[3] = [12;05;23;02]
Chromosome[4] = [20;04;13;14]
Chromosome[5] = [10;05;18;03]
Chromosome[6] = [20;01;10;06]

Prin terminarea procesului de mutație s-a finalizat o iterație de evoluție în care s-a
generat un nou set de cromozomi. Pentru acest nou set se poate recalcula funcția
obiectiv

Cromosome 1   02;05;17;01


F _ obj 1  abs   02  2*05  3*17  4*01  30   abs  67  30   37
Cromosome  2  10;04;13;14
F _ obj  2  abs  10  2*04  3*13  4*14   30   abs 107  30   77
Cromosome 3  12;05; 23;02
F _ obj 3  abs  12  2*05  3*23  4*02   30   abs  99  30   69
Cromosome  4   20;04;13;14
F _ obj  4  abs   20  2*04  3*13  4*14   30   abs 123  30   93
Cromosome 5  10;05;18;03
F _ obj 5  abs  10  2*05  3*18  4*03  30   abs 86  30   56
Cromosome  6   20;01;10;06
F _ obj  6  abs   20  2 *01  3*10  4*06   30   abs  76  30   46

În urma evaluării noului set de Cromozomi se poate observa că funcția obiectiv


descrește , ceea ce înseamnă că dispunem de o soluție mai bună în comparație cu
207
soluția reprezentată de anteriorul set de Cromozomi. Noii Cromozomi cu care vom
merge în următoarea iterație sunt:

Chromosome[1] = [02;05;17;01]
Chromosome[2] = [10;04;13;14]
Chromosome[3] = [12;05;23;02]
Chromosome[4] = [20;04;13;14]
Chromosome[5] = [10;05;18;03]
Chromosome[6] = [20;01;10;06]

Acești noi Cromozomi vor intra într-un proces similar celui prin care au trecut Cromozomii
din anterioara generație, format din evaluare, selecție, crossover și mutație, proces care se
va încheia prin generarea unei noi generații de Cromozomi într-o nouă iterație. Acest
proces se va repeta pentru un număr determinat de iterații. Pentru acest exemplu , după
rularea unui număr de 50 iterații cel mai bun Cromozom care se obține este:

Chromosome = [07; 05; 03; 01]


Aceasta însemnă că :
a = 7, b = 5, c = 3, d = 1
Dacă vom utiliza acest număr în ecuația
a +2 b +3 c +4 d = 30
Se va obține
7 + (2 * 5) + (3 * 3) + (4 * 1) = 30

Se observă că valorile variabilelor a, b, c și d generate printr-un algoritm genetic pot


satisface ecuația luată în discuție.

15.3. Reguli de codificare. Exemple de probleme specifice


Modul în care o posibilă soluție este codificată într-un cromozom depinde de
problema concretă. “Alfabetul” utilizat in reprezentarea genelor poate fi teoretic orice
alfabet, cele mai utilizate fiind:
 reprezentarea binară
 reprezentarea reală – specifică problemelor inginerești
 reprezentarea cu numere întregi

I.Codificarea binară.

208
Este varianta clasică. În acest caz cromozomii sunt vectori cu elemente din {0,1}
iar spaţiul de căutare este S = {0, l} , cu n numărul de gene (n este corelat cu
dimensiunea problemei). Este adecvată pentru problemele de optimizare
combinatorială (jocuri) în care configuraţiile pot fi specificate ca vectori binari. Un
cromozom poate arăta astfel

Fiecare cromozom este deci definit de un șir binar, unde un bit poate reprezenta o
caracteristică a soluției

Exemplul 1.
Problema maximizării numărului de biţi egali cu 1 (ONEMAX problem).
Se pune problema determinării şirului de biţi (xi,... ,xn), xi  {0,1n } care
maximizează funcţia


f : 0,1 n —  N , f x1 ,... , xn   n
j 1
xj

Problema este echivalentă cu a determina configuraţia de biţi care are cele mai multe
elemente egale cu 1. Aceasta este evident (1, ..., 1) problema fiind folosită pentru a testa
algoritmii genetici. Un exemplu este dat în continuare

Exemplul 2.

209
Problema submulţimii de sumă maximă limitată de un prag.
Se consideră o mulţime W = {w1,... ,wn} de valori întregi şi M o valoare întreagă.
Se caută o submulţime S  W cu proprietatea că suma elementelor lui S este cât mai
apropiată de M dar nu îl depăşeşte.
Orice submulţime S poate fi reprezentată printr-un vector (s1,s2,..., sn) cu sj = 0
dacă wi  S şi sj = 1 dacă wi  S.


n
Suma elementelor unei submulţimi S este în acest caz j 1
wi s j

De exemplu avem mulțimea W iar pragul este M=90

w1 w2 w3 w4 w5 w6 w7 w8

17 40 32 55 4 72 11 6

Cromozomul poate fi de exemplu

s1 s2 s3 s4 s5 s6 s7 s8
1 0 0 0 1 0 1 1

Exemplul 3.
Problema rucsacului - Knapsack problem.
Se consideră un set de n obiecte caracterizate prin greutăţile (w1,... ,wn) şi prin
valorile (v1,... ,vn). Se pune problema determinării unui subset de obiecte pentru a fi
introduse într-un rucsac de capacitate C astfel încât valoarea obiectelor selectate să fie
maximă. Un exemplu este dat în continuare.

210
Exemplu de problemă a rucsacului
 unidimensională (cu o singură constrângere):
Care cutii ar trebui să fie alese pentru a maximiza cantitatea de
bani în timp ce păstrează încă greutatea totală sub 15 kg?

 multidimensională (problemă cu mai multe constrângeri) ar putea


lua în considerare atât greutatea , volumul cutiilor cât și numărul
lor.
Remarcă
Problema rucsacului este o problemă de optimizare combinatorică⁠:
Dată fiind o mulțime de elemente, fiecare cu o greutate și o valoare, se
determină numărul din fiecare element al mulțimii care poate fi inclus într-o
colecție, astfel încât greutatea totală să fie mai mică sau egală cu o anumită
limită și valoarea totală să fie cât mai mare. Ea își trage numele de la problema
cu care se confruntă cineva care este obligat să umple un rucsac⁠ de dimensiune
fixă cu elementele cele mai valoroase. Problema apare adesea în alocarea
resurselor⁠ unde există constrângeri financiare⁠.

O soluţie a acestei probleme (în contextul utilizării unui algoritm genetic) poate fi
codificată ca un şir de n valori binare în felul următor: și = 1 dacă obiectul i este
selectat, respectiv și = 0 dacă obiectul nu este selectat.

Pentru 5 obiecte posibile de introdus în sac,


 genă reprezintă un bit (xi),
 în timp ce cromozomul este o soluţie potenţial (de exemplu 01101
înseamnă că articolele 2, 3 şi 5 vor fi incluse în rucsac).
Funcţia de adaptare / fitness indică cât de bună este o soluţie (cât este de
adaptat un cromozom).
De exemplu, presupunem că la un moment dat avem combinaţia:

Obiecte 1 2 3 4 5
Greutăți 70 55 40 15 5
wi
Valori 40 15 5 30 10
Vi

Atunci, pentru cromozomul: 01101,

211
constrângerea este: w = 55 + 40 + 5 = 100 ≤ C = 100 (ok), iar
funcţia de adaptare (fitness): v = 15 + 5 + 10 = 30

Exemplul 4.
Problema împachetării
Se consideră
 un set de n obiecte caracterizate prin dimensiunile (d1, d2,..., dn) şi
 un set de m cutii având capacităţile (c1, c2,..., cm).

Se pune problema plasării obiectelor în cutii astfel încât capacitatea acestora să


nu fie depăşită, iar numărul de cutii utilizate să fie cât mai mic. O posibilă
reprezentarea binară pentru această problemă este următoarea: se utilizează o
matrice cu n linii şi m coloane iar elementul Sij are valoarea 1 dacă obiectul i este
plasat în cutia j şi 0 în caz contrar. Prin liniarizarea matricii se ajunge ca fiecare
soluţie să fie reprezentată printr-un cromozom conţinând m*n gene.

212
II.Codificare reală.
Este adecvată pentru problemele de optimizare pe domenii continue (vezi
exemplul 5 următor). In acest caz cromozomii sunt vectori cu elemente reale, fiind
chiar elementele domeniului de definiţie al funcţiei (pentru exemplul următor
cromozomul este chiar x = (6.2945, 5.1548). Avantajul acestei reprezentări este
faptul că este naturală şi nu necesită proceduri speciale de
codificare/decodificare.

Exemplul 5.

Optimizarea unei funcţii definite pe un domeniu continuu.

Se consideră o funcţie

f : D   a1 , b1  x  a2 , b2  x.... an , bn   R n  R

şi se caută x* = (x1*,..., x*n) care minimizează funcţia f (f(x*) < f(x) pentru orice x
 D).

De exemplu avem funcția De Jong


de două variabile

f(x1, x2)= x1 + x2
cu
D = [ - 10, 10 ] x [ - 10 10 ]

Cromozomul este de forma

Cromozom x1 x2
1 6.2945 5.1548
2 8.1158 4.8626
3 -7.4603 -2.1555
4 8.2675 3.1096
5 2.6472 -6.5763
6 -8.0492 4.1209

III.Codificare specifică.
Se alege o variantă cât mai apropiată de specificul problemei.

213
Exemplul 6.
Problema împachetării
În varianta de codificare binară apare dezavantajul că pot fi generate configuraţii
care nu sunt fezabile. Acestea sunt de exemplu matricele care conţin mai multe valori
egale cu 1 pe o linie (aceasta ar însemna că un obiect este simultan inclus în mai multe
cutii). Pentru a evita astfel de situaţii se poate utiliza un alt tip de reprezentare:
 un vector cu n componente (s1,..., sn) în care
 si  {1,..., m} reprezintă cutia în care este inclus obiectul i.

Exemplul 7.
Problema comis-voiajorului
Se consideră un set de n oraşe şi se pune problema găsirii unui traseu care să
treacă o singură dată prin fiecare oraş şi care să aibă costul minim (dacă costul este
proporţional cu lungimea traseului atunci se caută trasee de lungime minimă).
Codificare naturală a unei configuraţii (traseu) este:
- (s1,..., sn) unde și  {1, ... , n} reprezintă numărul de ordine al oraşului vizitat
la etapa i (la fiecare etapa comis-voiajorul se află într-un oraş). Pentru a fi
respectată restricţia ca fiecare oraş să fie vizitat o singură dată este necesar
ca elementele vectorului s să fie distincte (si  sj pentru orice i  j). Astfel
fiecare configuraţie poate fi interpretată ca o permutare de ordin n, motiv
pentru care această codificare este numită şi codificare de tip permutare.

15.4. Reguli de decodificare


Decodificarea asigură pregătirea evaluării configuraţiei.

15.5. Construirea funcţiei de adaptare

Pentru a folosi analogia dintre procesele de căutare şi cele de evoluţie din natură
este util să se reformuleze problemele de optimizare ca probleme de maximizare (orice
problemă de minimizare poate fi transformată într-una de maximizare prin schimbarea
semnului funcţiei obiectiv).
„ Pentru o problemă de minimizare de forma: să se determine x*  D cu proprietatea că
f(x*) < f(x) pentru orice x  D, funcţia de adaptare are fi F(x) = -f(x). În cazul unei
probleme de maximizare atunci funcţia de adaptare poate fi chiar funcţia obiectiv.
În procesul de evoluție se folosește conceptul de fitness. Acesta definește cât de
214
departe este de obiectivul urmărit soluția curentă

Exemplul 8.
Problema ONEMAX.
În acest caz funcţia de adaptare coincide cu funcţia obiectiv a problemei,
calitatea unei soluţii fiind reflectată de numărul de componente egale cu 1.

Exemplul 9.
Problema comis-voiajorului.
În acest caz, dacă se foloseşte reprezentarea de tip permutare restricţia
problemei (trecerea o singură dată prin fiecare oraş) este implicit satisfăcută. Dacă
matricea C conţine costurile (c(i, j) reprezintă costul trecerii de la oraşul i la oraşul j)
atunci funcţia de cost poate fi descrisă prin:
n 1
f  s1.............sn    c  si , si 1   c  sn , s1 
j 1

În condiţiile în care costul trebuie minimizat, funcţia de adaptare va fi opusa funcţiei


cost.

15.6. Selecţia
Selecţia are ca scop determinarea populaţiei de părinţii care vor fi supuşi
operatorilor genetici de încrucişare şi mutaţie precum şi determinarea elementelor ce
vor face parte din generaţia următoare. Criteriul de selecţie se bazează pe gradul de
adaptare al configuraţiei la cerinţele problemei, exprimat prin valoarea funcţiei fitness.
Nu este obligatoriu ca atât părinţii cât şi supravieţuitorii se fie determinaţi prin
selecţie, fiind posibil ca aceasta să fie folosită doar într-o singură etapă. De exemplu, toţi
indivizii populaţiei curente sunt potenţiali părinţi dar după încrucişare şi mutaţie doar cei
determinaţi prin procesul de selecţie vor supravieţui. Pe de altă parte este posibil ca
părinţi să fie doar indivizii selectaţi iar toţi cei generaţi prin încrucişare şi mutaţie să fie
transferaţi în noua generaţie.
Procesul de selecţie nu depinde de modul de codificare a elementelor populaţiei
fiind însă legat de funcţia de adaptare.
Există mai multe metode de selecţie.

15.6.1. Elitismul
Această modalitate de selecţie presupune că cel mai adaptat individ este copiat
direct în noua populaţie (mai rar primii câţiva cei mai adaptaţi). Aceasta asigură faptul că
215
niciodată nu se va pierde soluţia cea mai bună.

15.6.2. Selecţia de tip ruletă


Ideea de bază a acestui tip de selecţie este că indivizii mai adaptaţi au şanse mai
mari. „Ruleta” se „învârte” de n ori pentru a se alege n indivizi. Părinții sunt selectați
funcție de fitness. În acest mod cel mai bun cromozom are cele mai mari șanse de a fi
selectat. Imaginea ruletei unde sunt amplasați toți cromozomii din populație , funcție de
mărimea valorii fitness pe care o prezintă este prezentată în figura următoare.

Prin activarea ruletei șansa va alege un cromozom. Este evident că cromozomul cu


valoarea de fitness cea mai mare va avea șansa de a fi selectat de cele mai multe ori.

Algoritmul prezintă următorul aspect:

1. Se calculează suma S a tuturor valorilor de fitness (adaptare) a cromozomilor din


populație (ale tuturor indivizilor din populaţie).
2. Se generează un număr aleator N între 1 şi S.
3. Se returnează cromozomul a cărui funcţie de adaptare adăugată la suma parţială
este ≥ N

Exemplu 1

Cromozom: 1 2 3 4 5 6
Fitness: 8 2 17 7 4 11
Suma 8 10 27 34 38 49
parţială:
1. Suma este 49
2. Numărul aleator generat N cu distribuție uniformă în intervalul [1 , 49] este : 23
3. Selectat: 3

216
Exemplu 2
Exemplu de folosire a ruletei pentru aflarea maximului funcției
1
f  x    x2  2x  5
4
în intervalul [0, 10]. Se utilizează un cromozom pe 10 biți. Pe 10 biți
valoarea maximă de reprezentare în baza 10 este 1023. Împărțind valoarea
cromozomului zecimală la 1023 se obține o valoare numerică pentru x în
intervalul 0 – 10 cu zecimale.
Pentru 5 cromozomi avem.

Nr. Cromozomi Valoare10 X Fitness %


= f(x) din
Valoare10 Total
1023

1 0001101011 107 1.05 6.82 31


2 1111011000 984 9.62 1.11 5
3 0100000101 261 2.55 8.48 38
4 1110100000 928 9.07 2.57 12
5 1110001011 907 8.87 3.08 14
TOTAL 22.05 100

15.6.3. Selecţia pe baza rangurilor


Principiu
Selecția de tip ruletă este deficitară atunci când funcțiile de fitness diferă foarte mult.
De exemplu dacă cel mai bun cromozom are o funcție de fitness care reprezintă 90%
din spațiul ruletei rezultă că restul cromozomilor vor avea o șansă foarte mică de a fi
selectați.
Selecția pe baza rangurilor atribuie fiecărui cromozom un număr de ordine (rang)
funcție de valoare fitness pe care o prezintă. Cromozomul cu cea mai rău fitness va
primi valoarea 1, următorul în ordinea valorii fitness va avea valoarea 2, etc. iar cel mai
bun valoarea N. Se partiționează ruleta in N sectoare. În acest mod toți cromozomii au
aceeași șansă de a fi selectați. Dezavantajul metodei constă în faptul că aceasta
converge mai lent deoarece toți membrii populației au aceiași șansă de a fi selectați

217
Situația înainte de numerotare (graful reprezintă valori fitness)

Situația după numerotare (graful reprezintă numere de ordine)

Algoritm
i. Se ordonează crescător valorile funcţiei de adaptare pentru toate elementele
populaţiei. Se reţin valorile distincte şi li se asociază câte un rang (cea mai mică
valoare are rangul 1, iar cea mai mare are rangul maxim). Se partiţionează
populaţia în grupuri de elemente care au aceeaşi valoare a funcţiei de adaptare şi
li se asociază rangul corespunzător valorii.
Presupunând că sunt k grupuri se construieşte distribuţia de probabilitate:

 1 2 .......... i ............. k  i
 p p ....... p .......... p  cu pi 

k
 1 2 i k 
j 1
j

Se generează câte un rang aleator în conformitatea cu distribuţia de mai sus (folosind


metoda ruletei de exemplu) după care se selectează uniform aleator un element din
grupul corespunzător rangului.
ii. O altă modalitate de stabilire a probabilităţilor de selecţie pornind de la rangul
elementelor este următoarea. Se ordonează crescător cele m elemente ale
populaţiei şi i se asociază câte un rang (0 pentru elementul cu cel mai mic grad de
adaptare şi m - 1 pentru elementul cu cel mai mare grad de adaptare).
Probabilitatea de selecţie a elementului i se calculează astfel:

   rang  i   /  m  1      
pi 
m
m
cu α < β valori alese astfel încât p
i 1
i  1 , ceea ce implică α + β = 2 care poate fi

interpretat ca numărul mediu de copii ale celui mai slab element iar / la numărul
218
mediu de copii ale celui mai bun element.

15.6.4. Selecţia de tip turnir


În acest caz se aleg aleatoriu k membri din populaţie şi se determină cel mai
adaptat dintre aceştia. Procedura se repetă pentru a selecta mai mulţi părinţi. Această
metodă este mai rapidă decât selecţiile prin ruletă sau ranguri. Probabilitatea selectării
individului i depinde de mărimea funcţiei de adaptare a lui i, precum şi de dimensiunea
eşantionului k. Turnirul poate fi determinist sau probabilistic.

15.6.5. Selecția de tip supraviețuitor

Politica de selecție de tip Survivor Selection, determină care indivizii urmează să


fie eliminați și cei care urmează să fie păstrați în generația următoare, astfel încât
diversitatea să fie să fie menținută în populație. Unii Algoritmi Genetici folosesc
Elitismul. În termeni simpli, aceasta înseamnă membrii cel mai promițători al populației
vor fi păstrați întotdeauna pentru următoarea generație ( prin urmare, în nici un caz
membrul populației cu fitness-ul cel mai bun nu va fi înlocuit). Cea mai simplă
modalitate de reducere a populației este aceea de a alege aleatoriu membri care
urmează să dispară în generația următoare. O astfel de abordare prezintă însă
dezavantajul că pot apare probleme de convergență spre optimul căutat (apar oscilații
în fitness-ul generațiilor care apar). Din acest considerent sunt utilizate pentru
reducerea populației următoarele strategii.

a) Selecția bazată pe fitness


În acest tip de selecție copii cei mai dotați vor înlocui membrii cei mai puțini dotați
din populație sau cei aleși prin strategii de tip ruletă, turnir etc. Un exemplu apare în
figura următoare unde membrii P1 și P10 sunt înlocuiți de cei mai dotați doi copii. Se
observă că P1 și P9 au același fitness. În astfel de situații alegerea dintre membrii cu
același fitness este aleatoare.

219
b) Selecția pe bază de vârstă
În selecția bazată pe vârstă nu mai apare noțiunea de fitness. Tehnica plecă de
la premisa că fiecare membru al populației poate rămâne și se poate reproduce,
indiferent de valoarea fitness pe care o prezintă un interval de timp determinat. Acest
criteriu de timp poate, de exemplu, fi dat de numărul de generații în care respectivul
membru a fost prezent în populație În exemplul dat în figura următoare cei mai vechi
membrii ai populației sunt P4 și P7. Aceștia sunt eliminați,înlocuiți eventual de copii lor,
iar vârsta pentru restul de membrii se incrementează cu 1.

15.7. Încrucişarea -Crossover


Încrucişarea permite combinarea informaţiilor provenite de la doi sau mai mulţi
părinţi pentru generarea unuia sau mai multor urmaşi. Vom considera doar cazul a doi
părinţi (notaţi cu x şi y) care generează doi urmaşi (notaţi cu x' şi y'). încrucişarea
(numită uneori recombinare) depinde de modul de codificare a datelor aplicându-se
direct asupra cromozomilor.

Tipuri de recombinări:

 Pentru valori binare (incrucisare-crossover):


- Încrucișare cu un singur punct / cu doua puncte /cu puncte multiple
- încrucișare uniforma

 Pentru valori reale:

220
- Recombinare intermediara
- Recombinare liniara
- Recombinare liniara extinsa

15.7.1 Variante specifice codificării binare


(cromozomul este o succesiune de n cifre binare)

Încrucişarea cu un punct de tăiere. Se alege în mod aleator un k  {l,..., n - 1}


numit punct de tăietură (încrucişare) şi se construiesc urmaşii în modul următor:
x'= (xi,...,xk,yk+i,...yn) şi y' = (yu ... ,yk,xk+i,.. .xn).

Încrucişarea cu două sau mai multe puncte de tăiere se realizează asemănător


cu cea de mai sus, doar că pot exista mai multe puncte de taiere.

221
Încrucişarea uniformă. La construirea fiecărui urmaş se selectează cu probabilitatea p
o genă din primul părinte şi cu probabilitatea 1-p o genă din al doilea părinte.
A. Cazul cel mai natural este cel în care p = 0.5.

15.7.2 Variante specifice codificării reale


(cromozomul este o succesiune de cifre reale)

Recombinare aritmetică.
Crossoverul aritmetic intermediar combină materialul genetic al părinților P1 și P2
aplicând regulile
VarjU   j  VarjP1  1   j   VarjP 2 j=1,2, ... , Nvar

VarjU - reprezintă variabila j a urmașului

VarjP1 , VarjP 2 - reprezintă variabila j a primului părinte, respective a celui de al

doilea părinte
α – reprezintă factorul de scalare generat aleator în intervalul [-d , 1+d ].
Uzual d=0.25

Domeniul de valori ale descendenților fata de cel al parinților

222
Aria posibilă a urmașilor apare în figura de mai jos

Exemplificare
Presupunem că cromozomii celor doi părinți sunt de forma

Cromozomi
P1 -1 6
P2 0 -2

Se consideră d=0.25.
- Pentru generarea primului copil C1, s-au generat aleatoriu valorile ponderilor
α 1=1.1 pentru prima variabilă și α 2=0.7 pentru cea de a doua variabilă.
Valorile variabilelor primului copil sunt

Var1C1  1.1  1  1  1.1  0  1.1


Var1C1  0.7   6   1  0.7    2   3.6

Cromozom
C1 -1.1 3.6

- Pentru cel de al doilea copil C2 , s-au generat aleatoriu valorile ponderilor


α 1=0.2 pentru prima variabilă și α 2=-0.15 pentru cea de a doua variabilă.
Valorile variabilelor pentru cel de al doilea copil sunt

Var1C2  0.2   1  1  0.2  0  0.2


Var1C2  0.15   6  1   0.15    2   3.2

223
Cromozom
C2 -0.2 -3.2

Recombinarea liniară
Este similară cu cea intermediară cu deosebirea că se utilizează un singur factor de
scalare α care se generează de asemenea aleatoriu în intervalul [-d , 1+d ].
Relațiile de calcul sunt de forma

VarjU   j  VarjP1  1   j   VarjP 2 j=1,2, ... , Nvar

VarjU - reprezintă variabila j a urmașului

VarjP1 , VarjP 2 - reprezintă variabila j a primului părinte, respective a celui de al

doilea părinte
α – reprezintă factorul de scalare generat aleator în intervalul [-d , 1+d ].
Uzual d=0.25

Astfel copiii vor fi plasați pe un segment de dreaptă determinat de genele părinților.

Exemplificare
Presupunem că cromozomii celor doi părinți sunt de forma

Cromozomi
P1 -1 6
P2 0 -2

Se consideră d=0.25.
- Pentru generarea primului copil C1, s-au generat aleatoriu valorile ponderilor

224
α 1=1.1 pentru ambele variabile.

Valorile variabilelor primului copil sunt

Var1C1  1.1  1  1  1.1  0  1.1


Var1C1  1.1  6   1  1.1   2   6.8

Cromozom
C1 -1. 6.8

- Pentru cel de al doilea copil C2 , s-au generat aleatoriu valorile ponderilor


α 1 =0.2 pentru ambele variabile.
Valorile variabilelor pentru cel de al doilea copil sunt

Var1C2  0.2   1  1  0.2   0  0.2


Var1C2  0.2   6   1  0.2    2   0.4

Cromozom
C2 -0.2 -0.4

Dacă reluăm formula de recombinare prezentată anterior pentru cazul a doi părinți într-o
formă simplificată vom avea
Copil1   gx  1   gy
Copil2   gx  1   gy

Atunci pentru α=0.5 cei doi copii vor fi identici, aspect care poate fi văzut în imaginea de
mai jos

225
15.8. Mutaţia
Mutaţia realizează mici schimbări aleatoare în una sau mai multe variabile ale
individului supus mutaţiei. În felul acesta este asigurată diversitatea populaţiei.
Trebuie definite:
- Probabilitatea ca o variabila sa sufere o mutație(rata de mutație)
o Este invers proporționala cu numărul variabilelor
o O valoare optima se poate considera 1/Nvar
o o singura variabila a unui individ suferă procesul de mutație
- Valoarea schimbării variabilei prin procesul de mutație

A. Mutația pentru variabile binare


În cazul codificării binare cel mai simplu şi frecvent operator de mutaţie este cel în care
se selectează aleator un cromozom, în cadrul acestuia se selectează o genă iar valoarea
acesteia este modificată (0 devine 1 iar 1 devine 0). în funcţie de modul în care se
selectează cromozomii şi genele există diverse variante.
i. De exemplu pentru fiecare cromozom se decide cu o anumită probabilitate (pm,
numită probabilitate de mutaţie) dacă el va fi supus mutaţiei sau nu. În caz afirmativ
se selectează (uniform aleator) o genă şi valoarea acesteia se modifică. În felul
acesta într-un cromozom poate fi modificată o singură genă. În exemplul de mai jos
biții selectați sunt inversați.

ii. O altă variantă este aceea în care toate genele se consideră ca făcând parte din
aceeaşi structură şi pentru fiecare dintre ele se decide dacă va fi modificată sau nu.
In felul acesta este posibil ca mai multe gene din cadrul unui cromozom să fie
modificate. În cazul codificării de tip permutare mutaţia cea mai simplă constă în
schimbarea poziţiei a două elemente. De exemplu de la configuraţia (D, C, F, A, B, E,
G) se ajunge la configuraţia (D, C, E, A, B, F, G) prin interschimbarea elementelor de
pe poziţiile 3 şi 6.
iii. Mutația uniformă modifică valoarea unor gene alese aleatoriu.
Cromozomul c = (c(1), c(2),..., c(k),..., c(LIND)) este transformat în
cm = (c(1), c(2),..., cm(k),..., c(LIND)).
226
Gena cm(k) va fi selectată în mod aleator din intervalul [c(k)-a; c(k)+a], a>0. Şi
operatorul de mutaţie este aplicat cu o probabilitate notată cu pm, care trebuie să fie
mică, de exemplu între 0.01 - 0.03.

B. Mutația pentru variabile reale


Se utilizează în principal o mutație de tip gaussian. Aceasta constă în adăugarea
unui număr ales aleator dintr-o distribuţie gaussiană cu media 0.
Derivaţia standard a distribuţiei este precizată prin doi parametri:
 scale - determină deviaţia standard pentru prima epocă,
 shrink - controlează modul în care se micşorează deviaţia standard o dată cu
avansul algoritmului.
În acest fel mutaţia este mai puternică la începutul algoritmului şi tot “mai slabă” pe
măsură ce algoritmul avansează și se creează generaţii noi.

Mutația de acest tip presupune


În generaţia k, pentru variabila j a părintelui supus mutației se calculează:
VarjC  VarjP  rj  d j  scalek
rj - aleator ales dintr-o distribuţie gaussiană normală cu centrul în zero;
dj - reprezintă mărimea domeniul în care ia valori această variabilă,
adică dj=Varj,max – Varj,min
 k
scalek  scale  1  shrink  
 N
N - numărul maxim de generaţii ales ca şi condiţie de oprire

Exemplificare

N=100 k=50 scale=1, shrink=1

 50 
scale50  1 1  1   0.5
 100 
domeniul de valori este [-10; 10] d1=d2=20

Cromozom
Părinte -3 1

227
r1  0.05 Var1C  3   0,05  20  0.5  2.5
r1  0.2 Var2C  1    0.2  20  0.5  1

Cromozom
Părinte -2.5 -1

15.9. Domenii de aplicabilitate


Algoritmii evolutivi sunt utilizați în general pentru probleme de optimizare, atunci când
nu există altă strategie de rezolvare a problemei şi este acceptat un răspuns aproximativ.

15.9.1. Arhitectura unui joc. Strategia de definire a funcțiilor de evaluare

Î n contextul realizării unui joc strategic, este necesar să fie rezolvate două
probleme:
• alegerea unor algoritmi de căutare eficienţi (algoritmii de căutare în spaţiul
stărilor sunt preluaţi din teoria jocurilor) şi
• găsirea unei funcţii/unor funcţii eficiente pentru jucătorul calculator (este
abordată prin utilizarea algoritmilor genetici).

Componente AI la implementarea unui joc (pentru jucător calculator)

Un joc strategic are trei faze. În continuare, prin:


- faza 1 ne vom referi la faza de început joc (aşezare) a pieselor,
- faza 2 va însemna faza de joc propriu zisa ( mutarea pieselor)
- faza 3 reprezintă finalul de joc.
În contextul acestor faze obiectivele pentru jucătorul calculator vor face referire la
228
algoritmii folosiţi pentru căutare şi pentru obţinerea estimatorilor:

1. Se implementează algoritmi de tip Alfa-Beta .

2. Algoritmii vor trebui sa funcționeze pe mai multe nivele de căutare


(corespunzătoare adâncimii arborelui de căutare) în funcţie de nivelul de dificultate
ales de jucător (spre exemplu pentru Beginer se va merge pe 3 nivele, în schimb la
Advanced pe 5 sau chiar 6 nivele)

3. Se vor implementa 3 nivele de dificultate: Beginer, Intermediate, Advanced;


fiecare va avea o adâncime prestabilită, adaptată astfel încât jocul să nu ruleze
prea încet.

4. Pentru optimizarea căutării, în loc de o singură adâncime pentru un nivel de


dificultate se va implementa o funcţie, care stabileşte adâncimea în funcţie de
faza jocului. Spre exemplu la început şi sfârşit nu se poate opta pentru o adâncime
foarte mare, fiind mai puţine piese, există foarte multe posibilităţi de a muta şi astfel
arborele creşte mult în lăţime şi timpul va fi prea lung. Spre exemplu pentru
Advanced funcţia poate dicta adâncimea 4 pentru faza 1 şi faza 3 a jocului şi 6
pentru faza 2 (mutare piese).

5. Estimatorul care dictează valoarea unei configuraţii de joc se va compune din


2 estimatori parţiali (pentru fiecare jucător în parte configuraţia are câte o valoare);
prin scăderea lor se află care este în avantaj.

6. In general estimatorul este compus din 3 funcţii de evaluare, câte una pentru
fiecare fază a jocului; este necesară această diferenţiere, deoarece relaţii între piese
ce sunt importante în faza 1 pot să nu fie relevante în faza 2 sau 3.

7. O funcţie de evaluare este suma produselor dintre relaţii şi coeficienţi de ponderare


a calității pieselor.

 Relaţiile reprezintă relaţiile între piese, considerate relevante, acestea urmează


sa fie specificate funcție de tipul jocului către programator. Relaţiile sunt fixe şi
configurarea estimatorului se va face numai prin setarea coeficienților (pentru a
renunţa la un atribut se va pune coeficientul asociat pe 0)
 coeficienţii reprezintă punctajul acordat pieselor
 Vor exista 3 categorii de estimatori:
 estimatorii setaţi de constructorul jocului prin logica sa, prin modul în care
a înţeles jocul;
 estimatori configuraţi de utilizator in momentul începerii jocului;
 estimatori obţinuţi prin evoluţie
 Estimatorii setaţi de utilizator sunt de doua categorii:
- offence (axat pe atac) şi
- defense (axat pe apărare)
 Estimatorii configuraţi de utilizator sunt tot în număr de 2 (pentru a putea juca
229
un meci între doua configuraţii diferite); se configurează din interfaţa grafică şi se
pot alege de la setările pentru jucătorul PC
 Estimatorii din a 3-a categorie apar în urma unui proces de evoluţie (tehnica
este utilizata in prezent), cu următoarele obiective:
a. Generarea a 50 estimatori (seturi de coeficienţi) aleator
b. Trecerea lor printr-o confruntare (intre 2000 - 5000 meciuri)
c. Selecţia celor mai buni 10
d. Supunerea lor la un proces de împerechere (algoritm genetic) + mutaţie
e. Reluarea confruntării şi reluarea procesului de evoluţie (punctele b-e)
până la obținerea unei calități mulţumitoare pentru jocul in cauza;

Generarea şi evoluţia estimatorilor

Inițial se stabilește numărul de indivizi (cromozomi) ai unei generaţii ( sa


presupunem ca sunt 50).
În pasul 1, se pleacă de la o primă generaţie stabilită aleator, pentru 50 de
estimatori diferiţi se generează câte n coeficienţi (n este numărul de coeficienți a
funcției de evaluare - sa presupunem ca n=17) .
În pasul 2 Asupra acestui set de 50 de estimatori, în pasul 2, se aplică un algoritm
de competiţie. Fiecare estimator va juca un joc cu fiecare. Dacă notăm estimatorii cu E0
- E49, E0 va juca câte un meci cu E1 - E49 şi aşa mai departe. E49 va juca cu E0 - E48.
În fiecare joc vom avea Jucătorul 1 şi Jucătorul 2 (Jucătorul 1 începe tot timpul).
Deoarece de obicei este important cine începe jocul, acela fiind considerat avantajat la
început, între doi estimatori diferiţi se vor disputa două jocuri, fiecare având dreptul
odată la să fie primul. Spre exemplu, între E3 şi E7 se vor juca două jocuri : E3 vs E7 şi
E7 vs E3. Un estimator nu va juca împotriva sa, acesta fiind un meci irelevant şi
considerat din start remiză. Rezultatul unui joc poate fi: câştigător jucătorul 1, câştigător
jucătorul 2 şi remiză. Turnamentul va consta din 1000 - 3000 de jocuri. Pentru a evita
jucarea la infinit a unei partide, se pune o limită la numărul de mutări posibile în joc, iar
dacă nici un jucător nu câştigă în decurs de un număr stabilit de mutări, rezultatul va fi
remiză.
La pasul 3, se face selecţia celor mai buni estimatori prin calcularea numărului de
meciuri câştigate de fiecare. Fiecare estimator va avea un punctaj asociat, (de exemplu
5 puncte pentru fiecare joc câştigat). Se vor selecta dintre estimatori cei mai buni 10,
care vor face parte din generaţia viitoare. Generaţia viitoare se va compune din cei 10
plus încă 40 rezultaţi din încrucişarea acestora. Deoarece avem un număr fix de părinţi

230
10 şi vrem să obţinem 40 de fii,funcţia de fitness va atribui fiecărui părinte o valoare ce
reprezintă numărul de încrucișări la care va lua parte
La pasul 4 În acest pas, folosindu-se funcţia de fitness de mai sus, se generează
cei 40 de membrii ai noii generaţii. Fiecare estimator va avea asociată o variabilă care
atestă posibilitatea acestuia de a participa la încrucişare. După fiecare încrucişare se
decrementează valoarea. Când se ajunge la 0, cromozomul respectiv nu mai are
dreptul la încrucişare. Cromozomii părinţi (estimatorii) sunt generaţi aleator. După ce
participă la o încrucişare, se decrementează variabila asociată ce ne informează
asupra posibilităţii de încrucişare. Dacă se generează aleator un cromozom care nu
mai are dreptul să participe, se va genera altul şi în cazul unui nou eşec, se verifică pe
rând pentru fiecare estimator variabila (posibilitatea de încrucișare) şi se ia primul găsit
pentru care valoarea acelei variabile este mai mare decât 0.
Pentru încrucişare, se utilizează de obicei un algoritmul genetic cu un punct de
tăiere. Se generează aleator un punct şi se interschimbă şirurile de coeficienţi ai celor
doi estimatori părinţi.
Pasul 5 arată punerea împreună a părinţilor şi fiilor pentru a forma noua
generaţie. La estimatorii rezultaţi se aplică aleator mutaţia, un factor important al
procesului de evoluţie care asigură varietate. Mutaţia poate apărea la spre exemplu la
5% din membrii generaţiei şi constă din alterarea unei gene, dar alterarea să fie mică. În
cazul nostru, vom acţiona prin modificarea mică (cu câteva unităţi) a câte unui coeficient
(un coeficient este echivalent cu o genă în cazul nostru) la 2 sau 3 fii din cei 40.

La pasul 6 In acest pas se trece la o competiţie între noii estimatori. Turnamentul


(competiţia) se desfăşoară la fel ca cel de la pasul 2. Săgeata întreruptă ce duce înapoi
la pasul 3 indică faptul că algoritmul de selecţie şi de evoluţie se poate aplica iterativ, de
câte ori este nevoie, până când se ajunge la rezultate mulţumitoare.
Pasul 7 se compune din selectarea celor mai buni 4 estimatori (rezultaţi după
ultima competiţie) şi aceştia se vor supune unor altfel de teste. Aceste teste constau în
jocuri împotriva jucătorilor umani. Puterea acestor estimatori rămâne relativă cât timp se
fac teste doar între estimatori, deoarece pot fi buni în competiţii împotriva altor
estimatori, dar pot fi slabi pentru un adversar uman. De aceea, înainte de a fi introduşi
în joc, aceştia sunt testaţi cu jucători umani. Schema de lucru utilizată este redată grafic
figura de mai jos.
Din generaţia 1 supusă competiţiei se aleg cei mai buni 10 estimatori.
Aceştia sunt supuşi algoritmului de evoluţie genetică, prin încrucişare şi mutaţie
obţinându-se generaţia doi de estimator. Analog, din cei mai buni estimatori ai
generaţiei 2 se va obţine generaţia 3 de estimatori. De-a lungul procesului, se
231
colectează 8 estimatori, 4 cei mai buni din a doua generaţie şi 4 cei mai buni din a treia
generaţie. În urma testelor cu jucători umani la care sunt supuşi, dintre cei 8 se aleg 4
care sunt cei mai buni.

Schema de principiu a evoluţiei estimatorilor în contextul jocurilor strategice.

232
16. CALCULUL EVOLUȚIONIST

Algoritmii genetici prezentați în capitolul 15 se caracterizează prin faptul că au


la bază conceptul de populație ca reprezentare, și conceptul de evoluție ca
proces de căutare a soluției.

Există o altă generație de algoritmi, care au la bază tot conceptul de populație


pentru reprezentarea soluțiilor, dar în procesul de căutare a soluției, baza nu o
reprezintă evoluția, ci interacțiunile sociale între membrii populației.

Principalii algoritmi, care de altfel au o puternică componentă socială, bazându-se


pe conceptul de „inteligență colectivă”, sunt:
 Ant Colony Optimization (ACO),
 Bee Colony Optimization (BCO),
 Particle Swarm Optimization (PSO),

16.1 Ant Colony Optimization


Ant Colony Optimization (ACO) a fost introdus în 1991-1992 de către M. Dorigo
(Dorigo, M. and Maniezzo, V. (1996). The ant system: optimization by a colony of
cooperating agents, IEEE Transactions on Systems, Man, and Cybernetics, 26(1), 1-13)
ca o nouă meta-euristică pentru optimizarea combinatorială, a căror rezolvare se poate
reduce la a găsi cel mai bun drum într-un graf. Inițial, algoritmul avea ca scop de a găsi
drumul optim într-un graf, într-un mod asemănător celui în care furnicile găsesc drumul
ideal de la colonie spre o sursă de hrană. De-a lungul timpului, ideea a fost modificată
astfel încă la momentul de faţă poate fii utilizat într-o gamă variată de probleme.

Furnicile în natură
În principiu, algoritmul se bazează pe faptul că furnicile călătoresc la întâmplare. În
momentul în care ele găsesc o sursă de hrană, marchează drumul până la colonie cu
feromoni. Studiile au arătat că acest lucru este posibil datorită unei substanţe, numită

233
feromon, cu care furnicile marchează traseul pe care îl urmează. O furnică lasă o urmă
de feromon pe unde circulă şi este influenţată de mirosul de feromon lăsat de alte
furnici. Feromonul este supus, odată cu trecerea timpului, fenomenului de evaporare.
Studiile au arătat că dacă pe traseul dintre muşuroi (N) si sursa de hrană (F) se
plasează un obstacol, după un timp toate furnicile îl vor ocoli pe drumul cel mai scurt.
Explicaţia este următoarea: când primele furnici ajung la obstacol ele aleg sa îl
ocolească prin partea stângă sau prin partea dreaptă cu o probabilitate egală. La
întoarcere mirosul de feromon de pe traseul mai lung este mai slab decât cel de pe
traseul mai scurt datorita fenomenului de evaporare. Prin urmare mai multe furnici vor
urma calea mai scurtă. După un anumit număr de ture efectuate între cele două
destinaţii, toate furnicile se vor deplasa pe traseul cel mai scurt.

Modelul coloniei de furnici: Ant Colony Optimization (ACO)


Este folosit în special în rezolvarea problemelor de optimizare combinatorială
(identificare trasee optime, planificare). Ideea de bază este de a utiliza o populație de
furnici artificiale (agenți). Fiecare dintre acești agenți construiește la fiecare generație
câte o soluție. Completarea componentelor soluțiilor se realizează în manieră
probabilistă iar probabilitățile de selecție a uneia sau alteia dintre valorile posibile se
calculează folosind:
234
 atât informații de natură locală privind problema de rezolvat (ceea ce observă
furnica) cât și
 informații de natură globală (obținute prin comunicarea indirectă dintre furnici
prin intermediul feromonilor).

Modelul presupune:
 Datele de intrare ale problemei corespund grafului asociat problemei
combinatoriale și a costurilor acestor drumuri (matricea de costuri).
 Se folosește o populație de m furnici plasate inițial aleator în noduri (se poate
considera că toate furnicile sunt inițial plasate în același nod – de exemplu în
primul nod).
 La fiecare generație, fiecare furnică efectuează n deplasări între noduri. Furnicile
memorează nodurile vizitate astfel încât să nu treacă de două ori prin același
nod. Trecerea furnicii k din nodul i în nodul j, la etapa t, se bazează pe
distribuția de probabilitate:

  ijij
 j nu a fost vizita
Pt k  i, j      il il
  

  
lN i , k


0 j a fost vizitat

Factorii ce intervin în calculul probabilității au următoarea semnificație:


1.  ij modelează cantitatea de feromoni depusă de furnici pe arcul (i,j); se

inițializează aleator și după fiecare generație este actualizat de către fiecare


furnică k care a parcurs arcul respectiv, după regula:
 ij  1    ij  Qij / cos t Tk 
- ρ este un coeficient subunitar care controlează evaporarea feromonului,
- Qij este 0 daca (i,j) nu aparține traseului parcurs de furnica k și este diferit de 0
în caz contrar (în cazul cel mai simplu Q=1). Practic se modelează dificultatea
drumului, în ce masură calitatea acestuia influențează cantitatea de de
feromoni depusă.

235
- cost(Tk) reprezintă costul traseului.
2. ηij modelează informația locală privind calitatea arcului; cea mai simplă variantă
este când ηij este invers proporțional cu costul arcului (i,j)

α si β sunt parametri care controlează ponderea relativă a celor două tipuri de


informații:cea furnizată de concentrația de feromoni și cea bazată pe informația locală
privind calitatea arcului. Se va menține un echilibru între

 explorare (α) -- situația în care furnicile vor merge aleatoriu, și

 exploatare (β) -- situația în care furnicile vor urma o cale marcată cu


feromoni.

Funcție de valoarea acestor doi parametrii furnicile vor fi ori orientate mai mult:

 spre a găsi noi surse de hrană și mai puțin spre exploatarea surselor deja
existente fie

 spre exploatarea cu precădere a surselor existente în detrimentul găsirii de noi


surse de hrană.

 Daca α = 0 avem numai exploatare iar dacă β = 0 avem numai explorare

3. N(i,k) reprezintă lista vecinilor nodului i care nu au fost încă vizitați de către furnica k

Vom studia în continuare, cum un proces similar poate fi utilizat într-o lume
locuită de furnici artificiale care să încerce să rezolve problema comis-voiajorului.

Problema comis-voiajorului (TSP) este problema găsirii celui mai scurt tur închis care
vizitează toate oraşele dintr-un set dat. Se consideră problema TSP restricţionată la
cazul în care, oraşele se află situate într-un plan şi există o cale între fiecare două oraşe
(graful TSP este complet conectat).

236
Algoritmul Ant Colony Optimization (ACO) pentru TSP

 Se amplasează aleatoriu furnicile în orașe


 Pentru fiecare furnică
1. Se alege un oraș care nu a fost încă vizitat (până când un tur este
completat)
2. Se optimizează turul
3. Se actualizează feromonul  ij   1/ lenght  tour 

 Se activează evaporarea feromonului  ij  1    ij

Presupunem că avem o problem de tip TSP cu 5 orașe. Distanța dintre orașe este dată
de următoarea matrice

 0 10 12 11 14 
10 0 13 15 8 
 
D  12 13 0 9 14 
 
11 15 9 9 16 
14 8 14 16 0 
Se cere determinarea celei mai bune rute care are o distanță minimă utilizând ACO

Pasul 1:
Presupunem că numărul de furnici este N=3. Determinăm vizibilitatea (h) între
orașe luând în considerare că acesta este egală cu inversul distanței 1 / d.

Se obține
 0 0.1000 0.0833 0.0909 0.0714 
0.1000 0 0.0769 0.0667 0.1250 

h   0.0833 0.0769 0 0.1111 0.0714 
 
0.0909 0.0667 0.1111 0 0.0625
0.0714 0.1250 0.0714 0.0625 0 

237
Pentru fiecare segment între orașe vom considera că feromonul are o valoare
inițială  0 , și presupunem că prezintă aceeași valoare pentru toate segmentele fiind

egală cu 1.

1 1 1 1 1
1 1 1 1 1

 o  1 1 1 1 1
 
1 1 1 1 1
1 1 1 1 1

Pasul 2:
Se determină probabilitatea de a trece de la un oraș la altul. În acest caz
considerăm că orașul 1 este punctul de plecare. Acest aspect, impune ca din ultimul
oraș vizitat să ne reîntoarcem înapoi în orașul 1. Deoarece orașul 1 este ales ca oraș
de plecare el nu va mai putea fi vizitat din nou, astfel că nivelul de vizibilitate a acestui
oraș este setat pe 0.

0 0.1000 0.0833 0.0909 0.0714 


0 0 0.0769 0.0667 0.1250 

h  0 0.0769 0 0.1111 0.0714 
 
0 0.0667 0.1111 0 0.0625 
0 0.1250 0.0714 0.0625 0 
În acest pas se va trece la calculul posibilității de vizitare a altor orașe din orașul 1. În
acest scop se va utiliza următoarea relație

   r , s    r , s 
 dacă s  M k

pk  r , s        
 
 r , u  r , u
 uM k
 0 dacă orasul a fost vizitat
Unde
 pk  r , s  este probabilitatea de mișcare din orașul r spre orașul s a furnicii k

  este nivelul feromonului

238
   r , s  este vizibilitatea orașului s din r

 M k este mulțimea orașelor posibile de vizitat de furnica k


  este ponderea feromonului 
  este ponderea controlului vizibilității. De obicei se ia  =1 și  =2
Presupunem că furnica 1 din orașul 1 va alege să meargă în următorul oraș conform
următoarei alegeri

 1, s   1, s  Din orașul 1 spre toate celelalte orașe


1 2

1 x 0.12 = 0.01 Din orașul 1 spre 2


1 x 0.083322 = 0.0069 Din orașul 1 spre 3
2
1 x 0.09092 = 0.0083 Din orașul 1 spre 4
1 x 0.071422 = 0.0051 Din orașul 1 spre 5

  1, s   1, s  =0.033


1 2

s  2,3,4,5

Astfel că probabilitatea ca furnica 1 să meargă din orașul 1 spre unul din celelalte orașe
este dată de relația

 1, s   1, s 
1 2

p1 1, s  
  1, s   1, s 
1 2

s  2,3,4,5

Probabilitatea de a merge din Probabilitățile cumulate

Orașul 1 spre 2 = 0.01 / 0.0303 = 0.3299 0.3299


Orașul 1 spre 3 = 0.0069 / 0.0303 = 0.2291 0.5590
Orașul 1 spre 4 = 0.0083 / 0.0303 = 0.2727 0.8317
Orașul 1 spre 5 = 0.0051 / 0.0303 = 0.1683 1

239
Pasul 3
Se va genera un număr aleatoriu uniform distribuit pentru a determina care oraș
se vizitează prin compararea acestei valori cu probabilitățile cumulate. Presupunem că
generăm numărul r=0.6841. Prin compararea acestuia cu probabilitățile cumulate
observăm că acesta este situat sub valoarea 0.8317. Astfel alegerea furnicii este aceea
de a vizita orașul 4.

Deoarece orașul 4 a fost selectat vizibilitatea acestui oraș pentru furnica 1 se va seta pe
0, astfel încât matricea aferentă va apare de forma
0 0.1000 0.0833 0 0.0714
0 0 0.0769 0 0.1250

h  0 0.0769 0 0 0.0714
 
0 0.0667 0.1111 0 0.0625
0 0.1250 0.0714 0 0 

Se pune din nou problema alegerii următorului oraș ( cu excepția orașului 1 ) spre care
se va efectua deplasarea din orașul 4. Vom avea

  4, s    4, s  Din orașul 4 spre toate celelalte orașe


1 2

(cu excepția orașului 1)

1 x 0.066722 = 0.0044 Din orașul 4 spre 2


1 x 0.111122 = 0.0123 Din orașul 4 spre 3
1 x 0.02 = 0.0 Din orașul 4 spre 4
1 x 0.071422 = 0.0039 Din orașul 4 spre 5

   4, s    4, s 
1 2
=0.0207
s  2,3,5

Astfel că probabilitatea ca furnica 1 să meargă din orașul 4 spre unul din celelalte orașe
este dată de relația

240
  4, s    4, s 
1 2

p1  4, s  
   4, s    4, s 
1 2

s  2,3,5

Probabilitatea de a merge din Probabilitățile cumulate

Orașul 4 spre 2 = 0.0044 / 0.0207 = 0.2147 0.2147


Orașul 4 spre 3 = 0.0123 / 0.0207 = 0.5965 0.8113
Orașul 4 spre 4 = 0.0 / 0.0207 = 0.0 0.8113
Orașul 4 spre 5 = 0.0039 / 0.0207 = 0.1887 1

Se va genera un număr aleatoriu uniform distribuit pentru a determina care oraș se


vizitează prin compararea acestei valori cu probabilitățile cumulate. Presupunem că
generăm numărul r=0.4024. Prin compararea acestuia cu probabilitățile cumulate
observăm că acesta este situat sub valoarea 0.8113. Astfel alegerea furnicii este aceea
de a vizita orașul 3.
Până în acest moment ruta pe care s-a deplasat furnica 1 este 1-4-3.
Acest pas este repetat pentru toate furnicile. Fiecare rută parcursă de oricare din cele
trei furnici va trece prin fiecare din orașe va avea următoarele distanțe.

Furnica Rută Distanță pentru fiecare rută


1 1-4-3-5-2-1 52
2 1-4-2-5-3-1 60
3 1-4-5-2-3-1 60

Distanța totală este utilizată pentru a actualiza nivelul feromonilor cu relația

 r ,s  1    r ,s  k 1  k
N
r ,s

241
Pasul 4:
Toate furnicile vor aduna o cantitate suplimentară de feromon la matricea feromonilor în
concordanță cu ruta pe care o parcurg.
 Cantitatea depusă este egală  r ,s   1/ lenght  tour  pe fiecare segment care leagă

două orașe
 În același timp apare un fenomen de evaporare a feromonului. Evaporarea este
dată de relația  r , s  1    r ,s

 Pentru cazul prezent avem în acest pas  r , s = 1 iar rata de evaporare  = 0.5

Furnica 1 va aduce un surplus de feromon de 1 / 52 = 0.0192, timp în care reducerea


de feromon datorită evaporării este (1 - 0.5) x 1 = 0.5. Vom obține pentru furnica 1 care
parcurge drumul 1-4-3-5-2-1 următoarea matrice de feromoni.

0.5000 0.5000 0.5000 0.5912 0.5000


0.5192 0.5000 0.5000 0.5000 0.5000

0.5000 0.5000 0.5000 0.5000 0.5192
 
0.5000 0.5000 0.5192 0.5000 0.5000
0.5000 0.5192 0.5000 0.5000 0.5000

Furnica 2 va aduce un surplus de feromon de 1 / 60 = 0.0167, timp în care reducerea


de feromon datorită evaporării este (1 - 0.5) x 1 = 0.5. Vom obține pentru furnica 2 care
parcurge drumul 1-4-2-5-3-1 următoarea matrice de feromoni.

 0.5000 0.5000 0.5000 0.5359 0.5000 


 0.5192 0.5000 0.5000 0.5000 0.5167 

0.5167 0.5000 0.5000 0.5000 0.5192 
 
 0.5000 0.5167 0.5192 0.5000 0.5000 
 0.5000 0.5192 0.5167 0.5000 0.5000 

242
Furnica 3 va aduce un surplus de feromon de 1 / 60 = 0.0167, timp în care reducerea
de feromon datorită evaporării este (1 - 0.5) x 1 = 0.5. Vom obține pentru furnica 3 care
parcurge drumul 1-4-5-2-3-1 următoarea matrice de feromoni.

0.5000 0.5000 0.5000 0.5526 0.5000 


0.5192 0.5000 0.5167 0.5000 0.5167 

0.5334 0.5000 0.5000 0.5000 0.5192 
 
0.5000 0.5167 0.5192 0.5000 0.5167 
0.5000 0.5359 0.5167 0.5000 0.5000 

Următoarele iterații presupun repetarea pașilor 2 și 3 până la un număr maxim de


iterații și de furnici impus de utilizator. Pentru exemplul dat vom obține pentru un număr
de 10 furnici și 20 iterații cea mai bună rută ca fiind 1-4-3-5-2-1 cu un cost de 52

16.2 Bee Colony Optimization (BCO)


Bee Colony Optimization se inspiră din comportamentul albinelor atunci când își caută
hrana. A fost propusă în 2005 de Dervis Karaboga în An idea based on honey bee swarm for
numerical optimization - (technical report-tr06, october, 2005) Pe această temă există mai
abordări, cea pe care o vom reda în acest capitol, este prezentată în referința 11,2

Albinele în natură

Pentru construirea unui algortm de tip BCO este necesară cunoașterea modului în care
funcționează o colonie de albine:
A. O colonie de albine poate explora un spațiu în care explorează și exploatează resurse
de tip polen / nectar într-o arie circulară cu raza de 10 Km.
B. Sunt exploatate prioritar resursele cele mai bogate. Acestea sunt exploatate de un
număr mare de albine. Zonele mai puțin promițătoare sunt explorate de un număr mai
mic de albine.

1
Pham D.T., Ghanbarzadeh A., Koc E., Otri S., Rahim S., and M.Zaidi. "The Bees Algorithm - A Novel Tool
for Complex Optimisation Problems"", Proceedings of IPROMS 2006 Conference, pp.454-461
2
The Bees Algorithm, and Its Applications, Dr. Ziad Salem, Computer Engineering Department Electrical
and Electronic Engineering Faculty

243
C. Explorarea zonelor se face de către albine cercetaș. Acestea caută aleator, la
întâmplare, surse potențiale de hrană.

D. Albinele cercetaș se întorc la colonie cu o evaluare a cantități de hrană prezente în


zona explorată (măsurată ca o combinație între cantitățile de polen, nectar - definită sub
forma unei cantități de zahăr)

E. După depozitarea cantității de hrană (polen, nectar) adusă, albinele merg spre o zonă
de comunicare (dance floor). În această zonă vin albinele care au găsit o sursă de
hrană sau au adus hrană. În această zonă se transmit informații privind calitatea ,
cantitatea și unde se găsește hrană. Este evident faptul că dacă o albină a găsit o
sursă de hrană bogată prin intermediul zonei de comunicare va atrage alte albine.
Acestea după aducerea hranei din zona semnalată vor mobiliza alte albine pentru
exploatarea aceleiași zone, apărând astfel un fenomen de creștere a numărului de
albine care exploatează aceiași zonă.

244
Informațiile se transmit prin intermediul unui dans numit „waggle dance” următoarele
informații:

1. Direcția zonei care are flori (unghiul dintre soare și zona


cu flori).
2. Distanța de la stup (durata dansului).
3. Calitatea zonei (fitness) (frecvența dansului).
Aceste informații permit albinelor să determine precis zona
care are o sursă de nectar care merită să fie exploatată.

În acest mod, numărul de albine care exploatează o zonă va depinde de calitatea (fitness)
zonei respective, apărând un fenomen modificare a numărului de albine dinamic funcție de
contextul zonelor care se exploatează. Astfel o zonă poate fi exploatată de mai multe albine
sau poate fi abandonată.

Bees Algorithm (BA)

Bees Algorithm (BA) este un algoritm de optimizare care se inspiră din modul în care
albinele caută hrană pentru a găsi o soluție optimă. În pseudocod algoritmul are aspectul

245
Exemplu: Găsirea optimului unei funcții matematice.

Următoarea figură prezintă funcția matematică luată în considerare.

1. În primul pas se inițializează populația de albine cu n=10. Se amplasează aleator în


zonele de căutare și se calculează fitness-ul pentru fiecare din aceste albine.
Pentru exemplul dat să presupunem că se cere găsirea unui optim în intervalul
xϵ[A, B]. Amplasarea aleatoare a 10 albine este echivalentă cu generarea a 10
numere aleatoare x în intervalul specificat și calcularea valorii y=f(x) care va defini
fitness-ul, pentru locația în cauză.

Fig 1. Inițializarea populației de (n=10) Albine prin amplasarea aleatoare a


acestora în zone și evaluarea funcției fitness pentru fiecare locație în parte.

246
2. Se evaluează calitatea (fitness-ul) zonelor vizitate de albine. Valorile obținute prin
evaluarea albinelor ( a locaților în care sunt prezente) este memorată într-o matrice
de dimensiune 10 care se ordonează descrescător de la cea mai mare valoare a lui
y la cea mai mică a acesteia, valorile depinzând de funcția matematică care se ia în
considerare.

3. Un număr de m albine din cele n existente care au cel mai bun fitness sunt
selectate. Aceasta are drept corespondent selectarea a m zone. În zonele vecine
fiecăreia din aceste m locații se vor efectua căutări. Din cele m albine sunt
selectate e albine elită, operația având ca rezultat selecția celor mai bune zone din
cele m selectate anterior. Presupunem că avem
m=5, e=2, m-e=3

Fig 2. Selecția

 celor mai bune (m=5) zone pentru căutări ulterioare în vecinătatea acestora;
 a unui număr de (e=2) albine de elită “▪” și

 selecția unui număr de (m-e=3) alte albine “▫” din zonele cele mai promițătoare.

4. Selectează zonele vecine locațiilor în care sunt prezente albinele pentru explorare.
Zona este de mărime ngh (ngh ϵ [0, 1]).

247
Fig. 3 Determinare mărimii zonelor vecine (mărime specificată de ngh)
5. Se recrutează albine pentru zonele selectate și evaluează fitness-ul albinelor
respective
 Se trimit albine la e zone (zone bogate) și la m-e zone (zone sărace)
 Se vor trimite mai multe albine la e zone (zone de elită)
 n2 = 4 (zone bogate)
 n1 = 2 (zone sărace)

Fig 4 Recrutarea albinelor pentru zonele selectate (mai multe albine pentru e=2
zone de elită)

248
6. Selectează cele mai bune albine din fiecare locație (cu valoarea fitness-ului cea mai
mare) pentru a forma noua populație de albine. Se alge cea mai bună albină din
fiecare cele m zone astfel

Fig 5 Selectarea abinelor * care au fitness-ul maxim din fiecare zonă de căutare

7. Se inițializează o nouă populație de albine. Aceasta este formată din restul albinelor
în număr de n-m care nu au fost implicate în procesul de căutare anterior. În cazul
dat avem n = 10 m = 5, respectiv n-m=5 albine.

o
Fig. 6 Se atribuie restul de (n-m) albine pentru o nouă căutare aleatoare

249
8. Se repetă pașii de la 2 la 7 până când se atinge condiția de stop (sfârșitul
numărului de repetiții definit de imax). În final se va obține cea mai bună soluție care
se vede în figura următoare. Această cea mai bună valoare a locației în care se va
găsi cea mai bună albină din m albine va reprezenta optimul funcției matematice.

Fig. 7 Punctul de maxim global găsit.

Parametrii Bee Algorithm (BA)

Parametru Notație Valori

uzuale

Număr albine n 100

Numărul celor mai bune locații, selectate din cele n locații explorate. m 10

Numărul locațiilor elită, alese din cele m selectate (corespund albinelor elită) e 3

Numărul de albine alese pentru explorarea vecinătății din cele mai bune e locații nep / 40
n2

Numărul de albine alese pentru explorarea restului de (m-e) locații rămase de nsp / 20
cercetat n1

Mărimea vecinătății din jurul locației unde este prezentă albina în care se face ngh 0.2
căutarea [0 - 1]. Rezultă o zona de căutare.

Numărul de iterații maxime imax 10, 300,


1000

250
Pașii Algoritmului

1. Algoritmul începe cu n albine care sunt amplasate aleatoriu în spațiul de căutare. De


exemplu n=100
2. Se evaluează calitatea (fitness-ul) zonelor vizitate de albinele cercetaș. Valorile
obținute prin evaluarea locației în care sunt prezente albinele este memorată într-o
matrice de următoarea manieră:

Albină 1 2 3 4 5 6 … … ... 99 100

Valoare fitness 20 50 60 30 80 10 … … … 35 72

Matricea se va ordona de la cea mai mare valoare a funcției fitness la cea mai mică
valoare a acesteia.

3. Un număr de m locații vor fi selectate (acestea vor corespunde celor mai bune
rezultate obținute de m albine din cele n prezente. De exemplu m=10

Albină 1 2 3 4 5 6 7 8 9 10

Valoare fitness 80 78 75 72 69 66 65 60 59 58

În continuare din cele m locații se aleg un număr de e locații. De exemplu e=2, deci
m-e=10-2=8.

4. Se stabilește dimensiune zonei de căutare în jurul locațiilor selectate. Dimensiunea


este specificată de parametrul ngh. Acestea se vor utiliza pentru actualizarea
zonelor de căutare pentru cele m albine cercetaș. Acest lucru este important,
deoarece ar putea exista soluții mai bune decât soluția inițială în zona de vecinătate
Presupunem că ngh=0.2. De exemplu zona de cercetare pentru albina prezentă în
locația 1 va fi în acest caz de [80-80*0.2 , 80+80*0.2] respectiv de [64 , 96].

251
5. Se recrutează albine pentru zonele selectate și se evaluează fitness-ul acestor zone.
 Un număr de albine (n2) vor fi selectate aleatoriu și vor fi trimise la e zone
(n2=40)
 Se aleg un număr de n1 albine (numărul este mai mic decât n2) care vor fi
trimise la cele m-e zone rămase. Presupunem că n1=20.

6. Se aleg albinele care prezintă cel mai bun fitness pentru fiecare zonă pentru a forma
următoarea populație de albine. Acest aspect nu există în natură. S-a procedat astfel
pentru a reduce numărul zonelor care se explorează.
Cele mai bune albine din cele m zone se vor selecta astfel:
a. Se iau în calcul succesiv cele e zone.
b. Se construiesc matrice care conțin n2=40 albine, în care, fiecare albină prezintă
un fitness egal cu valoarea fitness-ului albinei care a descoperit zona modificată
cu o valoare care depinde de rezultatul explorării zonei în cauză ( rezultată din
aplicarea parametrului ngh locației albinei care a descoperit zona) .
Matricea se va ordona și cea mai bună valoare se va lua în considerare.

Albină 1 2 3 … 40

Valoare fitness 82 81.2 79.9 … 79.2

Pasul 6 se repetă pentru toate cele m zone. La final se vor obține cele mai bune
m=10 albine care se vor memora la începutul matricei (n=100).

Albină 1 2 3 4 5 6 … 10 11 … 99 100

Valoare fitness 82 79 77 73 70 67 … 58.2

Căutarea în zonele vecine celor mai bune e zone care prezintă cele mai
promițătoare soluții se va face mai amănunțit prin recrutarea mai multor albine care
vor urma pe cele care au descoperit zona în detrimentul altor albine.. Împreună cu
albinele această recrutare diferențială reprezintă cheia operațiilor în Bee Algorithm.

252
7. Se inițializează noua populație:
Albinele din populația rămasă vor fi atribuite aleator în spațiul de căutare (pozițiile de
la 11 la 100 din matricea anterioară)

Noua populație va prezenta aspectul:

Albină 1 2 3 4 5 6 … 10 11 … 99 100

Valoare 82 79 77 73 70 67 … 58.2 Random values


fitness

8. În acest moment s-a terminat o etapă de explorare / exploatare. Pașii de la 2 la 7


sunt repetați până când criteriul de oprire este atins ( acesta este definit de imax
numărul maxim al etapelor de repetiție stabilit inițial). De exemplu imax=1000

La sfârșitul fiecărei iterații, colonia va fi formată din două componente.

 Prima este formată din albinele care vor explora zonele cele mai profitabile găsite iar
 cea de a doua din albinele care vor continua să caute aleatoriu alte zone

BA – Aplicații
Domeniile de aplicabilitate în care BA poate fi utilizat sunt
 Optimizarea funcțiilor
 Recunoașterea formelor (Clasificare ECG, Tehnici de clustering, Clasificare
imagini, etc.)
 Optimizarea Rețelelor Neuronale
 Jocuri strategice

253
BA – Eficiență

Tabel 1. Funcții utlizate în testarea strategiilor bioinspirate

Rezultate

Tabel 2. Studiu comparativ al eficienței strategiilor GA, ANTS, BCO –

(valorii medii pentru funcțiile din Tabelul 1)

254
16.3. Particle Swarm Optimization
Introducere
Particle swarm optimization (PSO) - Tehnica optimizării roiului de particule, este
unul de inspirație socială având ca punct de plecare mișcarea roiurilor de păsări.
Rezolvă majoritatea problemelor pe care algoritmii genetici le rezolvă. Un avantaj destul
de semnificativ în fața altor tehnici similare, este abilitatea de a opera fără a avea
nevoie de informații legate de gradient. Alt avantaj este ușurința de implementare. A
fost propus de Kennedy, J.; Eberhart, R. (1995). "Particle Swarm Optimization".
Proceedings of IEEE International Conference on Neural Networks. IV. pp. 1942–1948.
doi:10.1109/ICNN.1995.488968.

Concepte
 Particle Swarm Optimization, sau „tehnica optimizării roiului de particule”, ,
folosește un model populațional.
 Populația, roiul, este formată din particule, potențiale soluții. Roiul de particule,
se spune că „zboară” în hiperspațiul de dimensiune n, unde n este dimensiunea unei
soluții / nr. de parametri căutați. Acest zbor presupune găsirea unei soluții acceptabile
plecând de la o populație de soluții inițială generată aleatoriu, care se îmbunătățește pe
parcursul a mai multor iterații.
O particulă tinde să orbiteze
 în jurul celei mai bune sale poziții (pbest) și
 în jurul celei mai bune poziții (gbest) din grupul din care face parte.

 Fiecare particulă își ajustează viteza de deplasare și direcția în acord cu:


 propria sa experiență de zbor și
 cea a particulelor din roi.

255
 Algoritmul se poate termina după mai multe criterii, spre exemplu când o soluție
satisfăcătoare a fost găsită ori s-au executat un număr predefinit de iterații.
Există două tipuri de PSO:
- varianta gbest și
- varianta lbest.
Pe scurt, cele două variante se deosebesc prin mulțimea particulelor cu care o
oarecare particulă se află în interacțiune:
 în cadrul modelului gbest, o particulă schimbă informație cu tot roiul,
 pe când în cadrul modelului lbest, informația este schimbată doar cu particulele
aflate într-o vecinătate a acesteia.

Algoritmul original
În cele ce urmează vom prezenta algoritmul original PSO, o variantă gbest, așa
cum a fost descris de către creatorii săi (Kennedy, J.; Eberhart, R. (1995). "Particle
Swarm Optimization". Proceedings of IEEE International Conference on Neural
Networks. IV. pp. 1942–1948)
În acest model, la un moment oarecare t, fiecare particula i, are următoarele
caracteristici:
 xi – poziția curentă;
 vi – viteza curentă;
 fiecare particulă are în propria memorie cea mai bună poziție descoperită de-
a lungul iterațiilor, notată cu pi, iar
 întreg roiul are în propria memorie cea mai bună poziție găsită de toate
particulele sale, notată cu pg definită ca:

256
Atât pi, cât și pg sunt actualizate la fiecare iterație a algoritmului.
Acest model de PSO, numit „global”, menține o singură cea mai bună poziție
pentru tot roiul. Deoarece toate particulele din roi se îndreaptă spre această poziție,
dacă ea nu ar fi actualizată destul de des, la fiecare iterație sau câteva iterații, atunci tot
roiul ar converge prematur.
Vom împărți algoritmul în trei mari faze, pe care le vom descrie separat: faza de
inițializare, faza iterațiilor și faza de terminare.

Inițializarea
Înainte de a „zbura”, particulele au nevoie de o inițializare a componentelor
vectoriale descrise mai sus.
Fiecărei componente
 xti ale vectorului de poziție i se va asigna o valoare aleatoare uniform distribuită
în intervalul maxim din spațiul de căutare [−𝑥𝑚𝑎𝑥 , +𝑥𝑚𝑎𝑥 ],
 vti ale vectorului de viteză, fie i se va asigna inițial valoarea 0, fie o valoare
uniform aleatoare din intervalul [−𝑣𝑚𝑎𝑥 , +𝑣𝑚𝑎𝑥 ],
 cele specificate mai sus se traduc prin următoarele calcule

x0i  xmin  rand  xmax  xmin 


xmin  rand  xmax  xmin 
v0i 
t
Cele două componente (poziție, viteză) pot fi văzute în figura următoare.

257
Faza iterațiilor
În faza iterațiilor se actualizează pentru fiecare particulă în parte vectorul de viteză, vti ,

iar pe baza acestuia și vectorul de poziție, xti .

Schimbarea vitezei pentru fiecare particulă în fiecare iterație presupune luarea în


considerare:
- poziției curente a particulei
- a celei mai bune poziții anterioare pe care a avut-o particula
- a celei mai bune poziții anterioare a roiului

Tendința de deplasare a particulei, influența roiului sunt ponderate aleator. Ecuația


următoare arată cum se schimbă viteza în fiecare iterație iar ecuația următoare arată
cum viteza contribuie la schimbarea poziției particulei. În ecuație:
 w este factorul de inerție,
 c1 este coeficientul de încredere în decizia pe care o ia particula, iar
 c2 este coeficientul de încredere în comportarea roiului,
 rand este un generator de numere aleatoare uniform distribuite în intervalul (0,
1).
 Cea mai bună locație anterioară a particulei este memorată în pi iar cea mai
bună poziție curentă a roiului este memorată în pg .

Figura următoare arată cum fiecare din aceste componente se combină pentru a
rezulta noua viteză și poziția care rezultă pentru o particulă la sfârșitul unei.

vi
 wv i
 c1 rand   
 p  x   c2  rand     p  x 
i i
k
g
k
i
k
k 1
t t
k

xki 1  xki  vki 1  t

258
Pentru a căpăta proprietăți stohastice, algoritmul folosește, după cum se
observă, doi vectori care au conținut uniform aleatoriu 𝑟𝑎𝑛𝑑 ~ 𝑈(0,1), scalați de
coeficienții de accelerație c1 , c2   0, 2 .

 Coeficienții 𝑐1 , 𝑐2 au rolul de a stabili mărimea maximă a pasului înspre pi – cea


mai bună poziție personală , respectiv pg - cea mai bună poziție găsită de
întregul roi.
 Coeficientul w are rolul de a balansa căutarea între explorare globală (w mare)
şi locală (w mic).

Ignorând viteza anterioară vki , ecuația se împarte în două componente:

- componenta cognitivă personală, c1 rand


p x 
i i
k

t
Această componentă ia în considerare doar experiențele personale ale particulei i, și
influențează cât se va deplasa particula spre cea mai bună performanță a sa din trecut.
Pentru actualizarea vitezei, Kennedy a folosit într-un experiment de-al sau doar această
componentă în ecuație, sub forma

v i
 wv i
 c1 rand
p x ,
i i
k
k 1
t
k

omițând cea de-a doua componentă. Rezultatele obținute au fost mult inferioare soluției
complete, deoarece particulele nu aveau nici o interacțiune.

- componenta socială de grup, c2  rand


p
g
k  xki 
t
Această componentă ia în considerare interacțiunile dintre particula i și roi. Influențează
cât se va deplasa particula spre cea mai bună poziție găsită de roi.
În cadrul aceluiași experiment despre care am discutat mai sus, Kennedy a folosit
pentru actualizarea vitezei doar componenta socială, sub forma

vi
 wv
i
 c 2  rand
p
g
k  xki 
,
k 1
t
k

259
iar rezultatele au fost superioare primei încercări în care s-a folosit doar componenta
cognitivă.
În prezent nu se știu prea multe despre cât de importante sunt cele două
componente în parte, deși empiric s-a demonstrat că pe un set mai larg de probleme
componenta socială ar fi mai importantă. Cert este că, folosind ambele componente,
rezultatele sunt satisfăcătoare în comparație cu alți algoritmi care încearcă să rezolve
aceleași probleme.
Pe baza vectorului de viteză se calculează vectorul de poziție după formula:
xki 1  xki  vki 1  t
Urmează actualizarea celei mai bune poziții găsite de particula i până la
momentul t. După ce toate particulele au fost procesate, se poate calcula din nou cea
mai bună poziție găsită de roi.

Faza de terminare
Algoritmul se rulează de un număr de ori stabilit dinainte sau până se atinge un nivel
prestabilit de eroare. Desigur pot exista și alte criterii de oprire, acestea fiind date de
natura problemei de rezolvat. În figura următoare se prezintă faza de iterație și ultima
iterație în care s-a atins un optim.

260
În continuare redăm o simplă variantă de pseudo-cod, care sintetizează cele discutate
mai sus.

Exemplu

Optimizarea unui portofoliu utilizând Particle Swarm Optimization

Algoritmul PSO poate fi utilizat pentru optimizarea unui portofoliu în contextul unor tranzacții
bursiere. În contextul optimizării portofoliului, fiecare particulă poate defini o posibilă alocare de
capital între diverse mărfuri din contextul portofoliului. Funcția de fitness a acestui portofoliu
poate fi determinată utilizând funcții financiare care calculează riscul unei investiții.
Presupunând că se utilizează pentru funcția de fitness – Sharpe ratio - (Indice de performanță
a unui portofoliu. A fost descrisa de Sharpe care corelează castingul prognozat al unui portofoliu
eficient cu rata dobânzii pentru titlul cu risc zero si castingul prognozat al pieței. Este în prezent
un standard de măsură a eficienței unui portofoliu)

 E  RM   R f 
E  Rp   R f   P
M

Unde:

 E(Rp) câștigul prognozat al portofoliului;

261
 Rf câștigul prognozat al titlului cu risc zero;
 E(RM) câștigul prognozat al pieței (indice);
  P abaterea standard a portofoliului;
  M abaterea standard a pieței.

Considerăm următoare ilustrare a tehnicii PSO aplicată unui portofoliu constând din 3 bunuri

Particula gri este particula care a fost actualizată, Particula roșie este cea mai bună poziție a
particulei gri (pbest) iar cea albastră cea mai bună poziție globală (gbest).

Particula gri glisează în vectorul (0.5, 0.2, 0.3) care înseamnă că 50% din portofoliu este alocat
pentru bunul 1, 20% pentru bunul 2 și 30% pentru bunul 3. Coeficientul Sharpe pentru această
alocare de fonduri este de 0.38 care este mai mică decât cea mai bună poziție personală
(particular roșie) și cea mai bună poziție global (particular albastră). Din această poziție
particula gri este actualizată astfel încât aceasta se va apropria mai mult atât de valorile cele
mai bune atât personale (pbest) cât ți globale (gbest). Rezultatul este mai bun decât cel din
pasul anterior.

Particula gri prezintă în acest pas valoarea (0.3, 0.3, 0.4) care are un coeficient Sharpe de 0.48.
Deoarece această valoare este mai mare decât valoare pbest din pasul anterior poziția
particulei va actualiza valoare pbest

262
Adevărata provocare în procesul de optimizare cu (PSO) este legată de asigurarea respectării
faptului că constrângerile de optimizare a portofoliului sunt satisfăcute. Cele mai frecvente
constrângeri sunt în primul rând, legate de faptul că nu mai mult și nu mai puțin de 100% din
capitalul disponibil se alocă între active (de exemplu, valoarea vectorului trebuie să fie 1,0). În
al doilea rând, alocările negative de active nu sunt permise. Și, în sfârșit, capitalul disponibil
trebuie să fie alocat tuturor activelor din portofoliu. Aceasta din urmă fiind o constrângere
cardinalitate. Două tehnici comune sunt utilizate pentru a se asigura că particulele satisfac
constrângerile.

1. Pentru fiecare particulă care nu satisface constrângerile, se aplică un set de reguli pentru a
modifica poziția particula lui astfel încât aceste restricții să fie îndeplinite.
2. Se penalizează prin intermediul funcției de fitness de particule care nu satisfac constrângeri

263
Anexa

264
265
17. Machine learning

Machine Learning este un domeniu al Calculatoarelor și Tehnologiei


Informației care a evoluat din tehnicile de Recunoaștere a formelor (Pattern
Recognition) și a tehnicilor de învățare (computational learning theory) din
Inteligența Artificială.
În 1959 , Arthur Samuel a definit Machine Learning ca fiind:
Domeniul de studiu care dă posibilitate calculatoarelor abilitatea de a
învăța fără a fi programate explicit.
Machine Learning are drept obiect de studiu construcția algoritmilor care pot
învăța și face predicții utilizând seturi de date care descriu un fenomen al lumii
înconjurătoare. Acești algoritmi lucrează în două etape
1. În prima etapă construiesc un model ( în cazul general modele ) din
exemplele prezentate (exemple definite de date ce caracterizează
fenomenul analizat). Modelele sunt cunoscute sub numele de
Clasificatori
2. În a doua etapă modelul este utilizat pentru a face predicții pentru date
care aparțin aceluiași fenomen dar pentru care nu se cunoaște care
este efectul pe care îl prezintă acesta în cadrul fenomenului. Datele
utilizate pentru predicții , după efectuarea acestora, pot fi utilizate
pentru îmbunătățirea calității modelului construit în faza anterioară. În
acest mod modelul poate învăța și evolua în timp.

Procesul de tip machine learning este ilustrat de următoarea figură

266
Algoritmi de învățare
17.1 Clasificare. Arbori de decizie
17.1.1 Tipuri de date
Modelele care sunt construite în cadrul tehnicilor de clasificare descriu
fenomene și aspecte diferite (obiecte) ale realității înconjurătoare. Aceste
aspecte sunt descrise prin intermediul unor instanțe (măsurători) care conțin
fiecare două sau mai multe atribute numerice sau alfanumerice.
Există mai multe tipuri de atribute care pot apare in descrierea unui
obiect. Acestea vor trebui tratate unitar in contextul păstrării semnificaţiei pe
care o prezintă. Tipurile de atribute care pot apare sunt
 Atribute numerice:
 Atribute nominale
 Atribute de tip interval:
 Atribute mixte

De exemplu
Atribute Numeric Numeric Nominal Numeric
Tip discret continuu de tip
interval
Exemplu 2 4.53 red [2, 30]
valoare atribut
Domeniu [1, 2, 4, 8] [2, 10] [red, yellow, blue, green] [2, 30]

În contextul descrierii unui fenomen care definește un anumit aspect al


lumii înconjurătoare apar aspecte particulare care reprezintă trăsături
specifice în interiorul respectivului fenomen. Aceste trăsături specifice sunt
cunoscute sub denumirea de clase și sunt definite în setul de date
corespunzător fenomenului studiat prin atribute de tipul celor specificate mai
sus. Un exemplu de set de date care descrie condițiile în care se desfășoară
un joc de golf este dat în continuare. Aspectul „joc de golf” este descris
printru set de 14 instanțe (măsurători) fiecare fiind definită de un număr de 5
atribute. În interiorul acestui set de date sunt prezente mai multe trăsături

267
specifice. De exemplul la nivelul caracteristicii „outlook” apar un număr de 3
trăsături specific (clase) și anume: sunny, overcast, rainy, iar la nivelul
caracteristicii “play” doua trăsături specifice : no, yes. La nivelul unui atribut
numeric aceste trăsături specific se definesc prin intermediul intervalelor la
care pot aparține valorile numerice respective. De exemplu pentru atributul
“temperature”, pot apare un număr de 3 caracteristici (clase) corespunzătoare
intervalelor (60 – 70), (71 – 80), (81 – 90).

17.1.2. Definiție. Terminologie


Un model de tip Machine Learning poate fi reprezentat printr-un arbore
de decizie descris printr-o regulă sau un set de reguli de tip if-then-else.
Un arbore de decizie constă dintr-o structură de tip arbore în care:

 Nodurile interne ale arborelui indică un test pe un atribut;


 Ramurile reprezintă un rezultat al unui test;
 Nodurile frunză ale arborelui reprezintă etichete ale claselor;

Arborele de decizie poate fi construit în diverse variante funcție de atributul de


tip clasă care se ia în considerare. În cazul general modelul apare de forma
prezentă în figura următoare.

268

Decizia 1 Ramură

DA NU

Decizia 2 Decizia 3

DA NU
DA NU
Decizia 4 Decizia 5

DA NU DA NU

Frunze

Pentru setul de date prezentat anterior modele posibile de tip Machine


Learning vor putea fi
a) Dacă clasa este play

b) Dacă clasa este outloook

269
Modelul care urmează să fie utilizat depinde de obiectivul urmărit de
utilizator. Obiectivul este definit de caracteristica (clasa) funcție de care se
dorește a fi reprezentat setul de date.

7.1.3 Construirea arborelui de decizie


Cei mai mulţi algoritmi de generarea a arborilor de decizie trec prin
două faze:
 faza de construire (creştere) a arborelui (prin divizare, ”splitting”)
urmată de
 faza de tăiere (pruning).

Faza de construire a arborelui este un proces iterativ care implică divizarea


progresivă a datelor în subseturi mai mici.
 Prima iteraţie consideră că nodul rădăcină conţine toate datele.
 Următoarea iteraţie lucrează pe noduri derivate care vor conţine
subseturi de date. La fiecare divizare, atributele sunt analizate şi este
aleasă cea mai bună divizare. O importantă caracteristică a divizării
este aceea că ea este de tip (greedy) ceea ce înseamnă că algoritmul
nu se uită înainte în arbore să vadă dacă o altă decizie ar produce un
rezultat final mai bun.
 Faza de tăiere identifică şi mută ramurile care reflectă zgomote sau
excepţii. Criteriul care stă la baza selecției unui atribut este dat de
entropie.

Entropia - o măsură a omogenităţii unui set de exemple


Din punct de vedere fizic entropia este o mărime care măsoară gradul
de dezordine a unui sistem. Extinsă la nivelul unui set de date entropia va
măsura cât de dezordonat este setul de date respectiv. Ca urmare o entropie
mai mare a unui set de date are ca rezultat direct faptul ca e nevoie de mai
multa informaţie pentru a descrie setul in cauza.

270
Entropia se calculează astfel :
Fiind dat un set S, conţinând doar exemple pozitive și negative a unui
concept dorit, entropia setului S este:

Entropie(S )   p p log2 p p  pn log2 pn


unde:
pn - proporţia exemplelor negative din S
pp - proporţia exemplelor pozitive din S

Pentru exemplificare se presupunem ca S este o colecţie de 25 de exemple


din care 15 pozitive și 10 negative:

 15   15   10   10 
Entropie( S )     log 2      log 2    0.97
 25   25   25   25 
Utilizând acest indicator pentru fiecare nivel de construire a arborelui de
decizie se ia în considerare atributul care introduce cea mai puțină dezordine.

Information gain – Câştigul Informaţional

Construirea arborelui impune utilizarea unui indice cantitativ care sa


cuantizeze efectul împărţirii setului de date folosind un atribut particular.
Acesta poarta numele de information gain și calculează reducerea entropiei
care rezulta din împărţirea datelor după atributul A
Pentru un anumit atribut A, câştigul informaţional produs de selectarea
acestuia ca rădăcina a arborelui de decizie este egal cu conţinutul total de
informaţie din arbore minus conţinutul de informaţie necesar pentru
terminarea clasificării (construirii arborelui) după selectarea atributului A ca
rădăcina.

Information gain - câştigul informaţional reprezintă reducerea aşteptata in


entropie cauzata de segmentare. Mai precis, information gain, Gain(S, A) a
unui atribut A in raport cu o colecţie S este definit ca:

271
Sv
Gain( S , A)  Entropie( S )  
vValori ( A) S
Entropie( Sv )

unde:
 Valori(A) este un set de posibile valori pentru atributul A ,
 Sv este o submulţime a lui S pentru care atributul A are valoarea v
Sv = {s  S | A(s) = v}
Exemplu
A. Care din cele două atribute induce cea mai mare dezordine în setul de
date (deci prezintă cel mai mic câștig informațional) ?

1. Se calculează Entropia pentru cele două atribute

29 29 35 35
Entropy (29,35)   log 2  log 2  0.99
64 64 64 64

2. Se calculează Câștigul Informațional

Entropy  21,5    0.71


Entropy 8,30    0.74

Entropy  21,5    Entropy 8,30    0.27


26 38
Gain  S , A1   Entropy  S  
64 64

272
Entropy 18,33    0.94
Entropy 8,30    0.62

Entropy 18,33    Entropy 11, 2    0.12


51 13
Gain  S , A1   Entropy  S  
64 64

Se dă următorul set de date

273
1. Se calculează Câștigul informațional pentru cele 4 atribute

274
2. Câștigul informațional pentru cele 4 atribute este dat în tabelul de mai
jos
Atribut Câștig informațional

Gain(S,Outlook) 0.247

Gain(S,Humidity) 0.151

Gain(S,Wind) 0.048

Gain(S,Temperature) 0.029

Construcția arborelui va începe cu atributul Outlook care oferă cel mai


mare câștig informațional. Acest atribut va deveni rădăcina arborelui de
decizie care descrie setul de date. În această etapă arborele de decizie va
avea forma

Deoarece numărul de exemple negative pe direcția Overcast este 0


dezvoltarea pe direcția respectivă se va opri. Rămân în atenție numai
atributele pentru care Outlook are valoare Sunny respective Rain. Apar două
subseturi de date care se vor analiza similar ca mai sus. Cele două subseturi
de date sunt
 Ssunny = [D1, D2, D8, D9, D11] obținut prin selectarea din setul de date
numai a acelor pentru care valoarea Outlook este Sunny
 SRain = [D4, D5, D6, D10, D14] obținut prin selectarea din setul de date
numai a acelor pentru care valoarea Outlook este Rain

275
În final vom obține următorul arbore de decizie

276
17.2 Rețele Neuronale
O reţea neuronală artificială este un model care emulează reţeaua
neuronală biologică. Nodurile într-o reţea neuronală se bazează pe
reprezentarea matematică simplistă a cărei funcționare se aseamănă cu
neuronii reali.

Neuronul biologic
Celula nervoasă – sau neuronul – este elementul fundamental al
sistemului nervos. Schematic, în Figura 1 este redat simplist un lanţ de
neuroni, având menţionate componentele semnificative din punctul de vedere
al utilităţii în modelele matematice ulterioare:

Figura 1. Reprezentarea schematică a neuronului biologic. 1 – Arborele


dendritic; 2 – Soma(corpul celular); 3 – Nucleul celulei neuronale; 4 – Axonul; 5
– Arborele axonic; 6 – conexiuni sinaptice

Celula nervoasă are diametrul de ordinul micronilor şi este alcătuită din:


 corpul celular – conţine nucleul neuronului şi guvernează transformările
biochimice de sinteză a enzimelor necesare funcţionalităţii celulei
nervoase
 dendritele – sunt extensii filiforme cu ramificaţii arborescente ale
corpului celular, având diametrul de ordinul zecimilor de micron şi
lungimi de până la 10 microni. Dendritele sunt principalii receptori de
semnal ai neuronului.
 axonul – este o prelungire fibroasă, de lungime considerabilă în
comparaţie cu restul celulei nervoase, variind între 0.2 – 1 centimetru

277
pentru neuronii din cortex şi 10 centimetrii pentru neuronii periferici.
Axonul reprezintă conexiunea de ieşire a semnalului procesat de către
neuron.

Modalitatea de interconectare spaţială a celulelor nervoase este


realizată prin intermediul unor zone cu conductanţă electrică îmbunătăţită
denumite sinapse, şi care constituie practic o legătură între axonul unui
neuron şi o dendrită a altui neuron, cu rol de comunicare între cele două
celule.
Eficienţa energetică a creierului uman este de aproximativ 10-16
J/(operaţie-s) , în timp ce cele mai performante calculatoare au o eficienţă de
10-6 J/(operaţie-s).

17.2.1 Modele neuronale artificiale


În forma cea mai generală – şi în accepţia iniţială – o reţea neuronală
este un algoritm proiectat să modeleze modul în care creierul realizează o
anumită funcţiune, estimându-se empiric, cu aproximaţii acceptabile,
modalitatea de procesare a informaţiei de către cortex. Acest scop este
valabil doar pentru cazul primelor modele. Ulterior modelele neuronale au
părăsit ideea iniţială de simulare a propagării şi procesării semnalului nervos,
păstrând însă specificul nomenclatorului biologic pentru desemnarea unor
etape.
Astfel, aplicaţiile tratate în continuare se vor referi la reţele neuronale
care îşi realizează scopul propus printr-un proces iniţial de învăţare. Pentru o
bună performanţă aplicativă, rețeaua îşi creează ponderi de interconectare
între unităţile de intrare şi cele de ieşire, unităţi care vor fi denumite neuroni
sau unităţi de procesare. O definiţie simplistă a noţiunii de reţea neuronală
este dată de:

O reţea neuronală este un procesor cu distribuţie paralelă,


care are o mare capacitate de a stoca cunoştinţe dobândite din
experimente, în scopul utilizării active ale acestora.

Simularea acţiunii cerebrale este elocventă în cele două acţiuni de bază:

278
 cunoştinţele sunt acumulate în timpul unui proces de învăţare
 stocarea cunoştinţelor se realizează prin valoarea conexiunilor inter
neuronale, denumite şi ponderi sinaptice

O reţea neuronală artificială este alcătuită dintr-o :


 mulţime de noduri în care se află neuroni artificiali, elemente de
procesare neliniară care operează în paralel.
 Prin analogie cu neuronul biologic un neuron artificial are un anumit
număr de intrări (dendrite) şi o singură ieşire (axon) care se poate
conecta la intrarea mai multor neuroni.
 Fiecare intrare are asociată o anumită pondere (sinapsă) care
reprezintă importanţa pe care o are impulsul, prezent pe linia
respectivă la activarea neuronului. Ponderile permit modificarea
nivelului de propagare a semnalului, cauzând excitarea sau inhibarea
neuronului respectiv.
Legătura dintre neuronul biologic şi neuronul artificial este arătată în
Figura 2,

Figura 2. Neuronul biologic via neuronul artificial

Caracteristicile cele mai importante ale reţelelor neuronale, la fel ca și


ale creierului uman sunt:

279
 capacitatea de a învăţa

 capacitatea de generalizare

Capacitatea de a învăţa :

 Reţelele neuronale nu necesită programe puternice ci sunt mai


degrabă rezultatul (antrenamente) asupra unui set de date
 Dându-se un set de intrări (eventual şi cu ieşirile dorite) în urma
procesului de învăţare reţelele neuronale se autoorganizează astfel
că pot rezolva problemele pentru care au fost proiectate. Există o
gamă largă de algoritmi de învăţare fiecare cu avantajele şi
dezavantajele sale în funcţie de problema de rezolvat.

Capacitatea de generalizare :

 Dacă au fost învăţate corespunzător, reţelele neuronale artificiale


sunt capabile să dea răspunsuri corecte şi pentru intrări diferite faţă
de cele cu care au fost învăţate, atâta timp cât intrările nu sunt prea
diferite. Această generalizare se face automat ca urmare a structurii
lor şi nu ca urmare a inteligenţei omului înglobată într-un program ca
la sistemele expert.

În ciuda acestor caracteristici importante nimeni nu se încumetă să


afirme că reţelele neuronale vor ajunge în curând la performanţele creierului
uman; “inteligenţa” la care au ajuns cele mai sofisticate modele de reţele este
egală cu cea a unui copil de câţiva ani.

A. Modelul McCulloch & Pitts


Înainte de descoperirea modalităţii de funcţionare a sistemului nervos
celular, pentru care Hodgkin, Huxlez şi Eccles au primit premiul Nobel în
1963, în 1943, McCulloch şi Pitts au elaborat un model simplist al funcţionării
unui neuron, pornind de la funcţionarea acestuia.
Ei au presupus că neuronul se comportă în modul următor: din
sinapse, prin dendrite, acesta acumulează o sarcină electrică ce provine de la

280
axonii neuronilor vecini; în momentul în care valoarea sarcinii depăşeşte o
anumită valoare – numită prag – neuronul devine activ, transmiţând prin
axonul său un curent constant. Această funcţionare poate fi descrisă
matematic prin:

 n

U pentru x i T
o i 1
n
 0 pentru
 x
i 1
i T

unde:
xi = intrarea i
o = ieşire

Schematic modelul este redat în Figura 3:

x1
x2

U
n


O

i 1

xn

Figura 3. Schema modelului matematic McCulloch & Pitts

O astfel de unitate este denumită unitate de procesare. Considerând


valoarea pragului T=1 şi valoarea tensiunii de ieşire U=1, se pot construi cu
aceste unităţi de procesare unitare, circuite logice de tipul AND, NAND, OR, şi
respectiv celule de memorie.
Cei doi matematicieni au sugerat posibilitatea ca şi creierul uman să
fie o aglomerare de asemenea circuite logice, care ar procesa informaţia într-

281
un mod similar cu calculatoarele digitale, al căror model era definitivat în
aceeaşi perioadă.
Această prezumţie s-a dovedit a fi greşită, însă are valoare intuitivă,
deoarece s-a dovedit ulterior că neuronii funcţionează oarecum după modelul
activării la atingerea unui prag.
Acest model neuronal este caracterizat prin formalism şi printr-o definire
matematică elegantă, având un potenţial de calcul considerabil.
Simplicitatea sa presupune:
 stări binare de tip 0 şi 1
 asumarea operării în timp discret
 sincronicitatea operării tuturor neuronilor

B. Modelul Hebb
În 1949, Daniel Hebb, un biolog care se ocupa cu studiul
comportamentului primatelor, presupune că prin modificarea sinapselor,
conectivitatea celulelor nervoase este într-o continuă schimbare, pe măsură
ce organismul îşi dezvoltă diferite aptitudini. Hebb a enunţat o regulă a
învăţării, conform căreia:

Valoarea efectivă a variabilei de conexiune între doi neuroni


creşte prin activarea repetată a conexiunii.

Cartea a avut un răsunet imens printre psihologi, dar a fost neglijată


de ingineri, fapt ce a dus la ignorarea acestei reguli de învăţare în domeniul
reţelelor neuronale. Abia în 1956 a fost utilizată această regulă de învăţare,
evidenţiindu-se fenomenul de inhibiţie a conexiunii neuronale.
Conform regulii de învăţare a lui Hebb, sinapsele care conectează
neuronii nu transmit axonului neuronului receptor decât o parte a sarcinii
electrice primite de la axonul neuronului transmiţător. Reprezentarea
matematică a acestei leme se obţine utilizând un coeficient subunitar de
transmisie, numit pondere şi notat cu w.

Ponderile sunt asociate neuronului receptor şi îşi pot modifica valorile în


timp conform regulii:

282
 dacă neuronul transmiţător şi neuronul receptor sunt ambii activi în
acelaşi interval de timp, valoarea ponderii asociate conexiunii creşte;

 dacă fenomenul de activare concomitent se repetă de mai multe ori,


sau dacă intervalul de timp al dublei activări este mare, valoarea
ponderii asociate va creşte considerabil;

 dacă neuronul transmiţător şi neuronul receptor nu sunt simultan


activi într-o perioadă de timp mare, valoarea ponderii asociate
conexiunii scade.

Ulterior, s-a dovedit că într-adevăr, această regulă este valabilă, şi stă


la baza mecanismului de învăţare, respectiv uitare, în creierele naturale.
Plecând de la această regulă, se poate descrie o unitate de
procesare, cu ponderi asociative, care este modelul matematic utilizat şi în
prezent, cu variaţii nesemnificative. Astfel, considerând o unitate cu indicele i
cu n intrări de indice j, fiecare având o pondere wj, funcţionarea acesteia se
poate descrie prin:

 n

1 pentru x
j 1
j  wj  T
oi   n
0 pentru

x
j 1
j  wj  T

sau prin schema din figura 4

283
x1 w1

x2 w2
n 1
i 1
(hi) oi

xn wn

Figura 4. Schema modelului matematic Hebb

Pentru simplificare, vom nota suma ponderată care reprezintă intrarea


totală în unitatea de procesare cu hi.
n
hi   x j  w j
j 1

O asemenea unitate poate fi privită ca un procesor de informaţie foarte


primitiv. Dacă vom conecta un număr de astfel de procesoare între ele,
obţinem o reţea neuronală artificială, sau mai corect spus, o structură de
calcul conexionistă.
Modul de legare a acestor procesoare între ele reprezintă topologia
reţelei şi determină modul de calcul al ponderilor, şi implicit funcţionalitatea
reţelei.
Calculul ponderilor este denumit învăţare sau antrenare, iar metodele
iterative de calcul sunt cunoscute sub denumirea de algoritm de învățare
sau de antrenare.

17.2.3 Arhitecturi ale RNA

Reţele neuronale de tip perceptron


Sunt reţelele neuronale cele mai cunoscute datorită capacităţii acestora
de generalizare adică de a opera cu date diferite de cele prezentate în etapa
de antrenament. Sunt reţele în care propagarea datelor este făcută de la

284
intrare la ieşire (feedforward), caracteristică care este aplicată prin faptul că
un neuron poate avea ca intrări numai ieşirile neuronilor de pe straturile
precedente. Vom începe analiza noastră plecând de la o reţea neuronală
simplă cu un singur strat, perceptronul simplu, şi vom continua analiza până
la reţelele neuronale multistrat cu propagare înainte (multi-layer feed forward
networks).

A. Perceptronul cu un singur strat


Este o reţea simplă care a reuşit să stârnească interesul datorită
capacităţii de recunoaştere a unor tipare simple. Prezentăm în Figura 5 o
astfel de reţea având N intrări şi o singură ieşire.

x0
w0
x1
w1 y

wN-1
xN-1

Figura 5. Perceptronul cu un singur strat

Ieşirea reţelei este calculată după următoarea formulă:

 N 1 
y  f h   wi xi   
 i 0  (17.1)

Termenul θ poartă denumirea de bias şi poate fi orice funcţie sau constantă.


Vom vedea mai târziu importanţa acestui termen. Funcţia de activare fh
poate fi orice funcţie liniară (în acest caz avem o reţea liniară) sau
neliniară. Pentru peceptronul simplu considerăm că fh este funcţia
treaptă.

285
 1 daca s  0
f h s   
 1 daca s  0 (17.2)

Această reţea clasifică într-una din cele două clase disponibile (A sau B) un
set de intrări. Astfel dacă ieşirea y este 1 atunci avem clasa A, în timp
ce pentru ieşirea -1 avem clasa B. Altfel spus reţeaua reuşeşte
divizarea spaţiului intrărilor în două regiuni separate de un hiperplan.
Putem observa acest lucru considerând că avem 2 intrări. În acest caz
reţeaua separă spaţiul intrărilor în două după o linie ce are următoarea
ecuaţie:

w1 x1  w2 x2    0 (17.3)

Transformând ecuaţia (17.3) obţinem reprezentarea geometrică a liniei ce


separă cele două regiuni :
w1 
x2   x1 
w2 w2 (17.4)

Observăm cum toate intrările care sunt deasupra liniei aparţin clasei A în
timp ce intrările de sub linie aparţin clasei B (Figura 6).

Figura 6. Reprezentarea geometrică a liniar separabilităţii


spaţiului de intrare în două regiuni
Trebuie spus că ponderile determină panta liniei în timp ce termenul bias
determină ofsetul (la ce distanţă de origine este linia). Găsirea termenului bias
şi a ponderilor reţelei este posibilă în urma aplicării algoritmului de învăţare
asupra reţelei.

286
Situațiile în care cele două clase sunt liniar separabile sunt rare, în
majoritatea cazurilor acestea sunt neliniar separabile. Un exemplu este dat în
figura următoare

Această situație poate fi rezolvată utilizând o funcție de activare neliniară


cea mai utilizată fiind o funcție sigmoid.
În Tabelul 1 se prezintă principalele funcţii de activare și intervalul în
care acestea pot lua valori. Se poate observa că majoritatea funcţiilor sunt
diferenţiabile.

Tabelul 1. Definiţia principalelor funcţii de activare

287
Există și o împărţire a funcţiilor de activare pe categorii, în funcţie
de valoarea pe care reţeaua neuronală o prezintă la ieșire. Astfel avem
următoarele categorii:
 Dacă ieșirile reţelei sunt binare se utilizează funcţiile sigmoidă
si softmax. Problemele care se încadrează în această categorie sunt acelea
de recunoaștere de tipare, de clasificare, etc. Funcţia softmax este
predominant folosită la stratul de ieșire pentru un sistem de clustere. Aceasta
convertește o valoare brută într-o probabilitate posterioară ce ne oferă o
măsură a certitudinii.
 Pentru ieșiri ale reţelei care se doresc a fi continue și limitate de
un interval avem funcţia de activare sigmoidă, sinus și tangentă
hiperbolică. În această categorie se regăsesc funcţii de aproximare, metode
de interpolare și metode statistice.
 Pentru ieșiri continue și nelimitate avem funcţia exponenţială, radical
sau identitate.

Exemple
(A)

288
Ca şi limitare a acestor reţele putem aminti problematica
 XOR (sau-exclusiv),
 XNOR negația operației de disjuncție exclusivă (XOR) sau
orice tip de problema al cărui strat de intrare nu poate fi separabil în două
regiuni.
Pentru problema XNOR cele afirmate sunt prezentate în figura de mai jos în
care x1 și x2 primesc valorile binare 0, 1.

Pentru rezolvare acestei probleme se recurge la adăugarea unui strat de


neuroni intermediari a cărui denumire este de strat ascuns. Modul în care
apare acesta este ilustrat în secvența de figuri următoare

289
B. Perceptronul cu mai multe straturi
Reţelele de tip perceptron cu mai multe straturi (multi-layer
perceptron) sunt reţele de tip propagare înainte cu unul sau mai multe straturi
situate între nodurile de intrare şi nodurile de ieşire. Aceste straturi (straturi
ascunse) conţin neuroni care nu sunt direct conectaţi cu intrările sau ieşirile
reţelei. Toate limitările impuse de perceptronul cu un singur strat sunt
depăşite de acest tip de reţea.

290
Performanţele unei reţele de tipul perceptron cu mai multe straturi
constau în folosirea unor funcţii de activare neliniare pentru nodurile interne.
Dacă am folosi numai funcţii de activare liniară putem aproxima o reţea
neuronală de tip perceptron cu mai multe straturi cu o reţea de tip perceptron
cu un singur strat.
Ca şi arhitectură, perceptronul cu mai multe straturi se prezintă ca în
Figura 7.

Ni No
Nh,1 Nh,s
Nh,2
Figura 7. Perceptronul multistrat cu s straturi ascunse

 Primul strat Ni este stratul de intrare. Neuronii de pe acest strat


sunt lipsiţi de funcţia de activare, adică lasă să treacă orice valoare
primită la intrare.
 Următoarele s straturi (Nh,1 , .., Nh,s) se numesc straturi
ascunse. Fiecare strat ascuns (Nh,l) primeşte valori la intrare numai de la
stratul anterior lui (Nh,l-1), ieşirile lui constituindu-se ca intrări pentru
stratul următor (Nh,l+1). Nu sunt permise conexiuni în interiorul stratului.
 Ieşirile ultimului strat ascuns Nh,s sunt intrări pentru stratul de
ieşire No. Trebuie spus că sunt permise şi conexiuni de genul skip layer
(astfel neuronii pot primi ca şi intrări, ieşirile altor neuroni care nu se află
pe un strat imediat precedent lor). Conexiunile directe între stratul de
intrare şi cel de ieşire sunt în special foarte folositoare.
 Numărul de neuroni de pe straturile ascunse poate fi diferite de
la strat la strat. Fiecare dintre aceşti neuroni are o funcţie de activare Fi
care acţionează asupra intrărilor şi bias-ului.

291
Minsky şi Papert au arătat în 1969 că o reţea neuronală de tip
perceptron multistrat cu 1 strat ascuns, rezolvă multe dintre problemele
rămase nerezolvate de perceptronul cu un singur strat, dar nu au putut
prezenta o soluţie la modul de ajustare a ponderilor în această reţea. Soluţia
la această problemă a venit în 1986, când Rumelhart, Hinton şi Williams au
determinat modul de ajustare al ponderilor propagând eroarea de la stratul de
ieşire spre stratul de intrare. Această tehnică s-a şi numit back-propagation.
Deşi tehnica back-propagation poate fi aplicată la reţele de tip perceptron cu
oricâte straturi ascunse, s-a arătat că pentru reţele cu intrări binare, un singur
strat ascuns este suficient pentru aproximarea oricărei funcţii ce are un număr
finit de discontinuităţi (Teorema aproximării universale). În cele mai multe
aplicaţii este utilizată funcţia sigmoid ca şi funcţie de activare a neuronilor.

Tehnica back-propagation implică 2 faze:


 Prima fază – avem o intrare x pe care o aplicăm la intrarea reţelei.
Valorile se propagă înainte trecând din start în strat şi ajungând până la
stratul de ieşire. Comparăm valorile prezentate în stratul de ieşire al reţelei
cu valorile dorite rezultând o valoare de eroare.
 Faza a doua – valorile de eroare sunt trecute invers prin reţea, de la
ieşire la intrare, având ca scop modificarea ponderilor neuronilor de pe
fiecare strat al reţelei.

Aşa cum am spus şi mai sus un singur strat ascuns e suficient pentru
rezolvarea majorităţii problemelor. Putem folosi însă şi două sau trei straturi
ascunse pentru probleme dificile. Dacă numărul neuronilor de pe straturile de
intrare şi ieşire este uşor determinabil (ţine exclusiv de natura aplicaţiei),
numărul neuronilor de pe stratul ascuns este dificil de aproximat.
Neuronii de pe straturile ascunse au rol în detectarea trăsăturilor
comune pentru tiparele de antrenament. De aceea un număr prea mic de
neuroni va influenţa negativ capacitatea de generalizare a reţelei conducând
la o eroare medie pătratică mare. Un număr mare de neuroni conduce la un
volum de calcul mare şi măreşte exponenţial timpul de antrenament.

292
Ca şi concluzie putem nota faptul că în prezent alegerea numărului de
neuroni de pe stratul ascuns este făcută experimental.

Exemplu

Sa se calculeze ieșirea rețelei neuronale hΘ(x) pentru x1 = 2 și x2 = 3. Se


cunosc matricele de ponderi Θ(1) (leagă stratul 1 de stratul 2) și Θ(2) (leagă
stratul 2 de stratul 3). Neuronii sunt toți la fel: nu au bias și funcția de activare
este liniara f(x) = x.

 0.5 0.5 
  (2)   1 1 0
 (1)
  0.2 0.2 
 1 1 
 

Răspuns: Pentru al 2-lea strat avem ieșirile:


a1=f(-0.5*x1+0.5* x2) = 0.5 ;
a2=f(0.2*x1-0.2* x2) = -0.2;
a3=f(1*x1-1* x2) = -1

Ieșirea rețelei: hΘ(x) = f(-1* a1+1*a2+0*a3) = -0.7

293

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