Sunteți pe pagina 1din 87

Coperta: dup lucrarea Astrul Dimineii de Virginia Baz-Baroiu

Cartea Introducere n inteligen artificial Aplicaii cu strategii de cutare


neinformate i informate scris de dl. dr. ing. Bogdan Groza abordeaz ca
subiect rezolvarea problemelor prin strategii de cutare, oferind totodat o
manier de evaluare comparativ a performanelor acestor strategii. Lucrarea
are un pronunat caracter aplicativ, materialul fiind organizat ntr-o structur
tipic lucrrilor de laborator. Dei lucrarea se adreseaz n principal
stundenilor, maniera cursiv i concis n care este scris ofer o lectur
plcut i util oricrui cititor interesat de subiect. n plus, doresc s subliniez
rigoarea tiinific a materialului prezentat n lucrare, rezultat n mod firesc din
experiena deosebit de cercettor a autorului.
Referent tiinific: ef lucrri dr.ing. Dorina Petric

INTRODUCERE N INTELIGEN ARTIFICIAL


APLICAII CU STRATEGII DE CUTARE NEINFORMATE
I INFORMATE

Aplicaii cu strategii de cutare neinformate i informate

-4-

INTRODUCERE N INTELIGEN ARTIFICIAL


APLICAII CU STRATEGII DE CUTARE NEINFORMATE
I INFORMATE

Bogdan Groza1

Universitatea Politehnica Timioara, Facultatea de Automatic i Calculatoare, Bd. Vasile


Prvan nr. 2, Room A304, 300223, Timioara, Romnia, e-mail: bogdan.groza@aut.upt.ro,
web: www.aut.upt.ro/~bgroza.

Aplicaii cu strategii de cutare neinformate i informate

-5-

CUPRINS

LUCRAREA 1
ARTIFICIALE

INTRODUCERE N PROBLEMATICA INTELIGENEI


8

1.1
1.2
1.3
1.4

AGENTUL INTELIGENT, CAPACITATEA DE A REZOLVA PROBLEME ................................8


FORMULAREA UNEI PROBLEME ...................................................................................10
ETAPELE REZOLVRII UNEI PROBLEME .......................................................................11
EFICIENA REZOLVRII UNEI PROBLEME MSURI CALITATIVE I CANTITATIVE N
EVALUAREA STRATEGIILOR DE CUTARE ..................................................................................12
1.5
IMPLEMENTAREA GENERAL A STRATEGIILOR INFORMATE I NEINFORMATE ...........13
1.6
EXERCIII ....................................................................................................................14
LUCRAREA 2
STRATEGII NEINFORMATE DE CUTARE: STRATEGIILE DE
CUTARE PE NIVEL I BIDIRECIONAL .....................................................................17
2.1
2.2
2.3
2.4

STRATEGII DE CUTARE I CARACTERISTICI ALE ACESTORA ......................................17


STRATEGIA DE CUTARE PE NIVEL (BREADTH-FIRST) ...............................................17
STRATEGIA DE CUTARE BIDIRECIONAL (BIDIRECTIONAL SEARCH) .....................20
EXERCIII ....................................................................................................................22

LUCRAREA 3
3.1

EVITAREA CICLURILOR N ALGORITMII DE CUTARE ........31

EXERCIII ....................................................................................................................31

LUCRAREA 4
STRATEGII NEINFORMATE DE CUTARE: STRATEGIILE DE
CUTARE N ADNCIME, ADNCIME LIMITAT I ADNCIME ITERATIV...34
4.1
4.2
4.3
4.4

STRATEGIA DE CUTAREA N ADNCIME (DEPTH-FIRST) ..........................................34


STRATEGIA DE CUTARE LIMITAT N ADNCIME (DEPTH-LIMITED)........................35
STRATEGIA DE CUTARE ITERATIV N ADNCIME (ITERATIVE-DEEPENING)...........36
EXERCIII ....................................................................................................................38

LUCRAREA 5
STRATEGII NEINFORMATE DE CUTARE: STRATEGIA DE
CUTARE CU COST UNIFORM ............................................................................................42
5.1
5.2

STRATEGIA DE CUTARE CU COST UNIFORM (UNIFORM COST) .................................42


EXERCIII ....................................................................................................................44

Aplicaii cu strategii de cutare neinformate i informate

-6-

LUCRAREA 6
STRATEGII INFORMATE DE CUTARE: STRATEGIILE DE
CUTARE BEST FIRST I GREEDY ....................................................................................54
6.1
6.2
6.3
6.4

CE ESTE O EURISTIC ..................................................................................................54


STRATEGIA DE CUTARE BEST FIRST .........................................................................55
STRATEGIA DE CUTARE GREEDY ..............................................................................55
EXERCIII ....................................................................................................................56

LUCRAREA 7
7.1
7.2
7.3

PROBLEME CU CONSTRNGERI ...................................................................................60


ROLUL UNEI EURISTICI ................................................................................................60
EXERCIII ....................................................................................................................61

LUCRAREA 8
CUTARE A*
8.1
8.2

STRATEGII INFORMATE DE CUTARE: STRATEGIA DE


62

DEMONSTRAIE ASUPRA OPTIMALITII LUI A* ........................................................63


EXERCIII ....................................................................................................................63

LUCRAREA 9
9.1

ALEGEREA UNEI EURISTICI .............................................................60

STRATEGII DE CUTARE N SPAII CU INCERTITUDINI .......68

EXERCIII ....................................................................................................................80

LUCRAREA 10

NTREBRI RECAPITULATIVE I PROBLEME............................81

Aplicaii cu strategii de cutare neinformate i informate

-7-

Cuvnt nainte

Prezentul material este destinat pentru a fi utilizat n cadrul activitii de


laborator de ctre studenii din anul IV ai Facultii de Automatic i Calculatoare din
Universitatea Politehnica din Timioara care urmeaz materia Bazele Inteligenei
Artificiale dar poate fi desigur folosit de oricine l consider util. Lucrrile coninute
reprezint doar o parte din lucrrile de laborator efectuate n perioada 2005-2008 cu
studenii anului 4 Automatic la materia Inteligen Artificial, lucrri care vor fi pe de
o parte continuate cu studenii anului 4 Ingineria Sistemelor la materia Bazele
Inteligenei Artificiale. Aceste lucrri reprezint doar prima parte a laboratorului de
Inteligen Artficial inut pentru promoiile de 5 ani, a doua parte a adresat problemele
de logic (implementare n Prolog) i reele neuronale. Este posibil ca prezentul
material s fie extins i cu lucrrile aferente acestei a doua pri n funcie de interesul
acordat disciplinei de ctre studeni i posibilitatea activrii sale, acum materia avnd
caracter opional. Materialul poate fi accesat on-line la www.aut.upt.ro/~bgroza/iia.pdf.

Timioara,
Noiembrie 2008

Bogdan Groza

Aplicaii cu strategii de cutare neinformate i informate

-8-

Lucrarea 1
Introducere n problematica
Inteligenei Artificiale
1.1

Agentul inteligent, capacitatea de a rezolva probleme

Russel i Norvig, n binecunoscuta lor carte Artificial Intelligence a Modern


Approach, devenit referin de nelipsit pentru orice curs n domeniu, definesc
inteligena artificial ca fiind studiul agenilor existeni ntr-un mediu care percep i
acioneaz.
Agentul poate fi perceput ca o entitate care percepe mediul prin intermediul
senzorilor i acioneaz asupra lui prin intermediul efectorilor. De asemenea un agent
are o arhitectur, pe care o asociem prii fizice a acestuia, numit hardware, i un
program de funcionare, care l numim software. Acest lucru este ilustrat n figura 1.1.
De remarcat c acest concept nu adreseaz doar ageni de natur fizic tip robot ci
chiar i ageni de natur virtual (sub form de program, algoritm etc.) care au i ei o
component hardware pe care funcioneaz. Partea software, programul, este
componenta care pstreaz natura inteligent.

Figura 1.1 Agentul inteligent n interaciunea sa cu mediul

Aadar obiectivul Inteligenei Artificiale este construirea Agenilor Inteligeni.


ntrebarea este ns ce ne face s numim un agent ca fiind inteligent. Rspunsul la
aceast ntrebare nu este simplu i de-a lungul anilor au fost dezvoltate diverse
poteniale rspunsuri. Poate cel mai cunoscut criteriu pentru a demonstra c o main

Aplicaii cu strategii de cutare neinformate i informate

-9-

este inteligent este testul Turring ilustrat n figura 1.2, descris de Alan Turing n 1950
n lucrarea "Computing Machinery and Intelligence". n acest test, un participant A
discut pe o linie cu o main de calcul B (agentul inteligent) i pe alt linie cu un alt
participant uman C. Toi participanii la comunicare sunt n incinte izolate fr contact
cu mediul, iar la final participantul A trebuie s poat face distincia ntre B i C, care
este main i care este om. Dac nu se poate face aceast distincie maina a trecut
testul i este inteligent.
Camera B

Participant uman C

om

Co
m
un
ica
r

Masina inteligenta B

un
ic
ar
e

Camera C

Camera A

Care dintre B si C este masina inteligenta sau om ?

Participant uman A

Figura 1.2 Test Turing

Sigur, trecerea acestui test este un deziderat greu de atins. Pentru contextul de
fa vom opta pentru un rspuns mai simplu, care chiar dac mai redus ca profunzime
i complexitate, nu este lipsit de semnificaie. Vom defini un agent inteligent ca fiind o
entitate capabil de a rezolva probleme. ntr-adevr, capacitatea de a rezolva probleme
este o dovad de inteligen. Mai mult, chiar i noi, ne-am format inteligena nc din
cele mai timpurii stagii, rezolvnd probleme.
Dar ce nseamn a rezolva o problem? Indiferent de problema adresat i de
mediul de care aparine, chiar este recomandabil s gndim acest lucru nu n contextul
agenilor inteligeni artificiali ci al vieii noastre de zi cu zi, rezolvarea unei probleme
poate fi ntotdeauna vzut ca fiind echivalent cu capacitatea de a lua nite decizii,
deci orice problem este o problem decizional n cele din urm. Exemplele sunt
desigur numeroase, de exemplu a juca ah nseamn a putea lua n mod corect o decizie
asupra piesei care trebuie mutat, sau a trece strada nseamn a lua n mod corect o
decizie cu privire la momentul n care trebuie s facem un anume pas etc.
Acest lucru ne duce n cele din urm la a defini un agent inteligent ca fiind o
entitate capabil de lua decizii n scopul rezolvrii unei probleme. Pentru a accentua
caracterul inteligent al lurii de decizii este de dorit ca entitile inteligente s poat

Aplicaii cu strategii de cutare neinformate i informate


-

- 10

evalua efectul decizilor (plan-ahead) iar aceast evaluare se face n baza informailor
disponibile agentului, de cele mai multe ori acestea fiind ns incomplete (altfel spus,
entitile inteligente nu sunt tot timpul omnisciente).

1.2

Formularea unei probleme

Trebuie acum s lmurim ce nseamn din punct de vedere formal rezolvarea


unei probleme. nainte de a rezolva o problem aceasta trebuie formulat. Formularea
sau descrierea unei probleme, indiferent de natura ei, se poate face n baza a trei
noiuni:
Stare iniial (SI) starea din care ncepe problema.
Stare final (SF) starea n care se termin problema.
Operatorii de generare a strilor - aciunile care pot fi ntreprinse.
Se impune observaia c starea final poate fi specificat n mod direct, adic
explicit printr-o valoare, sau indirect, printr-o funcie de test. Ca exemplu putem
considera problema n care un agent trebuie s se deplaseze din punctul A n punctul B.
n acest caz starea final este explicit dat ca fiind punctul B. Pentru cel de-al doilea
caz putem considera alt problem, de exemplu jocul de ah. n acest caz starea final
nu este explicit specificat, pentru c starea final este cea de ah mat, dar cum arat
ah mat? Evident acest lucru nu poate fi tiut la nceputul jocului i din acest motiv
trebuie s existe o funcie de test cu ajutorul creia la fiecare pas se poate testa dac
starea atins este ah mat. De asemenea pot fi una sau mai multe stri finale valide care
rezolv problema. n general specificarea explicit a unei stri finale i unicitatea
acesteia poate fi folosit ca avantaj n rezolvarea unei probleme deoarece se pot aplica
strategii de cutare ceva mai eficiente ca timp i spaiu precum cutarea bidirecional
aa cum se va vedea n capitolul 2.
Spaiul strilor este totalitatea de stri n care se poate ajunge, aplicnd
succesiv operatori pe strile nou rezultate din starea curent. Putem de asemenea defini
spaiul strilor ca fiind ansamblul de stri i tranziii posibile ntre acestea, acest lucru
crend o imagine de tip graf asupra problemei (o astfel de imagine este n general un
bun punct de plecare n rezolvarea problemelor).
Prin drum sau cale n spaiul strilor nelegem orice secven de stri legate
prin operatori n spaiul starilor. Fiecare drum n spaiul strilor are un cost, care este
evaluat de o funcie care o vom nota cu g i care asociaz unui drum un cost. Costul
drumului prin spaiul strilor de la starea iniial la starea curent se mai numete i
costul strii sau al nodului, n momentul n care discutm de arbori de cutare.
n acest context soluia unei probleme este drumul prin spaiul strilor de la
starea iniial la starea final. Trebuie evitat confuzia c starea final este soluia
problemei, soluia problemei este drumul pn la starea final i nu starea final n
sine. Acum putem defini foarte simplu i ce presupune rezolvarea unei probleme:
rezolvarea unei probleme este cutarea unei ci de la starea iniial la starea final a

Aplicaii cu strategii de cutare neinformate i informate


-

- 11

problemei i deci echivaleaz cu gsirea unei ci n spaiu strilor de la starea iniial la


starea final.
Poate fi util s ne oprim asupra unui exemplu ilustrativ. Una dintre problemele
care vor fi studiate n acest material, datorit simplitii dar i a puterii de
exemplificare este puzzleul 3x3, ilustrat n figura 1.3, ce poate fi generalizat sub forma
nxn. Pentru acesta putem extrage urmtoarele caracteristici:
Stare iniial: orice aranjare a pieselor din careu care este punctul de
plecare al problemei.
Stare final: orice aranjare prestabilit a pieselor.
Operatori: toate mutrile posibile ale spaiului liber: stnga, dreapta, sus,
jos (desigur, e vorba de mutarea fizic a pieselor din jurul acestuia)
Rezolvare: gsirea unui drum prin spaiul strilor de la starea iniial ctre
starea final prin aplicarea operatorilor (deci mutrile care trebuie fcute
pentru a ajunge de la configuraia care se d la configuraia care se cere)
Spaiul strilor: numrul de variante posibile pentru a aranja piesele pe
tabl, anume permutri de 9 care nseamn 9!= 362880 stri
Se impune ns o observaie esenial, i anume, c de fapt sunt mult mai
puine stri dect 9! pentru c exist i poziii n care nu se poate ajunge, de exemplu
orice poziie care s-ar obine prin interschimbarea a dou piese alturate. Din acest
motiv dimensiunea spaiului strilor o vom trata sub indicatorul de complexitate O
astfel putem spune n mod riguros c dimensiunea spaiului strilor pentru puzzleul de
n piese este O(n!) prin aceasta indicnd n fapt doar o limit superioar asupra
numrului de stri ale problemei.

1 2 3
6
4
7 5 8
Stare Initiala

1 2 3
4 5 6
7
8
Stare Intermediara
Figura 1.3 Exemplu de puzzle 3x3

1.3

Etapele rezolvrii unei probleme

1 2 3
4 5 6
7 8
Stare Finala

Aplicaii cu strategii de cutare neinformate i informate


-

- 12

n baza preambulului fcut, putem enumera urmtorii pai care trebuie s i


urmm n rezolvarea unei probleme:
1) Abstractizarea - nseamn eliminarea detaliilor inutile i pstrarea
elementelor eseniale rezolvrii problemei
2) Determinarea strii iniiale
3) Determinare strii finale
4) Extragerea operatorilor (aciunilor posibile)
5) Pornirea unei strategii de cutare n spaiul strilor
Este de remarcat c paii 1,2,3 i 4 in de formularea problemei n timp ce
pasul 6 reprezint aplicarea strategiei de cutare i rezolvarea efectiv a problemei.
Generarea unor stri noi se face prin aplicarea operatorilor asupra strii curente n timp
ce alegerea efectiv a strii care urmeaz s fie explorat (expandat) este determinat
de strategia de cutare folosit.
Odat cu pornirea unei strategii de cutare se ajunge implicit la generarea
spaiului strilor i mai exact se va ajunge la o structur ce poate fi asociat unui
Arbore de Cutare. Este de remarcat c arborele de cutare nu trebuie s apar explicit
ca structur de date, ci acesta poate fi simulat de ctre algoritmul de cutare. Aadar
structura de date asociat n mod concret sau virtual unei strategii de cutare este
arborele de cutare. n mod uzual asociem urmtoarele informaii unui nod al arborelui
de cutare:
Starea starea creia nodul i este asociat
Printele nodului nodul care a generat nodul curent
Operator operatorul prin care a fost generat nodul
Adncime numrul de nivele pn la acest nod
Cost costul drumului de la nodul rdcin la nodul curent
Euristica valoare estimativ a distanei pn la starea final
Este important de observat c arborele de cutare nu este acelai lucru cu
spaiul strilor, de exemplu Arborele de Cutare poate avea un numr infinit de stri
chiar dac Spaiul Starilor este finit n cazul n care strategia de cutare are cicluri
(aspect discutat n capitolul 3). De asemenea un nod dintr-un Arbore de Cautare
corespunde unei stri dar nu este echivalent cu aceasta deoarece de exemplu un nod are
un singur nod printe n timp ce ntr-o stare se poate ajunge din mai multe stri i n
acest caz o stare poate avea mai multe stri printe.

1.4

Eficiena rezolvrii unei probleme msuri calitative i


cantitative n evaluarea strategiilor de cutare

La alegerea unei strategii de cutare pentru rezolvarea unei probleme,


evaluarea eficienei rezolvrii problemei poate fi pus din diverse puncte de vedere. De
exemplu iat cteva ntrebri orientative: Cutarea ajunge la o soluie? Soluia gsit a
fost cea mai bun? Soluia a fost furnizat n timp util? Care au fost costurile gsirii

Aplicaii cu strategii de cutare neinformate i informate


-

- 13

acestei soluii? De cele mai multe ori, strategia de cutare aleas poate fi un compromis
ntre calitatea soluiei (costul cii Stare iniial Stare final) i costul cutarii (timp,
memorie, costuri de implementare etc.).
Pe lng astfel de ntrebri orientative, exist msuri cantitative i calitative
exacte pentru a estima eficiena unei strategii de cutare. Acestea sunt urmtoarele:
Msuri cantitative:
Complexitatea de timp a strategiei T - n ct timp (msurat ca numr de
pai ai algoritmului) este gsit soluia.
Complexitatea de spaiu a strategiei S de ct spaiu (este vorba de
memorie) este nevoie pentru gsirea soluiei.
Msuri calitative:
Completitudine o strategie se numete complet dac garanteaz gsirea
unei soluii.
Optimalitate o strategie se numete optimal dac garanteaz gsirea
celei mai bune soluii din punctul de vedere al costului cii ntre starea
iniial i starea final.
Trebuie precizat c n timp ce complexitile de timp i spaiu sunt aprecieri
pur cantitative, msurate cu ajutorul indicatorului de complexitate O, completitudinea
este ntotdeuna o proprietate binar: o strategie este sau nu este complet. n ceea ce
privete 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 gsesc cea
mai bun soluie dar gsesc o soluie foarte apropiat ca i cost de cea mai bun soluie
(de exemplu A* atunci cnd nu folosim euristici admisibile, un astfel de caz va fi
discutat n seciunea 8).

1.5

Implementarea general a strategiilor informate i neinformate

Toate strategiile de cutare neinformate i informate discutate n acest material


urmeaz aceeai paradigm general n implementare. Pe lng paii anterior amintii
de abstractizare, extragere a strilor iniial i final, respectiv a operatorilor, trebuie s
adugm i pasul n care se realizeaz cutarea efectiv pe care l vom denumi funcie
de cutare (funcie search). Acest lucru este ilustrat n figura 1.4.
n ceea ce privete funcia search aceasta are ca i component de baz o bucl
n care se realizeaz succesiv: extragerea noului nod successor, testarea dac acest nod
corespunde strii finale, adugarea succesorilor nodului curent n lista utilizat pentru
memorarea strilor. Lista de noduri este cea care face diferena ntre diversele strategii
de cutare, aceasta fiind stiv, coad, list ordonat dup euristic etc. Pseudocodul
funciei search este urmtorul:
funcie search {
nod_curent.stare = stare_iniial
adaug nod_curent n lista_noduri
repet la infinit {
dac lista_noduri este vid atunci return(failure)

Aplicaii cu strategii de cutare neinformate i informate


-

- 14

nod_curent = extrage_nod(list_noduri)
dac nod_curent.stare=stare_final atunci soluie()
adaug n lista_noduri succesori(nod_curent)
}
} sfrit funcie

1.6

Exerciii

1. Se consider un puzzle 3x3 (asemenea celui din figura 2) i un tablou cu leduri de


dimensiune 3x3 la care prin apsarea unui led acesta i schimb starea proprie din
stins n aprins (i invers) precum i a ledurilor aflate n stnga, dreapta, sus, jos fa de
acesta. n starea iniial toate ledurile sunt stinse i se dorete o stare final cu toate
ledurile aprinse. Se cere:
a) Care este dimensiunea spaiului starilor pentru cele 2 probleme?
b) Care sunt operatorii asociai?
c) Desenai arborele de cutare.
2. Una dintre cele mai vechi probleme abordate de strategiile de cutare este problema
canibalilor i misionarilor. Trei canibali i trei misionari se afl pe marginea unui ru,
tiind c barca de care dispun nu poate lua dect 2 persoane i pe nici unul dintre
rmuri nu pot fi mai muli canbali dect misionari s se gseasc o soluie pentru ca
acetia s traverseze rul (n figura 1.5 este sintetizat arborele de cutare pentru aceast
problem).

Aplicaii cu strategii de cutare neinformate i informate


-

Figura 1.4. Abordarea general a unei probleme folosind o strategie de cutare

- 15

Aplicaii cu strategii de cutare neinformate i informate


-

Figura 1.5. Arborele de cutare pentru problema canibalilor i misionarilor

- 16

Aplicaii cu strategii de cutare neinformate i informate


-

- 17

Lucrarea 2
Strategii neinformate de cutare:
strategiile de cutare pe nivel i bidirecional
2.1

Strategii de cutare i caracteristici ale acestora

Strategiile de cutare care nu folosesc euristici pentru a alege nodul successor


se mai numesc i strategii de cutare neinformate sau oarbe (blind-search). apte
strategii de cutare neinformate sunt abordate n acest material:
Strategia de cutare pe nivel (Breadth-First)
Strategia de cutare n adncime (Depth-First)
Strategia de cutare cu cost uniform (Uniform Cost)
Strategia de cutare limitat n adncime (Depth-Limited)
Strategia de cutare iterativ n adncime (Iterative-Deepening)
Strategia de cutare bidirecional (Bidirectional search)
Cu privire la toate acestea, inclusiv strategiile informate ce vor urma,
intereseaz aflarea rspunsului la urmtoarele ntrebri:
a) Care este complexitatea de timp a strategiei?
b) Care este complexitatea de spaiu a strategiei?
c) Este strategia complet?
d) Este strategia optimal?
e) Cum se implementeaz?
f) Ce avantaje i dezavataje are?
Rspunsul la ntrebrile de la a) la f) va fi dat n cele ce urmeaz n cazul
particular al fiecrei strategii n parte. n ceea ce privete ntrebarea e) aceasta se refer
la tipul structurii de date n care se rein nodurile arborelui de cutare. Aa cum se va
observa este vorba de structuri de tip coad, stiv sau liste sortate. n ceea ce privete
ntrebarea de la f) aceasta presupune o analiz n baza caracteristicilor proprii de la a)
la e) dar i o analiz comparativ cu celelalte strategii.

2.2

Strategia de cutare pe nivel (Breadth-First)

Cea mai simpl strategie de cutare este cutarea pe nivel, numit i breadthfirst. Aceast strategie exploreaz nodurile n ordinea nivelelor, altfel spus nodurile de
pe nivelul d sunt explorate naintea nodurilor de pe nivelul d+1. Acest aspect este
ilustrat n figura 2.1, doar pentru simplitatea figurii s-a optat pentru un arbore binar,
deci exist doar doi operatori, altfel numrul de operatori poate fi variabil.

Aplicaii cu strategii de cutare neinformate i informate


-

- 18

Figura 2.1 Arborele de cutare n cazul strategiei breadth-first

Complexitate de timp i spaiu


Complexitatea

timp a strategiei poate fi simplu calculat ca


T = 1 + b + b + ... + b = O b d , unde d este adncimea primei soluii a problemei
(depth), iar b este factorul de ramificaie al problemei (branching factor).
Factorul de ramificaie maxim este egal cu numrul de operatori. Trebuie ns
observat c nu toi operatorii pot fi aplicai pe orice stare i din acest motiv factorul de
ramificaie nu este tot timpul egal cu numrul de operatori. Astfel putem avea un factor
de ramificaie minim, maxim i mediu. Dac lum ca exemplu un puzzle 3x3 aa cum
se poate observa i n figura 2.2 factorul de ramificaie maxim este 4 i minim 2 dar n
medie va fi 3. Se poate defini deasemenea un factor de ramificaie efectiv. Acesta se
calculeaz
pe
cale
experimental
i
este
rezultatul
ecuaiei
2
d
d
n = 1 + be + be + ... + be be n unde n este numrul de noduri explorate obinut pe
cale experimental.
2

de

1 2 3
6
4
7 5 8
Factor Ramificatie 4

( )

1 2 3
4 5 6
7
8
Factor Ramificatie 3

1 2 3
4 5 6
7 8
Factor Ramificatie 2

Figura 2.2 Factori de ramificaie variabili pe problema puzzleului 3x3

Aplicaii cu strategii de cutare neinformate i informate


-

- 19

( )

Complexitatea de spaiu este S = b d = O b d deoarece strategia reine tot


timpul doar nodurile de pe ultimul nivel al arborelui de cutare.

Completitudine i optimalitate
Aa cum se poate observa strategia de cutare pe nivel este complet atunci
cnd numrul de operatori este finit deoarece parcurge n mod exhaustiv toate nodurile
arborelui de cutare.
Strategia este ns optimal doar dac costul crete proporional cu adncimea,
deci dac orice nod este mai scump dect orice alt nod aflat pe un nivel deasupra lui.
Altfel spus, dac pentru oricare dou noduri: x, y , D ( x ) < D ( y ) g ( x ) < g ( y )
unde D este funcia care returneaz adncimea nodului i g reprezint costul. Deci nici
un nod de pe nivelul d+1 nu poate fi mai ieftin decat un nod de pe nivelul d , aceast
condiie este n particular satisfacut cnd costul operatorilor este egal, lucru valabil
pentru multe probleme ntlnite n practic, inclusiv problema puzzleului 3x3 anterior
aminitit.

Implementare
Strategia breadth-first poate fi uor implementat folosind o structur de tip
coad (queue) n care la fiecare pas se extrage din coad nodul curent i se adaug la
sfrit nodurile rezultate din explorarea nodului curent.
Extrage nod 1

Coada:

Pasul 1

Adauga succesori nod 1 Extrage nod 2

Pasul 2

Adauga succesori nod 2 Extrage nod 3

Pasul 3

Adauga succesori nod 3

Pasul 4

Figura 2.3. Evoluia cozii la strategia de cutare Breadth First

Avantaje i dezavantaje
Avantajul major este faptul c strategia este complet, mai mult este chiar i
optimal n condiiile anterior menionate.

Aplicaii cu strategii de cutare neinformate i informate


-

- 20

Dezavantajul major este faptul c are necesiti de memorie mult prea mari,
creterea spaiului fiind tot exponenial. n general spaiul este o problem mult mai
mare dect timpul, astfel, dac pentru un algoritm care solicit mult timp de calcul
putem n cele din urm atepta pn cnd furnizeaz rezultatul, n cazul n care
memoria nu este suficient, algoritmul evident nu poate rula i nu va furniza nicioadat
un rezultat. Tabelul 2.1 ilustreaz acest lucru pe o cretere exponenial de timp i
memorie.
Adncime
16
32
40
56

Timp
0.06 secunde
1.19 ore

Memorie
64 KB
4 GB

12 zile
2284 ani

1 TB
64 106 TB

Tabel 2.1. Creterea necesitilor de timp i spaiu pentru un algoritm de complexitate timp i

spaiu

10

2.3

( ) pentru cazul n care dimensiunea unei stri este 1 octet iar durata unui pas al algoritmului

O 2n

secunde.

Strategia de cutare bidirecional (Bidirectional search)

O potenial mbuntire la adresa strategiei de cutare pe nivel poate fi adus


prin pornirea a dou cutri simultane: una de la starea iniial ctre starea final i una
n sens invers. Acest lucru duce n mod evident la njumtirea resurselor de timp i
memorie necesare avnd singura cerin suplimentar de a pstra o list a frontierelor
pentru cele dou cutri n care s se verifice periodic dac nu exist noduri care
coincid, figura 2.4 ilustreaz acest lucru. Aceast strategie poart numele de strategia
de cutare bidirecional i menionm nc de acum c pentru economie de memorie
pe una dintre direcii poate fi aplicat i alt strategie precum strategia de cutare n
adncime ce va fi discutat n seciunea urmtoare.

Aplicaii cu strategii de cutare neinformate i informate


-

Noduri Frontiera

Arbore de cautare BF

Noduri Frontiera

Stare
Initiala

- 21

Stare
Finala

Arbore de cautare BF

d
d/2

d/2

Figura 2.4. Strategia de cutare bidirecional

Complexitate de timp i spaiu


Deoarece adncimea arborelui de cutare se njumtete, complexitile de
respectiv
timp i spaiu vor deveni T = 2 1 + b + b 2 + ... + b d / 2 = O b d / 2

S = 2b

d /2

= O(b

d /2

). Acest lucru este sugerat i n figura 2.4. La complexitatea de

timp trebuie adugat i timpul de calcul necesar pentru verificarea coliziunilor ntre
cele dou frontiere. Deoarece acest lucru implic o cutare binar, sub indicatorul O
complexitatea nu se schimb, mai exact ns timpul de calcul va fi
T = 1 + b + b 2 ... + b d + 1 + b log 2 b + b 2 log 2 b 2 + ... + b d / 2 log 2 b d / 2 = O b d / 2
n
cazul n care presupunem c la fiecare nod nou explorat se verific dac acesta nu
cumva exist n lista de frontiere a cutrii pornite din cealalt parte.

Completitudine i optimalitate
Cutarea bidirecional este complet i optimal dup cum sunt cele dou
strategii care le implic. Astfel pentru cazul n care se folosete breadth-first, este
complet tot timpul (atunci cnd factorul de ramificaie este finit) i este optimal pe
toate cazurile unde este i breadth-first optimal.

Implementare
Se implementeaz cele dou strategii de cutare, astfel se pornete cu breadthfirst simultan de la starea iniial i de la starea final. Pe lng aceasta se pstreaz i
dou liste ale frontierelor ntre care se verific periodic dac nu exist coliziuni. Se

Aplicaii cu strategii de cutare neinformate i informate


-

- 22

poate alege breadth-first dintr-o parte i o cutare diferit din cealalt parte, atenie ns
la riscurile ca nodurile din cele dou frontiere s nu coincid.

Avantaje i dezavantaje
Avantajul major este c reduce semnificativ costurile cutrii Breath First, dar
mai mult faptul c este mult mai rapid dect orice alt strategie neinformat. Ca
dezavantaj rmne consumul de memorie care este tot exponenial. Alt dezavantaj este
faptul c nu poate fi implementat dac nu este cunoscut starea final sau dac
operatorii de generare a strilor nu sunt inversabili sau sunt greu de calculat
predecesorii.

2.4

Exerciii

1. Doi frai au un vas de 8 litri cu ap i doresc sa l mpart n mod egal. Ei mai


dispun de dou vase de 3 respectiv 5 litri goale. Se cere:
a) abstractizai starea iniiala i final
SI={R1=0,R2=0,R3=8} SF={R1=0,R2=4,R3=4}
b) extragei operatorii
1.
2.
3.
4.
5.
6.

R3 R2
R3 R1
R2 R1
R2 R3
R1 R2
R1 R3

semnific toarn coninutul lui Ri n Rj pn cnd Ri este gol sau Rj este la


capacitate maxim
c) Propunei o strategie de cutare optimal i complet i precizai complexitatea
acesteia la o adncime d=8
Breadth-first:

S=T=O(bd)=68

d) Cutai soluia folosind strategia de la c) (se va evita explorarea strilor care


deja au mai fost ntlnite)
1

Aplicaii cu strategii de cutare neinformate i informate


-

- 23

{0,0,8}
{0,5,3}
{3,0,5}
{3,5,0}
{3,2,3}
{0,3,5}
{0,2,6}

{0,5,3}

{3,5,0}r

{3,5,0} r
{0,5,3} r
{0,5,3} r

{3,0,5}
{3,5,0}

{3,3,2}
{3,2,3} r

{3,2,3}

{3,0,5} r
{2,0,6}

{0,0,8}r

{3,0,5} r
{3,0,5} r
{0,0,8} r
{0,0,8} r

{0,3,5}

{0,5,3} r

{0,0,8}r
{0,5,3} r
{0,2,6}

{3,3,2}
{2,0,6}
{1,5,2}
{2,5,1}
{1,0,7}
{3,4,1}
{0,1,7}
{0,4,4}

{3,5,0} r
{2,5,1}

{1,5,2} r
{3,5,0} r
{0,5,3} r

{3,0,5} r
{3,5,0} r
{3,5,0} r
{3,0,5} r

{3,1,4}

{3,3,2} r
{3,4,1}

{1,0,7} r

{3,0,5} r

{1,0,7}
{2,0,6} r

{3,0,5} r
{0,0,8} r

{1,5,2}
{0,2,6} r

{0,1,7}
{2,5,1} r

{0,3,5} r
{0,0,8} r
{0,5,3} r
{0,5,3} r
{0,0,8} r
{0,4,4}

nseamn stare repetat i nu se va dezvolta n continuare


nseamn c operatorul nu poate fi aplicat
e) Determinai cte noduri au fost explorate, ce adncime are soluia i care este
factorul efectiv de ramificaie
-

adncimea este 8 i au fost explorate doar 14 noduri la un factor efectiv de


ramificaie b1,39

2. S se scrie programul C# care rezolv problema unui puzzle 3x3 folosind strategia
breadth-first urmrind interfaa din figura 2.5 de mai jos. Se cere: a) utilizarea unor
casete text TextBox pentru introducerea strii iniiale i finale b) pentru consum minim
de memorie se impune codificarea fiecrei stri a puzzle-ului ca ntreg pe 32 de bii c)
utilizarea unei cozi Queue pentru pentru implementarea strategiei e) afiarea pe ecran a
soluiei ntr-un obiect ListBox f) afiarea pe ecran a cantitii de memorie utilizate, a
numrului de stri explorate i a adncimii soluiei.

Aplicaii cu strategii de cutare neinformate i informate


-

- 24

Figura 2.5. Exemplu de interfa pentru un puzzle 3x3

Indicaii pentru rezolvare:


Definim o clas pentru reprezentarea nodurilor din arborele de cutare. Clasa
va conine un constructor care primete nodul printe, starea care corespunde
nodului i adncimea acestuia. Toate aceste valori sunt private i pot fi
returnate cu metode Get.
class SearchTreeNode
{
//nodul parinte
private SearchTreeNode parrentNode = null;
//starea asociata nodului curent
private int state;
//adancimea nodului
private int depth;
public SearchTreeNode(SearchTreeNode pn, int s,
int d)
{
parrentNode = pn;
state = s;
d = depth;
}
public SearchTreeNode GetParrentNode()

Aplicaii cu strategii de cutare neinformate i informate


-

- 25

{
return parrentNode;
}
public int GetState()
{
return state;
}
public int GetDepth()
{
return depth;
}
}
Coada se declar ca obiect de tip Queue. Vom mai defini ca valori globale
starea iniial respectiv starea final.
private Queue nodesToExplore = new Queue();
// coada care retine nodurile ce vor fi explorate
private int initialState; // starea initiala
private int finalState; // starea finala
Codificarea i decodificarea strilor din ir n ntreg i invers, util pentru
consum sczut de memorie i pentru compararea simpl a strilor, este
realizat de urmtoarele metode. Vom memora puzzleul ca ir i nu ca matrice
(deci ca matrice liniarizat).
// functile DecodeState si EncodeState se utilizeaza
pentru a decodifica starea din intreg in
// vector (pentru a putea face deplsarea spatiului sus,
jos, stanga, dreapta) respectiv codificarea
// din vector in intreg pentru a face memorarea starii in
nodul arborelui de cautare
private byte[] DecodeState(int state)
{
byte[] dstate = new byte[9];
int i = 0;
for (i = 0; i<9; i++)
{
dstate[8 - i] = (byte) (state % 10);
state = state / 10;
}
return dstate;

Aplicaii cu strategii de cutare neinformate i informate


-

- 26

}
private int EncodeState(byte[] state)
{
int estate = 0, i = 0;
for (i = 0; i < 9; i++)
{
estate = estate * 10 + state[i];
}
return estate;
}
Succesorii se genereaz n baza metodelor de mai jos
//generare stare succesor in functie de operatorul aplicat
up, down, left, right (daca e 0 nu se aplica, daca e 1 se
aplica)
private byte[] GenerateState(byte[] state, int pos, int
up, int down, int left, int right)
{
int i = 0;
byte[] newstate =new byte[9];
for (i = 0; i < 9; i++)
{
newstate[i] = state[i];
}
newstate[(pos / 3)*3 + pos % 3] =
newstate[((pos / 3) + up * (-1) + down * 1) * 3 + (pos %
3) + left * (-1) + right * 1];
newstate[((pos / 3) + up *(-1) + down * 1) * 3
+ (pos % 3) + left * (-1) + right * 1] = 0;
return newstate;
}
//adaugare succesori ai starii curente in coada (maxim 4
succesori)
private void AddSuccessors(SearchTreeNode currentNode){
SearchTreeNode left, right, up, down;
int i = 0;
while ((i < 9) &&
(DecodeState(currentNode.GetState())[i] != 0)) i++;
//determina pozitia spatiului liber, se observa ca i div 3
e linia pe care se afla spatiul liber si i mod 3 e coloana
if ( (i / 3) != 0)

Aplicaii cu strategii de cutare neinformate i informate


-

- 27

//nu este pe prim linie deci se poate muta sus


{
up = new SearchTreeNode( currentNode,
EncodeState(GenerateState(DecodeState(currentNode.GetState
()), i, 1, 0, 0, 0)), currentNode.GetDepth() + 1);
nodesToExplore.Enqueue(up);
}
if ((i/3) != 2)
//nu este pe linia de jos deci se poate muta jos
{
down = new SearchTreeNode( currentNode,
EncodeState(GenerateState(DecodeState(currentNode.GetState
()), i, 0, 1, 0, 0)), currentNode.GetDepth() + 1);
nodesToExplore.Enqueue(down);
}
if ((i%3) != 0)
//nu este pe coloana din stanga deci se poate muta stanga
{
left = new SearchTreeNode(currentNode,
EncodeState(GenerateState(DecodeState(currentNode.GetState
()), i, 0, 0, 1, 0)), currentNode.GetDepth() + 1);
nodesToExplore.Enqueue(left);
}
if ((i%3) != 2)
//nu este pe coloana din dreapta deci se poate muta
dreapta
{
right = new SearchTreeNode(currentNode,
EncodeState(GenerateState(DecodeState(currentNode.GetState
()), i, 0, 0, 0, 1)), currentNode.GetDepth() + 1);
nodesToExplore.Enqueue(right);
}
}
Funcia search care implementeaz algoritmul de cutare este urmtoarea
//functie search (algoritm de cautare)
private void Search()
{
SearchTreeNode currentNode = new
SearchTreeNode(null, initialState, 0);
nodesToExplore.Enqueue(currentNode);
do
{

Aplicaii cu strategii de cutare neinformate i informate


-

- 28

if ( nodesToExplore.Count == 0 )
//verifica daca mai sunt stari de explorat
{
System.Windows.Forms.MessageBox.Show("Nu exista solutie");
break;
}
currentNode = (SearchTreeNode)
nodesToExplore.Dequeue();
if ( currentNode.GetState() == finalState)
//verifica daca s-a ajuns la solutie
{
System.Windows.Forms.MessageBox.Show("S-a gasit solutia");
ShowSolution(currentNode);
break;
}
AddSuccessors(currentNode);
// adauga succesorii starii curente
}while(true);
}

Soluia este afiat prin parcurgerea arborelui de cutare de la nodul cu starea


final pn la rdcin care conine starea iniial
//afiseaza solutia in ListBox
private void ShowSolution(SearchTreeNode fs)
{
SearchTreeNode currentnode = fs;
byte[] dstate;
while (currentnode != null)
{
dstate = DecodeState(currentnode.GetState());
listaSolutie.Items.Add(dstate[0].ToString() + " " +
dstate[1].ToString() + " " + dstate[2].ToString() + "
dstate[3].ToString() + " " + dstate[4].ToString() + "
dstate[5].ToString() + " " + dstate[6].ToString() + "
dstate[7].ToString() + " " + dstate[8].ToString());
currentnode = currentnode.GetParrentNode();
}
listaSolutie.SelectedIndex = listaSolutie.Items.Count
labelAdancime.Text = "Adancime Solutie: " +
listaSolutie.Items.Count.ToString();

" +
" +
" +

- 1;

Aplicaii cu strategii de cutare neinformate i informate


-

- 29

labelDim.Text = "Dimensiune Coada: " +


nodesToExplore.Count.ToString();
}
Alte cteva funcii legate de interfa sunt urmtoarele
//pentru evenimentul Click pe buton
private void startButton_Click(object sender, EventArgs e)
{
nodesToExplore.Clear();
listaSolutie.Items.Clear();
InitStates();
Search();
}
//initializeaza starea initiala si starea finala din
casetele text
private void InitStates()
{
byte[] iState = { Convert.ToByte(SI0.Text),
Convert.ToByte(SI1.Text), Convert.ToByte(SI2.Text),
Convert.ToByte(SI3.Text), Convert.ToByte(SI4.Text),
Convert.ToByte(SI5.Text), Convert.ToByte(SI6.Text),
Convert.ToByte(SI7.Text), Convert.ToByte(SI8.Text) };
byte[] gState = { Convert.ToByte(SF0.Text),
Convert.ToByte(SF1.Text), Convert.ToByte(SF2.Text),
Convert.ToByte(SF3.Text), Convert.ToByte(SF4.Text),
Convert.ToByte(SF5.Text), Convert.ToByte(SF6.Text),
Convert.ToByte(SF7.Text), Convert.ToByte(SF8.Text) };
initialState = EncodeState(iState);
finalState = EncodeState(gState);
}
//afiseaza starea selectata din ListBox in casetele text
private void listaSolutie_SelectedIndexChanged(object
sender, EventArgs e)
{
char[] state =
listaSolutie.Items[listaSolutie.SelectedIndex].ToString().
ToCharArray();
SS0.Text = state[0].ToString();
SS1.Text = state[2].ToString();
SS2.Text = state[4].ToString();
SS3.Text = state[6].ToString();

Aplicaii cu strategii de cutare neinformate i informate


SS4.Text
SS5.Text
SS6.Text
SS7.Text
SS8.Text

=
=
=
=
=

- 30

state[8].ToString();
state[10].ToString();
state[12].ToString();
state[14].ToString();
state[16].ToString();

3. S se rezolve n C# problema anterioar folosind cutarea bidirecional.


4. S se scrie programul C# care rezolv problema tabloului cu leduri. Se consider un
tablou cu leduri de dimensiune 3x3 la care prin apasarea unui led acesta i schimb
starea proprie din stins n aprins (i invers) precum i a ledurilor aflate n stnga,
dreapta, sus, jos fa de acesta. n starea iniial toate ledurile sunt stinse iar tabloul
trebuie adus n starea final n care toate ledurile vor fi aprinse. Se va folosi o interfa
apropiat de cea de la problema 2.

Aplicaii cu strategii de cutare neinformate i informate


-

Lucrarea 3
cutare

- 31

Evitarea ciclurilor n algoritmii de

Strile repetate, stri n care agentul deja a mai fost i care conduc la adugarea
n listele de succesori a unor noduri ce conin stri deja explorate, conduc la creterea
inutil a necesitilor de timp i spaiu precum i la arbori de cutare de dimensiune
infinit. De exemplu, datorit strilor repetate, strategia breadth-first anterior
implementat pentru puzzleul 3x3 nu gsete n timp util soluia chiar la adncimi
relativ mici. Mai mult, arborii infinii fac n unele cazuri ca strategia de cutare s nu
mai gseasc niciodat soluia problemei, intrndu-se ntr-o bucl infinit. Chiar dac
strategiile orientate pe cutarea pe nivel evit buclele infinite, i sunt astfel complete
indiferent de situaie, acelai lucru nu se ntmpl n cazul cutrilor n adncime ce
vor fi discutate n capitolul urmtor i care n cazul intrrii ntr-un ciclu nu vor mai
furniza nicicnd o soluie.
Pentru evitarea acestui neajuns exist cteva restricii care pot fi aplicate. n
ordinea cresctoare a eficienei dar i a dificultii implementare i a resurselor
solicitate acestea sunt:
dintr-un nod fiu nu se accept succesori cu aceeai stare cu a nodului printe,
dintr-un nod nu se accept succesori cu aceeai stare cu a unui nod care i-a fost
strmo,
dintr-un nod nu se accept succesori cu stri care au mai fost generate
vreodat.
Desigur, implementarea ultimei metode necesit stocarea tuturor strilor deja
explorate, pentru aceasta, complexitatea de spaiu este cea care induce problemele cele
mai mari, altfel complexitatea de timp este logaritmic datorit posibilitii de a plasa
strile parcurse n liste ordonate i a efectua cutri binare.

3.1

Exerciii

1. Pentru implemetarea strategiei breadth-first pentru puzzleul 3x3 din capitolul


anterior aplicai restriciile pentru evitarea strilor repetate i extragei caracterisiticile
de performan pentru fiecare dintre restricii. Se va folosi o interfa apropiat de cea
din figura 3.1, care afieaz n plus fa de problema anterioar i numrul de stri
explorate.

Aplicaii cu strategii de cutare neinformate i informate


-

- 32

Figura 3.1. Exemplu de interfa

Indicaii pentru rezolvare:


Se folosete o tabel HashTable pentru memorarea strilor care sunt deja
explorate
private Hashtable exploredStates = new Hashtable(); //
tabela care retine starile ce au fost deja explorate

n funcia search, nainte de a explora o stare (a i aduga succesorii) se


verific n tabela HashTable dac strea nu a fost deja explorat
private void Search()
{
SearchTreeNode currentNode = new
SearchTreeNode(null, initialState, 0);
nodesToExplore.Enqueue(currentNode);
do
{
if ( nodesToExplore.Count == 0 )
//verifica daca mai sunt stari de explorat
{
System.Windows.Forms.MessageBox.Show("Nu exista solutie");
break;

Aplicaii cu strategii de cutare neinformate i informate


-

- 33

}
currentNode = (SearchTreeNode)
nodesToExplore.Dequeue();
if ( currentNode.GetState() == finalState)
//verifica daca s-a ajuns la solutie
{
System.Windows.Forms.MessageBox.Show("S-a gasit solutia");
ShowSolution(currentNode);
break;
}
if
(!exploredStates.ContainsKey(currentNode.GetState()))
//verifica daca starea curenta a mai fost explorata
{
AddSuccessors(currentNode); // adauga
succesorii starii curente
exploredStates.Add(currentNode.GetState(), currentNode);
//adauga starea curenta intre starile explorate
}
}while(true);
}
La repornirea cutrii se golete lista de noduri explorate i a celor care
urmeaz a fi explorate
private void startButton_Click(object sender, EventArgs e)
{
nodesToExplore.Clear();
listaSolutie.Items.Clear();
exploredStates.Clear();
InitStates();
Search();
}
3. S se rezolve n C# problema anterioar cu restricii pentru stri repetate i folosind
cutarea bidirecional.
4. S se scrie programul C# care rezolv problema tabloului cu leduri folosind
restriciile pentru evitarea strilor repetate. Se va folosi o interfa apropiat de cea de
la problema 1.

Aplicaii cu strategii de cutare neinformate i informate


-

- 34

Lucrarea 4
Strategii neinformate de cutare:
strategiile de cutare n adncime, adncime
limitat i adncime iterativ
4.1

Strategia de cutarea n adncime (Depth-First)

Strategia de cutarea n adncime, aa cum se va vedea n cele ce urmeaz, este


alternativa pentru a reduce consumul ridicat de memorie de la cutarea pe nivel. n
acest caz nodurile sunt explorate n ordinea adncimii i se revine la nivelul superior
doar cnd cutarea ajunge ntr-un punct mort (dead-end). Acest lucru este sugerat n
figura 4.1 pe un arbore de cutare de adncime 4 i factor de ramificaie 2.

Figura 4.1. Arborele de cutare n cazul strategiei depth-first

Complexitate de timp i spaiu


Este uor de observat c n cazul cel mai dezavantajos din punct de vedere
computaional complexitatea de timp este tot T = O b d . n ceea ce privete spaiul
ns, din cauz c explorarea se face ntotdeauna n adncime acesta ajunge la
S = O(b d ) ceea ce nseamn complexitate liniar i este desigur un avantaj major
comparativ cu complexitatea exponenial de la cutarea pe nivel.

( )

Completitudine i optimalitate

Aplicaii cu strategii de cutare neinformate i informate


-

- 35

Cutarea n adncime nu este complet n arbori infinii, adic atunci cnd apar
cicluri. Altfel, dac se folosete o constrngere pentru evitarea strilor repetate
strategia este complet. Deoarece risc s gseasc soluia aflat la adncimea cea mai
mare, i nu ine cont nici de costuri, strategia nu este optimal.

Implementare
Cutarea n adncime se implementeaz uor folosind o stiv n care sunt
adugate, evident la nceput, nodurile care rezult din explorarea nodului curent i tot
aa. Acest lucru este ilustrat n figura 4.2.
Extrage nod 1

Adauga succesori nod 1 Extrage nod 2

Adauga succesori nod 2 Extrage nod 3

Adauga succesori nod 3

4
3

Pasul 1

Pasul 2

Pasul 3

Pasul 4

Stiva:

Figura 4.2. Evoluia stivei la cutarea depth-first

Avantaje i dezavantaje
Avantajul major al strategiei de cutare n adncime este faptul c necesitile
de memorie sunt minimale, complexitatea de spaiu fiind liniar. Dezavantajul major
este c strategia nu este nici optimal i nici complet.

4.2

Strategia de cutare limitat n adncime (Depth-Limited)

Principalul dezavantaj al strategiei de cutare n adncime este faptul c nu


este complet. Din fericire aceast deficien poate fi nlturat parial prin
introducerea unei limite de adncime l. Astfel, vor fi explorate doar nodurile pna la o
limit l i dac adncimea soluiei este mai mic dect l atunci ea va fi gsit.
Utilizarea strategiei de cutare n adncime este recomandat atunci cnd se cunoate
adncimea unei soluii. De altfel, algoritmul numit BackTracking aa cum fost
prezentat n cadrul unor materii este de fapt o cutare limitat n adancime i motivul
pentru care a funcionat era faptul c se cunotea limita de adncime iar atunci cnd nu
se cunotea adncimea soluiei BackTracking nu se mai putea aplica.

Aplicaii cu strategii de cutare neinformate i informate


-

- 36

Complexitate de timp i spaiu


Complexitatea de timp rmne cea de la cutarea n adncime i anume
T = O b d , la fel i cea de spaiu S = O(bd ) . Deoarece explorarea se face efectiv

( )

( )

pn la limita de adncime l, este mai corect s spunem c T = O bl i S = O(bl ) .

Completitudine i optimalitate
Strategia de cutare limitat n adncime este complet doar dac adncimea
unei soluii este mai mic dect l, i.e. d<l . Rmne necesar i remarca de la breadth
first, anume c arborele trebuie s fie finit, ceea ce presupune i un numr de operatori
finit.
Strategia nu este optimal deoarece este predispus la a gsi nti soluia cea
mai adnc, mai mult nu ine cont nici de poteniale costuri ale operatorilor. Totui este
interesant de observat c exist un caz n care strategia este optimal: atunci cnd toate
soluiile problemei se afl pe limita de adncime. Acesta este cazul multor probleme
rezolvate cu backtracking n liceu sau primul an de facultate: aranjarea a n regine pe
tabla de ah, umplerea unei table de ah de dimensiune nxn prin sritura calului etc.

Implementare
Strategia se implementeaz identic cu strategia de cutare n adncime, doar c
n acest caz se impune i o limit de adncime peste care funcia search nu mai desface
succesori.

Avantaje i dezavantaje
Principalul avantaj este acela c are necesiti de memorie sczute, la fel ca la
cutarea n adncime, n timp ce rmne complet atunci cnd d<l. Dezavantajul este
faptul c nu este optimal.

4.3

Strategia de cutare iterativ n adncime (IterativeDeepening)

Ar fi desigur de dorit s avem o strategie de cutare care este complet i


optimal precum cutarea pe nivel, dar n acelai timp are necesitile de memorie
sczute de la cutarea n adncime. Din fericire acest lucru este posibil folosind
cutarea limitat n adncime cu limite iterate (0,1,2,3,). Aceast strategie mbin
cele mai bune caracteristici de la cutarea n adncime i cutarea pe nivel apelnd

Aplicaii cu strategii de cutare neinformate i informate


-

- 37

succesiv cutarea limitat n adncime cu limite iterate. Astfel, unele noduri vor fi
explorate de mai multe ori aa cum se poate observa i n figura 4.3. n figur, pentru a
nu ncrca desenul s-a omis faptul c primul nod este explorate de 4 ori, pentru cei 4
arbori de cutare generai la adncime 1, 2, 3 respectiv 4.

Complexitate de timp i spaiu

( )

Complexitate de timp rmne T = O b d dar deoarece unele noduri sunt


explorate de mai multe ori, la fiecare iteraie n adncime, complexitatea este de fapt
T = (d + 1) + d b + (d 1) b 2 + ... + b d = O b d . Din aceast cauz, chiar dac din
punct de vedere asimptotic, al indicatorului O, strategia are aceeai complexitate de
timp cu celelalte strategii, n realitate timpul de calcul este mai mare i trebuie s ne
ateptm ca strategia de cutare iterativ n adncime s dea un rspuns ntr-un timp
ceva mai lung dect celelalte.
Complexitatea de spaiu rmne cea de la strategia de cutare n adncime
S = O(b d ) .

( )

Figura 4.3. Arborele de cutare n cazul strategiei iterative-deepening

Completitudine i optimalitate
Strategia este complet n arbori finii la fel ca strategia de cutare pe nivel. De
asemenea este i optimal n aceleai condiii cu strategia de cutare pe nivel: costul
cresctor odat cu adncimea (lucru adevrat n cazul particular al operatorilor cu
costuri egale).

Aplicaii cu strategii de cutare neinformate i informate


Implementare

- 38

Se implemenetaz prin apelarea iterativ a strategiei de cutare limitat n


adncime prin iterarea limitei de adncime l. Structura folosit este deci stiva.

Avantaje i dezavantaje
Avantajul major este faptul c este optimal i complet la fel ca strategia de
cutare pe nivel avnd ns necesiti sczute de memorie la fel ca strategia de cutare
n adncime. n general, n spaii de dimensiune mare este strategia preferat datorit
consumului redus de memorie. Dezavantajul este faptul c fiecare nod este parcurs de
mai multe ori, dar asimptotic vorbind acest lucru devine irelevant.

4.4

Exerciii

1. Exist probleme pentru care cutarea depth-limited este optimal i complet? Dai
3 exemple i o regul general pentru ca depth-limited este optimal i complet.
2. Se considera un puzzle 3x3 si un tablou cu leduri de dimensiune 3x3 la care prin
apsarea unui led acesta i schimba starea proprie din stins n aprins (i invers) precum
i a ledurilor aflate n stanga, dreapta, sus, jos fa de acesta. Se cere: pentru fiecare
dintre strategiile de cautare neinformate cunoscute explorai arborele de cautare pn la
adncimea d=3 precizand ordinea n care nodurile au fost explorate i indicnd
structura utilizat pentru implementare (coad, stiv etc.)
3. S se scrie programul C# care rezolv problema unui puzzle 3x3 folosind strategia
depth-first evitnd strile repetate i folosind o interfa apropiat de cea din figura de
mai jos. Se recomand folosirea codului surs din capitolele anterioare.

Aplicaii cu strategii de cutare neinformate i informate


-

- 39

Figura 4.4. Exemplu de interfa

Indicaii pentru rezolvare:


Coada de la breadth-first n care se rein nodurile ce urmeaz a fi explorate se
transform n cazul lui depth-first n stiv
private Stack nodesToExplore = new Stack(); // stiva care
retine nodurile ce vor fi explorate
n funciile de adugare succesori i de cutare operaiile se vor face cu Push i
Pop n loc de Enqueue i Dequeue
//adaugare succesori ai starii curente in coada (maxim 4
succesori)
private void AddSuccessors(SearchTreeNode
currentNode){
SearchTreeNode left, right, up, down;
int i = 0;
while ((i < 9) &&
(DecodeState(currentNode.GetState())[i] != 0)) i++;
//determina pozitia spatiului liber, se observa ca i div 3
e linia pe care se afla spatiul liber si i mod 3 e coloana
if ( (i / 3) != 0) //nu este pe prim linie
deci se poate muta sus
{
up = new SearchTreeNode( currentNode,

Aplicaii cu strategii de cutare neinformate i informate


-

- 40

EncodeState(GenerateState(DecodeState(currentNode.GetState
()), i, 1, 0, 0, 0)), currentNode.GetDepth() + 1);
nodesToExplore.Push(up);
}
if ((i/3) != 2) //nu este pe linia de jos deci
se poate muta jos
{
down = new SearchTreeNode( currentNode,
EncodeState(GenerateState(DecodeState(currentNode.GetState
()), i, 0, 1, 0, 0)), currentNode.GetDepth() + 1);
nodesToExplore.Push(down);
}
if ((i%3) != 0) //nu este pe coloana din
stanga deci se poate muta stanga
{
left = new SearchTreeNode(currentNode,
EncodeState(GenerateState(DecodeState(currentNode.GetState
()), i, 0, 0, 1, 0)), currentNode.GetDepth() + 1);
nodesToExplore.Push(left);
}
if ((i%3) != 2) //nu este pe coloana din
dreapta deci se poate muta dreapta
{
right = new SearchTreeNode(currentNode,
EncodeState(GenerateState(DecodeState(currentNode.GetState
()), i, 0, 0, 0, 1)), currentNode.GetDepth() + 1);
nodesToExplore.Push(right);
}
}
//functie search (algoritm de cautare)
private void Search()
{
SearchTreeNode currentNode = new
SearchTreeNode(null, initialState, 0);
nodesToExplore.Push(currentNode);
do
{
if ( nodesToExplore.Count == 0 )
//verifica daca mai sunt stari de explorat
{
System.Windows.Forms.MessageBox.Show("Nu exista solutie");
break;

Aplicaii cu strategii de cutare neinformate i informate


-

- 41

}
currentNode = (SearchTreeNode)
nodesToExplore.Pop();
if ( currentNode.GetState() == finalState)
//verifica daca s-a ajuns la solutie
{
System.Windows.Forms.MessageBox.Show("S-a gasit solutia");
ShowSolution(currentNode);
break;
}
if
(!exploredStates.ContainsKey(currentNode.GetState()))
//verifica daca starea curenta a mai fost explorata
{
AddSuccessors(currentNode); // adauga
succesorii starii curente
exploredStates.Add(currentNode.GetState(), currentNode);
//adauga starea curenta intre starile explorate
}
}while(true);
}
La repornirea cutrii trebuie golit acum stiva de nodurile ce urmeaz a fi
explorate
4. S se rezolve problema anterioar folosind cutarea limitat n adncime i cutarea
iterativ n adncime.
5. S se rezolve problema anterioar folosind cutarea bidirecional cu breath-first
dintr-o parte i depth-first din cealalt parte.
6. S se scrie programul C# care rezolv problema tabloului cu leduri folosind
iterative-deepening. Se poate rezolva aceast problem folosind depth-first?

Aplicaii cu strategii de cutare neinformate i informate


-

- 42

Lucrarea 5
Strategii neinformate de cutare:
strategia de cutare cu cost uniform
5.1

Strategia de cutare cu cost uniform (Uniform Cost)

Ceea ce nici una din strategiile de cutare anterior introduse nu putea s


rezolve era optimalitatea pentru cazul n care operatorii nu au costuri egale i deci
costul unor noduri de pe un nivel mai mare (aflat mai jos n arbore) nu este neaprat
mai mare dect costul unor noduri de pe un nivel mai mic. Strategia de cutare cu cost
uniform rezolv eficient aceast problem. Strategia mai este cunoscut i ca Dijkstra's
Single-Source Shortest Path sau simplu algoritmul lui Dijkstra.
Strategia funcionez similar cu strategia de cutare pe nivel doar c de aceast
dat nodurile sunt explorate nu n ordinea nivelelor ci n ordinea costurilor explornduse ntotdeauna nodul cel mai ieftin. n cazul n care costul operatorilor este egal,
strategia de cutare cu cost uniform se comport identic cu strategia de cutare pe
nivel.
Un scurt exemplu poate fi util n lmurirea modului de funcionare al
strategiei. Fie graful orientat aciclic din figura 5.1, se dorete gsirea celui mai scurt
drum de la A la E. Pentru aceasta nodurile sunt explorate n ordinea costurilor, lucru
indicat n figura 5.2 n care se observ c drumul gsit de strategie este A-C-E care este
cel mai ieftin.

Figura 5.1. Graf orientat aciclic

Aplicaii cu strategii de cutare neinformate i informate


-

- 43

Figura 5.2. Arborele de cutare n cazul strategiei cu cost uniform

Extrage nod 1 Adauga succesori nod 1 Extrage nod 2

Lista
ordonata
dupa
cost:

Adauga succesori nod 2 Extrage nod 3

Adauga succesori nod 3

15

15

16

Pasul 1

Pasul 2

Pasul 3

Pasul 4

Figura 5.3. Evoluia listei ordonate dup costuri

Complexitate de timp i spaiu

( )

Complexitatea de timp este T = O b d . O alt valoare frecvent folosit pentru

complexitatea de timp este T = O b

co

cm

unde co este costul cii optime n arbore iar

( )

cm este costul minim al operatorilor. Complexitatea de spaiu este T = O b d .

Completitudine i optimalitate

Aplicaii cu strategii de cutare neinformate i informate


-

- 44

Strategia de cutare cu cost uniform este complet, costul strict cresctor odat
cu adncimea n arbore fcnd ca ciclurile s fie evitate. Strategia este optimal n
funcie de cost cu excepia situaiei cnd apar costuri negative n arbore.

Implementare
Se implementeaz folosind o list sortat cresctor dup costuri.

Avantaje i dezavantaje
Avantajul strategiei este c este complet i optimal chiar i atunci cnd
costul nu este strict cresctor cu nivelul. Dezavantajul ns este c are necesiti de
memorie ridicate, la fel ca n cazul lui breath-first.

5.2

Exerciii

1. Poate fi vzut cutarea breadth-first ca un caz particular de uniform-cost?


2. Complexitatea strategiei uniform-cost este T=O(bd) . Explicai de ce este corect i
relaia T=O(bco/cm) unde c este costul cii optime n arbore iar c este costul minim
al operatorilor.

3. Se consider un puzzle 3x3 i un tablou cu leduri de dimensiune 3x3 la care prin


apasarea unui led acesta i schimb starea proprie din stins n aprins (i invers) precum
i a ledurilor aflate n stnga, dreapta, sus, jos fa de acesta. Pentru ficare dintre
urmtoarele strategii stabilii dac sunt optimale i complete precum i complexitatea
efectiv de timp i spaiu la o adncime a soluiei d=10: a) breadth-first b) depth-first c)
depth-limited d) iterative-deepening e) uniform-cost f) bidirectional search.
4. Se consider un spaiu cu obstacole de dimensiune 100x100 careuri i un agent
inteligent care doreste s ajung din SI(x,y) n SF(x,y). Fiecare careu are asociat o
cot care are asociat o valoare aleatoare i se definete un prag care reprezint
valoarea numeric a cotei maxime peste care agentul poate s treac (orice careu a
crui cot depete acest prag se consider obstacol). Se consider c deplasarea n
linie dreapt are costul 100 iar cea n diagonal are costul 141. S se implementeze
programul C# care rezolv aceast problem. Se va folosi o interfa apropiat de cea
din figura 5.4.

Aplicaii cu strategii de cutare neinformate i informate


-

- 45

Figura 5.4 Exemplu de interfa pentru problema spaiului cu obstacole

Indicaii pentru rezolvare:


Se definete o clas pentru nodul arborelui de cutare
class SearchTreeNode
{
public SearchTreeNode parrent = null;
public int cost;
public int level;
public long id = 0;
public int coordX = 0;
public int coordY = 0;
public int nodeOperator = 0; //degreess from 90 to
360
}

Aplicaii cu strategii de cutare neinformate i informate


-

- 46

Se definesc costurile pentru deplasarea n linie dreapt i n diagonal


// costul miscarii in linie dreapta
private const int straigthMovement = 100;
// costul miscarii in diagonala sqrt(2) =
1.4142135623730950488016887242097
private const int diagonalMovement = 141;

Se definete matricea pentru memorarea hrii i nlimea treptei pentru


obstacole (ulterior aceasta se va citi dintr-un text-box)
// matrice utilizata pentru memorarea hartii 100x100
private int[,] m = new int[100,100];
private int obstacleHeight = 50;

Se definesc listele cu noduri deja explorate respectiv cu noduri ce urmeaz a fi


explorate. Deoarece lista cu noduri ce urmeaz a fi explorate trebuie sortat se
definete i un obiect de tip IComparer
Hashtable ExploredStates;
ArrayList StatesToExplore;
private IComparer myComparer = null;
Clasa care implementeaza IComparer pentru costuri este urmtoarea
class CostComparer : IComparer
{
int IComparer.Compare(Object x, Object y)
{
SearchTreeNode n1 = (SearchTreeNode)x;
SearchTreeNode n2 = (SearchTreeNode)y;
if (n1.cost > n2.cost)
{
return 1;
}
else
{
if (n1.cost < n2.cost)
{
return -1;

Aplicaii cu strategii de cutare neinformate i informate


-

- 47

}
else
{
return 0;
}
}
}
}
Se genereaz aleator harta i se afieaz n PictureBox. Pentru a face problema
mai interesant harta a fost generat aleator cu cote care evolueaz de la
centrul spre marginea hrii astfel nct n centru s fie densitate de obstacole
mai mare (pentru simplitate se poate renuna la acest lucru).
// harta este generata aleator cu obstacole a caror
densitate creste spre centrul hartii
private void GenerateMap()
{
int i,j;
Random r = new Random();
for (i = 0; i < 100; i++)
{
for (j = 0; j < 100; j++)
{
if ((Math.Pow(i - 50, 2) + Math.Pow(j
- 50, 2)) < Math.Pow(10, 2))
{
m[i, j] = r.Next(128);
}
else
{
if ((Math.Pow(i - 50, 2) +
Math.Pow(j - 50, 2)) < Math.Pow(20, 2))
{
m[i, j] = r.Next(100);
}
else
{
if ((Math.Pow(i - 50, 2) +
Math.Pow(j - 50, 2)) < Math.Pow(30, 2))
{
m[i, j] = r.Next(80);
}

Aplicaii cu strategii de cutare neinformate i informate


-

- 48

else
{
m[i, j] = r.Next(40);
}
}
}
}
}
}
// harta din matrice este desenata in PictureBox
private void DisplayMapOnPictureBox()
{
Bitmap bmp = new Bitmap(100, 100);
int i, j;
Color col = Color.Green;
for (i = 0; i < 100; i++)
{
for (j = 0; j < 100; j++)
{
bmp.SetPixel(i, j,
Color.FromArgb(col.R , col.G - m[i, j], col.B));
}
}
pictureBoxMap.Image = bmp;
pictureBoxMap.SizeMode =
PictureBoxSizeMode.StretchImage;
}
Funcia search cu evitarea strilor repetate
//algoritmul de cautare (functia Search)
private void Search(SearchTreeNode startNode,
SearchTreeNode targetNode)
{
bool solutionFound = false;
SearchTreeNode currentNode;
StatesToExplore.Add(startNode);
// cautarea continua pana cand se gaseste o
solutie
while (solutionFound == false)
{
if (StatesToExplore.Count == 0)

Aplicaii cu strategii de cutare neinformate i informate


-

- 49

{
// daca lista e goala nu mai sunt
succesori si deci nu exista solutie
System.Windows.Forms.MessageBox.Show("Nu exista solutie");
break;
}
currentNode =
GetNextSuccessor(StatesToExplore);
if (Solution(currentNode, targetNode))
{
System.Windows.Forms.MessageBox.Show("Solutie Gasita" );
ShowSolution(currentNode);
solutionFound = true;
}
else
{
// verifica daca nodul current nu a
fost deja explorat
if
(!(ExploredStates.ContainsKey(currentNode.id)))
{
AddSuccessors(currentNode,
StatesToExplore, targetNode);
ExploredStates.Add(currentNode.id,
currentNode);
}
}
}
}
Crearea, adugarea i extragerea succesorilor. Pentru o mai bun vizualizare a
micrilor au fost codificate dup unghiul la care se face micarea 0, 45, 90
etc.
// se adauga succesorii nodului curent in lista dupa cele
8 directii de miscare
private void AddSuccessors(SearchTreeNode node,
ArrayList StatesToExplore, SearchTreeNode target)
{
int i, newX, newY;
SearchTreeNode n;
int cost = 0;

Aplicaii cu strategii de cutare neinformate i informate


-

- 50

for (i = 0; i < 8; i++)


{
newX = -1; newY = -1;
switch ( i*45 )
{
case 0: newX = node.coordX; newY =
node.coordY + 1; cost = straigthMovement; break;
case 45: newX = node.coordX + 1; newY
= node.coordY + 1; cost = diagonalMovement; break;
case 90: newX = node.coordX + 1; newY
= node.coordY; cost = straigthMovement; break;
case 135: newX = node.coordX + 1; newY
= node.coordY - 1; cost = diagonalMovement; break;
case 180: newX = node.coordX; newY =
node.coordY - 1; cost = straigthMovement; break;
case 225: newX = node.coordX - 1; newY
= node.coordY - 1; cost = diagonalMovement; break;
case 270: newX = node.coordX - 1; newY
= node.coordY; cost = straigthMovement; break;
case 315: newX = node.coordX - 1; newY
= node.coordY + 1; cost = diagonalMovement; break;
}
// creeaza succesorul doar daca nodul nu
este in afara hartii si nivelul este mai mic decat nivelul
obstacolului
if (CoordinatesInsideBounds(newX, newY))
{
if (m[newX, newY] < obstacleHeight)
{
n = new SearchTreeNode();
n.parrent = node;
n.Accessible = true;
n.nodeOperator = i * 45;
n.coordX = newX;
n.coordY = newY;
n.id = n.coordX + n.coordY * 10000;
n.level = node.level + 1;
n.heuristic = DiagonalDistance(n,
target);
n.cost = node.cost + cost;
node.succesors[i] = n;
StatesToExplore.Add(n);
}
}

Aplicaii cu strategii de cutare neinformate i informate


-

- 51

}
StatesToExplore.Sort(myComparer);
}
// verifica daca coordonatele sunt in interiorul
hartii
private bool CoordinatesInsideBounds(int x, int y)
{
if ((x >= 0) && (x < 100) && (y >= 0) && (y <
100))
{
return true;
}
else
{
return false;
}
}
// returneaza urmatorul succesor, adica starea cea
mai apropiata de starea finala
private SearchTreeNode GetNextSuccessor(ArrayList
StatesToExplore)
{
SearchTreeNode state =
(SearchTreeNode)StatesToExplore[0];
StatesToExplore.RemoveAt(0);
return state;
}
Afiarea soluiei i testarea dac un anume nod conine sau nu starea final.
private void ShowSolution(SearchTreeNode position)
{
Bitmap bmp = new Bitmap(pictureBoxMap.Image);
SearchTreeNode n = position;
while (n != null)
{
bmp.SetPixel(n.coordX, n.coordY,
Color.Red);
n = n.parrent;
}
pictureBoxMap.Image = bmp;
pictureBoxMap.SizeMode =

Aplicaii cu strategii de cutare neinformate i informate


-

- 52

PictureBoxSizeMode.StretchImage;
labelNoduri.Text = "Noduri explorate: " +
ExploredStates.Count.ToString();
labelDimensiune.Text = "Dimensiune lista: " +
StatesToExplore.Count.ToString();
labelCost.Text = "Costul soltiei: " +
position.cost.ToString();
}
// verifica daca nodul curent este chiar nodul
tinta
private bool Solution(SearchTreeNode node,
SearchTreeNode targetnode)
{
if ((node.coordX == targetnode.coordX) &&
(node.coordY == targetnode.coordY))
{
return true;
}
else
{
return false;
}
}
Funcia care calculeaz distana diagonal.
// calculeaza distanta diagonala intre doua puncte
private int DiagonalDistance(SearchTreeNode
current, SearchTreeNode target)
{
int xd = Math.Abs(current.coordX target.coordX);
int yd = Math.Abs(current.coordY target.coordY);
return straigthMovement * (Math.Max(xd, yd) Math.Min(xd, yd)) + diagonalMovement * Math.Min(xd, yd);
}

Funciile asociate diverselor evenimente.


private void Form1_Load(object sender, EventArgs e)
{

Aplicaii cu strategii de cutare neinformate i informate


-

- 53

GenerateMap();
DisplayMapOnPictureBox();
}
private void buttonGenerateMap_Click(object
sender, EventArgs e)
{
GenerateMap();
DisplayMapOnPictureBox();
}
private void buttonCostUniform_Click(object
sender, EventArgs e)
{
SearchTreeNode x = new SearchTreeNode();
SearchTreeNode y = new SearchTreeNode();
y.coordX =
Convert.ToInt32(textBoxFinalStateX.Text);
y.coordY =
Convert.ToInt32(textBoxFinalStateY.Text);
y.heuristic = 0;
y.id = y.coordX + 10000 * y.coordY;
x.coordX =
Convert.ToInt32(textBoxInitialStateX.Text);
x.coordY =
Convert.ToInt32(textBoxInitialStateY.Text);
x.heuristic = DiagonalDistance(x, y);
x.id = x.coordX + 10000 * x.coordY;
x.level = 0;
x.parrent = null;
x.cost = 0;
m[x.coordX, x.coordY] = 0;
m[y.coordX, y.coordY] = 0;
ExploredStates = new Hashtable();
StatesToExplore = new ArrayList();
myComparer = new CostComparer();
Search(x, y);
}
5. Se va scrie programul pentru rezolvarea aceleiai probleme de la punctul anterior
dar de aceast dat fiecare cot reprezint costul de acces al careului n cauz (se
renun deci la costul deplasrii n linie dreapt i n diagonal).

Aplicaii cu strategii de cutare neinformate i informate


-

- 54

Lucrarea 6
Strategii informate de cutare:
strategiile de cutare best first i greedy
6.1

Ce este o euristic

Conform dicionarului explicativ al limbii romne euristic,-,euristici cu


referire la procedee i metodologie nseamn ceva care servete la descoperirea unor
cunotinte noi. n ceea ce privete strategiile de cutare, euristica este o informaie care
ajut la luarea unei decizii cu privre la noul nod ce urmeaz a fi explorat, informaie
care ar trebui s conduc mai repede la atingerea strii finale. Russell i Norvig spun n
lucrarea lor de referin information about the state space can prevent algorithms
from blundering about in the dark. Acesta este rolul eurisiticilor, de a preveni ca o
strategie s caute n ntuneric ncercnd s deschid o cale mai bun, mai scurt,
ctre starea final. Strategiile euristice de cutare se mai numesc i strategii informate
de cutare.
Euristica este valoarea estimat a distanei de la starea curent la starea final,
iar funcia care evalueaz acest lucru o notm n general cu h, i.e.
h(n) = costul estimat al celei mai ieftine ci de la nodul dat la nodul soluie
Deci euristica este o funcie care se aplic unui nod dintr-un arbore de cutare,
mai exact strii asociate lui, i se folosete la ordonarea nodurilor n lista de noduri ce
urmeaz a fi explorate. Astfel, lista este ordonat dup euristic n cazul cutrii
Greedy respectiv dup cost plus euristic n cutarea cazul A*, aa cum se va vedea n
cele ce urmeaz.
Pentru ilustrarea mai clar a conceptului de euristic iat cteva exemple de
euristici:
Pentru explorarea unei hrti funcia h(n) poate fi distana n linie dreapt de la
punctul current la punctul final (numit i Straight Line Distance Heuristic
hSLD).
Pentru umplerea unui rucsac cu obiecte: h(n) poate fi spaiul liber care rmne
n rucsac (sau invers volumul/greutatea obiectului ales).
Pentru un puzzle h(n) poate fi numrul de piese aflate n pozitii greite sau
suma distanelor pieselor pn la poziia lor final, sum evaluat ca suma
distanelor Manhattan a fiecrei piese pn la poziia ei final (distana
Manhattan se mai numete i city block distance i este distana n linie
dreapt fr a merge n diagonal).

Aplicaii cu strategii de cutare neinformate i informate


-

1 2 3
4 5 6
7 8
Stare Finala

- 55

3 2 1
4 5 6
8 7
Stare Curenta

Numarul de piese care nu sunt la locul lor: 1+0+1+0+0+0+1+0+1=4


Suma distantelor Manhattan: 2+0+2+0+0+0+2+0+2=8
Figura 6.1 Stare a unui puzzle 3x3 cu valorile celor dou euristici

Se face relevant urmtoarea observaie. Cutarea cu cost uniform utilizeaz o


informaie pe baza creia se decide care este nodul cel mai bun dar atenie aceasta nu
este o cutare euristic deoarece aceast msur este un simplu cost care faciliteaz
gsirea soluiei optimale ca i cost dar nu mpinge strategia spre starea final. Este
extrem de relevant s putem distinge ntre ce nseamn un cost i ce nseamn o
euristic, dac un cost ajut strategia la a gsi soluia de cost optim euristica aduce
avantaje n necesitile de timp i necesitile de spaiu.

6.2

Strategia de cutare Best First

Strategia Best-First este un simplu model teoretic i idealizat de strategie de


cutare euristic. Aceasta presupune explorarea nodului i alegerea ca successor a celui
mai bun nod. Sigur acest lucru este imposibil de realizat n general pentru c este
necesar o funcie care evalueaz care este nodul cel mai bun, iar dac o astfel de
funcie ar exista nici nu mai am avea nevoie de un arbore de cutare pentru c strategia
de cutare ar merge direct ctre soluie avnd complexitate de timp i spaiu liniar.
Deci noiunea de cutare best-first rmne doar ca model idealizat al strategiilor
euristice.

6.3

Strategia de cutare Greedy

Aplicaii cu strategii de cutare neinformate i informate


-

- 56

Strategia greedy alege spre explorare ntotdeauna nodul care este cel mai
apropiat de starea final, deci cel cu cea mai bun euristic. n acest sens se poate face
o analogie cu strategia cu cost uniform care alegea ntotdeauna nodul cu costul cel mai
bun. Dac strategia de cutare cu cost uniform pstra o list sortat dup valoarea
costului, Greedy va pstra o list sortat dup valoarea euristicii.

Complexitate de timp i spaiu

( )

Complexitatea de timp a strategiei Greedy este tot T = O b d

( )

n cel mai

defavorabil caz. La fel i complexitatea de spaiu S = O b d . n practic ns, de cele


mai multe ori nu ne confruntm cu cazuri defavorabile pentru Greedy i timpul de
calcul respectiv spaiul sunt mult mai mici.

Completitudine i optimalitate
Strategia greedy nu este complet n arbori infinii, ciclurile conducnd evident
la blocaje. Dac se folosesc mecanisme de evitare a ciclurilor, strategia este complet.
Totodat, strategia nu este nici optimal deoarece nu ine cont de costuri.

Implementare
Greedy se implementeaza identic cu strategia cu cost uniform, doar c nodurile
sunt pstrate n list ordonate dup euristic i nu dup cost. Se poate ns implementa
i pe paradigma de la cutarea n adncime, folosindu-se o stiv i pstrndu-se un
consum mai mic memorie dar conducnd mai ncet spre soluie.

Avantaje i dezavantaje
Avantajul major este c strategia greedy ofer rapid soluii i n practic greedy
se dovedete a fi o alegere foarte bun atunci cnd nu se dorete gsirea unei soluii
optimale. Dezavantajul este c strategia nu este complet i nici optimal, deasemenea
cnd se implementeaz identic cu uniform-cost poate conduce la necesiti de memorie
ridicate.

6.4

Exerciii

1. S se scrie programul pentru problema puzzleului 3x3 din capitolele anterioare


folosind strategia informat Greedy. Se va rezolva pentru ambele euristici anterior
introduse i se vor compara rezultatele obinute: adncime soluie, numr de noduri
explorate etc.

Aplicaii cu strategii de cutare neinformate i informate


-

- 57

2. Se consider spaiul cu obstacole din capitolul anterior. S se scrie programul care


rezolv aceast problem folosind strategia Greedy. Se va folosi interfaa din figura
6.2.

Figura 6.2 Exemplu de interfa pentru problema spaiului cu obstacole

Inidicaii pentru rezolvare


n clasa pentru nodul arborelui de cutare se adaug euristica
class SearchTreeNode
{
public SearchTreeNode parrent = null;
public int cost;
public int heuristic;
public int level;
public long id = 0;
public int coordX = 0;
public int coordY = 0;

Aplicaii cu strategii de cutare neinformate i informate


-

- 58

public int nodeOperator = 0; //degreess from 90 to


360
}

Se folosete un IComparer pe baz de euristic


class HeuristicComparer : IComparer
{
int IComparer.Compare(Object x, Object y)
{
SearchTreeNode n1 = (SearchTreeNode) x ;
SearchTreeNode n2 = (SearchTreeNode) y ;
if (n1.heuristic > n2.heuristic)
{
return 1;
}
else
{
if (n1.heuristic < n2.heuristic)
{
return -1;
}
else
{
return 0;
}
}
}
Restul programului este identic cu cel din lucrarea anterioar, doar sortarea se
va face dup euristic aa cum rezult din urmtorul cod surs
private void buttonGreedy_Click(object sender, EventArgs
e)
{
SearchTreeNode x = new SearchTreeNode();
SearchTreeNode y = new SearchTreeNode();
y.coordX =
Convert.ToInt32(textBoxFinalStateX.Text);
y.coordY =
Convert.ToInt32(textBoxFinalStateY.Text);

Aplicaii cu strategii de cutare neinformate i informate


-

- 59

y.heuristic = 0;
y.id = y.coordX + 10000 * y.coordY;
x.coordX =
Convert.ToInt32(textBoxInitialStateX.Text);
x.coordY =
Convert.ToInt32(textBoxInitialStateY.Text);
x.heuristic = DiagonalDistance(x, y);
x.id = x.coordX + 10000 * x.coordY;
x.level = 0;
x.parrent = null;
x.cost = 0;
m[x.coordX, x.coordY] = 0;
m[y.coordX, y.coordY] = 0;
ExploredStates = new Hashtable();
StatesToExplore = new ArrayList();
myComparer = new HeuristicComparer();
Search(x, y);
}
3. Se va scrie programul pentru rezolvarea aceleiai probleme de la punctul anterior dar
de aceast dat fiecare cot reprezint costul de acces al careului n cauz (se renun
deci la costul deplasrii n linie dreapt i n diagonal).

Aplicaii cu strategii de cutare neinformate i informate


-

Lucrarea 7

- 60

Alegerea unei euristici

Pentru problemele discutate n acest material, dar i pentru multe alte probleme
din practic, este uor s inventm euristici. Nu n utimul rnd exist i programe
dedicate pentru aceasta. Problema care se pune acum este de a decide din mai multe
euristici care este mai bun. Astfel, dac pentru dou euristici h1, h2 avem h1(n)>h2(n)
atunci spunem c h1 domin pe h2 i utilizarea euristicii dominatoare duce ntotdeauna
la un rezultat mai bun, adic vor fi explorate mai puine noduri pentru a gsi soluia. La
modul general, dac se cunosc mai multe euristici monotone h1,h2,,hm i nu se tie
care euristic domin se poate utiliza h(n)=max(h1,h2,,hm ).

7.1

Probleme cu constrngeri

O gam aparte de probleme decizionale sunt problemele cu constrngeri, n


care un set de variabile care pot lua diverse valori trebuie s satisfac anumite
constrngeri pentru ca starea final s fie atins. ntre cele mai cunoscute probleme cu
constrngeri, studiate n liceu sau n primii ani de facultate, sunt: aezarea a 8 regine pe
o tabl de ah, colorarea unei hri etc. n acest caz sunt n general preferate
urmatoarele trei euristici:
Euristica celei mai constrnse variabile variabila care poate lua cele mai
puine valori este aleas.
Euristica variabilei cu cea mai mare putere de constrngere variabila care
constrnge cele mai multe variabile este aleas.
Euristica valorii cu cea mai mic putere de constrngere valoarea care ofer
cea mai mare libertate n alegerile ulterioare este aleas.
Pentru evitarea strilor fr rezolvare se folosete mecanismul numit forwardchecking. De exemplu: la problema aezrii celor 8 regine, se ncearc aezarea unei
noi regine doar pe poziiile pe care nu este deja atacat.

7.2

Rolul unei euristici

Rolul unei euristici este de a aduce factorul efectiv de ramificaie ctre 1


deoarece n acest caz indiferent de adncimea soluiei necesitile de timp i spaiu nu
vor nregistra o cretere exponenial. Sigur, pentru marea parte a problemelor o
euristic care s realizeze acest lucru nu se poate gsi, dar se poate constata c
euristicile reuesc n general s reduc semnificativ factorul de ramificaie. Pentru
evaluarea eficienei unei euristici se poate calcula factorul efectiv de ramificaie aa
cum a fost el definit n capitolul 2.

Aplicaii cu strategii de cutare neinformate i informate


7.3 Exerciii

- 61

1. Scriei programul pentru rezolvarea problemei aranjrii a 8 regine pe tabla de ah


folosind diverse constrngeri i comparai rezultatele obinute.
2. Scriei programul pentru rezolvarea problemei colorrii unei hri folosind diverse
constrngeri i comparai rezultatele obinute.
3. Scriei programul pentru rezolvarea problemei unui puzzle 3x3 cu cele dou euristici
din seciunea anterioar i comparai rezultatele obinute. Care dintre cele dou
euristici este cea dominatoare.

Aplicaii cu strategii de cutare neinformate i informate


-

- 62

Lucrarea 8
Strategii informate de cutare:
strategia de cutare A*
Strategia A* poate fi vzut ca o combinaie ntre strategia de cutare greedy i
strategia de cutare cu cost uniform, A* combinnd cele mai bune caracteristici ale
acestora. Pentru aceasta A* utilizeaz funcia de evaluare a nodului: f(n)=g(n)+h(n)
unde g(n) este costul de la starea iniial la starea curent (funcia de la cutarea cu cost
uniform) iar h(n) este costul celui ieftin drum de la starea curent la starea final
(euristica de la cutarea Greedy).

Complexitate de timp i spaiu


Complexitatea de spaiu n cel mai ru caz este exponenial i la A* dac nu
este respectat condiia: |h(n)-h*(n)|<O(lg(h*(n))) (h*(n) este costul real pn la
starea final). Totui pentru marea parte a situailor practice A* solicit resurse mai
mici dect ceilali algoritmi de complexitate exponenial.

Completitudine i optimalitate
A* este complet i este optimal cu condiia ca euristica h(n) s fie
admisibil. O euristic se numete admisibil dac nu supraestimeaz costul atingerii
strii finale plecnd din starea curent. Eurisiticile admisibile se mai numesc i euristici
optimiste deoarece ntodeauna estimeaz c este mai uor de a ajunge la final dect este
n realitate. n baza discuiei din capitolul anterior se poate utiliza h(n)=max(h1,h2,,hm
) iar dac fiecare din euristicile hi este admisibil atunci i h(n) este adimisibil.

Implementare

A* se implementeaz folosind o list sortat cresctor dup funcia f.


Avantaje i dezavantaje
A* este cea mai bun strategie de cutare, se poate demostra chiar c este
optimal-eficient, adic orice alt strategie care exploreaz mai puine noduri dect A*
risc s nu gseasc cea mai bun soluie. Dezavantajul este c necesit resurse de
memorie relative ridicate. Pentru a nltura acest dezavantaj o potenial soluie este
combinarea lui A* cu Iterative Deepening combinaie cunoscut sub numele de
Iterative Deepening A* sau IDA*.

Aplicaii cu strategii de cutare neinformate i informate


8.1 Demonstraie asupra optimalitii lui A*

- 63

Este evident c A* este complet, costul uniform conducnd inevitabil la


explorarea nodurilor pn la gsirea unei soluii. Pentru a demonstra c A* este
optimal recurgem la reducere la absurd i presupunem c A* nu este optimal. Fie n
acest caz co costul optim al cii ctre soluie i fie x o stare final sub-optimal
returnat de A*, avem deci:
g(x) > co

(1)

Fie un nod n care aparine cii optimale, deoarece h este o euristica admisibil:
co >=f(n)

(2)

Deoarece A* nu a deschis starea n avem:


f(n)>=f(x)

(3)

Din (2) si (3) rezult


co >=f(x)

(4)

Dar din moment ce x este starea final avem:


h(x) = 0

(5)

Acum din (4) i (5) rezult:


co >=g(x)

(6)

i deci x nu poate fi suboptimal deoarece costul su este mai mic sau egal cu
costul optimal, ceea ce este o contradicie cu ipoteza (1) i deci A* este optimal.

8.2

Exerciii

1. Se consider harta din figur i distanele n linie dreapt (hSLD) din tabel. Se cere:

Aplicaii cu strategii de cutare neinformate i informate


-

- 64

Figura 8.1 Hart oarecare.

Oras
Timisora
Recas
Lugoj
Buzias
Farliug
Bocsa
Sag
Voiteg
Deta

hSLD (Resita)
100
90
30
65
30
10
95
40
70

Figura 8.2 Euristica distanei n linie dreapt pentru punctele de pe hart.

a) explicai cutarea greedy i ilustrai ordinea n care nodurile sunt explorate


pentru gsirea unui drum Timioara-Reita

Aplicaii cu strategii de cutare neinformate i informate


-

- 65

Figura 8.3 Arborele de cutare pentru strategia Greedy

b) Explicai cutarea A* i ilustrai ordinea n care nodurile sunt explorate pentru


gsirea unui drum Timioara-Reia

Figura 8.4 Arborele de cutare pentru strategia A*

Aplicaii cu strategii de cutare neinformate i informate


-

- 66

c) Care dintre cele dou cutri a ajuns mai rapid la solutie i care a gsit soluia
optimal? Observai c arborele de cutare are aceeai adncime pentru ambele
strategii, ns doar A* a gsit soluia optimal (Greedy a parcurs 115km iar A*
94km)
2. Se consider spaiul cu obstacole din capitolul anterior. S se scrie programul care
rezolv aceast problem folosind strategia A*. Se va folosi interfaa din figura 8.5.

Figura 8.5 Exemplu de interfa pentru problema spaiului cu obstacole

private void buttonAstar_Click(object sender,


EventArgs e)
{
SearchTreeNode x = new SearchTreeNode();
SearchTreeNode y = new SearchTreeNode();
y.coordX =
Convert.ToInt32(textBoxFinalStateX.Text);

Aplicaii cu strategii de cutare neinformate i informate


-

- 67

y.coordY =
Convert.ToInt32(textBoxFinalStateY.Text);
y.heuristic = 0;
y.id = y.coordX + 10000 * y.coordY;
x.coordX =
Convert.ToInt32(textBoxInitialStateX.Text);
x.coordY =
Convert.ToInt32(textBoxInitialStateY.Text);
x.heuristic = DiagonalDistance(x, y);
x.id = x.coordX + 10000 * x.coordY;
x.level = 0;
x.parrent = null;
x.cost = 0;
m[x.coordX, x.coordY] = 0;
m[y.coordX, y.coordY] = 0;
ExploredStates = new Hashtable();
StatesToExplore = new ArrayList();
myComparer = new CostPlusHeuristicComparer();
Search(x, y);
}

3. Se va scrie programul pentru rezolvarea aceleiai probleme de la punctul anterior dar


de aceast dat fiecare cot reprezint costul de acces al careului n cauz (se renun
deci la costul deplasrii n linie dreapt i n diagonal). Se mai poate folosi euristica
distanei diagonale n acest caz? Explicai implicaiile, propunei o alt euristic.
4. Acelai program de la punctele 3 i 4 dar care deseneaz cu culori diferite traseele
urmate de Uniform-cost, Greedy, A* i afieaz casete comparative cu parametrii
fiecrei strategii (costul drumului, timp, memorie etc.).

Aplicaii cu strategii de cutare neinformate i informate


-

- 68

Lucrarea 9
Strategii de cutare n spaii cu
incertitudini
Un caz aparte sunt scenariile cu incertitudini, n acest caz agentul inteligent nu
este omniscient cu privire la spaiul strilor. De exemplu n cadrul problemei gsirii
drumului optim pe o hart, harta era generat anterior i cunoscut de ctre agent. Dar,
putem la fel de bine trata i cazul n care agentul nu cunoate harta i trebuie s o
descopere singur. Un astfel de scenariu nu este simplu de tratat din punct de vedere al
optimalitii i completitudinii, din fericire putem construi o soluie relativ eficient
bazat pe noiunile introduse pn acum. n cele ce urmeaz vom trece direct la
rezolvarea problemei gsirii drumului pe harta 100x100 din capitolele anterioare la
care adugm faptul c harta nu este cunoscut n prealabil i agentul trebuie s o
descopere. Recurgem la simplificarea n baza creia punctele de pe hart au valori
binare 1 sau 0 dup cum sunt accesibile sau nu. Se va folosi o interfa apropiat de cea
din figura 9.1. Sintetizm indicaiile pentru rezolvare dup cum urmeaz:

Figura 9.1 Drumul gsit de agentul inteligent folosind strategia de cutare adaptiv

Aplicaii cu strategii de cutare neinformate i informate


-

- 69

Se definesc costurile deplasrii i se genereaz harta ntr-o manier similar cu


cea din capitolele aterioare
private const int straigthMovement = 100; // costul
miscarii in linie dreapta
private const int diagonalMovement = 141; //
costul miscarii in diagonala sqrt(2) =
1.4142135623730950488016887242097
private int[,] m = new int[100,100]; // matrice
utilizata pentru memorarea hartii 100x100
// harta este generata aleator cu obstacole a
caror densitate creste spre centrul hartii
private void GenerateMap()
{
int i,j;
int treshold;
Random r = new Random();
for (i = 0; i < 100; i++)
{
for (j = 0; j < 100; j++)
{
if ((Math.Pow(i - 50, 2) + Math.Pow(j
- 50, 2)) < Math.Pow(10, 2))
{
treshold = 4;
}
else
{
if ((Math.Pow(i - 50, 2) +
Math.Pow(j - 50, 2)) < Math.Pow(20, 2))
{
treshold = 6;
}
else
{
if ((Math.Pow(i - 50, 2) +
Math.Pow(j - 50, 2)) < Math.Pow(30, 2))
{
treshold = 8;
}
else

Aplicaii cu strategii de cutare neinformate i informate


-

- 70

{
treshold = 9;
}
}
}
if (r.Next(10) < treshold)
{
m[i, j] = 0;
}
else
{
m[i, j] = 1;
}
}
}
}
// harta din matrice este desenata in PictureBox
private void DisplayMapOnPictureBox()
{
Bitmap bmp = new Bitmap(100, 100);
int i, j;
for (i = 0; i < 100; i++)
{
for (j = 0; j < 100; j++)
{
if (m[i , j ] == 0)
{
bmp.SetPixel(i, j, Color.White);
}
if (m[i , j ] == 1)
{
bmp.SetPixel(i, j, Color.Black);
}
}
}
pictureBoxMap.Image = bmp;
pictureBoxMap.SizeMode =
PictureBoxSizeMode.StretchImage;
}

n funcia search are loc urmtoarea modificare, deoarece nu este sigur c


agentul va putea fi mutat n succesorul generat de funcie (ar putea fi un

Aplicaii cu strategii de cutare neinformate i informate


-

- 71

obstacol)
se
apeleaz
roboPosition
=
MoveBetweenTreeNodes(roboPosition, currentNode). Dup
acest apel, ctre funcia care ncearc s pun agentul n succesor, dac poziia
este egal cu nodul succesor atunci nseamn c succesorul a fost accesibil i
deci nu era un obstacol.
//algoritmul de cautare (functia Search)
private void PathFind(SearchTreeNode startNode,
SearchTreeNode targetNode)
{
int movements = 0;
Hashtable ExploredStates = new Hashtable();
ArrayList StatesToExplore = new ArrayList();
bool solutionFound = false;
SearchTreeNode currentNode;
SearchTreeNode roboPosition;
SearchTreeNode rootNode;
roboPosition = startNode;
rootNode = startNode;
StatesToExplore.Add(rootNode);
// search continues until a solution is found
or no states to explore axists
while ((StatesToExplore.Count != 0) &&
(solutionFound != true))
{
currentNode =
GetNextSuccessor(StatesToExplore);

if
(!(ExploredStates.ContainsKey(currentNode.id))) // current
node was not explored
{
// inca nu se stie daca pozitia
din nodul curent este sau nu accesibila
// se incearca mutarea robotului
din pozitia curenta in pozitia din nodul curent
roboPosition =
MoveBetweenTreeNodes(roboPosition, currentNode);
// se marcheaza pe harta noua
pozitie a robotului
Bitmap bmp = new
Bitmap(pictureBoxMap.Image);

Aplicaii cu strategii de cutare neinformate i informate


-

- 72

bmp.SetPixel(roboPosition.coordX, roboPosition.coordY,
Color.Blue); pictureBoxMap.Image = bmp;
// se verifica daca pozitia
robotului este identica cu pozitia din nodul curent
if (roboPosition.id ==
currentNode.id)
{
// daca da se adauga
succesorii nodului curent in lista
AddSuccessors(currentNode,
StatesToExplore, targetNode);
ExploredStates.Add(currentNode.id, currentNode);
}
// daca nu, pozitia din nodul
curent nu este accesibila
else
{
currentNode.Accessible =
false;
}
}
// se verifica daca pozitia curenta este
chiar solutia
if (Solution(roboPosition, targetNode))
{
System.Windows.Forms.MessageBox.Show("Target Reached" +
movements.ToString());
solutionFound = true;
}
}
if (solutionFound == false) {
System.Windows.Forms.MessageBox.Show("There is no
solution"); }
}

Funciile de adugare a succesorilor, extragere a noului nod de explorat i de


verificare a coordonatelor sunt similare cu cele din capitolele anterioare.
// se adauga succesorii nodului curent in lista
// atentie, nu toti succesori sunt accesibili,
putand fi si obstacole, lucru care se va afla cand robotul

Aplicaii cu strategii de cutare neinformate i informate


-

- 73

incearca sa miste in acel nod


// dupa ce au fost adaugati, lista de succesori
este sortata
private void AddSuccessors(SearchTreeNode node,
ArrayList StatesToExplore, SearchTreeNode target)
{
int i, newX, newY;
SearchTreeNode n;
for (i = 0; i < 8; i++)
{
newX = -1; newY = -1;
switch ( i*45 )
{
case 0: newX = node.coordX; newY =
node.coordY + 1; break;
case 45: newX = node.coordX + 1; newY
= node.coordY + 1; break;
case 90: newX = node.coordX + 1; newY
= node.coordY; break;
case 135: newX = node.coordX + 1; newY
= node.coordY - 1; break;
case 180: newX = node.coordX; newY =
node.coordY - 1; break;
case 225: newX = node.coordX - 1; newY
= node.coordY - 1; break;
case 270: newX = node.coordX - 1; newY
= node.coordY; break;
case 315: newX = node.coordX - 1; newY
= node.coordY + 1; break;
}
if (CoordinatesInsideBounds(newX, newY))
{
n = new SearchTreeNode();
n.parrent = node;
n.Accessible = true;
n.nodeOperator = i * 45;
n.coordX = newX;
n.coordY = newY;
n.id = n.coordX + n.coordY * 10000;
n.level = node.level + 1;
n.heuristic = DiagonalDistance(n,
target);
node.succesors[i] = n;
StatesToExplore.Add(n);

Aplicaii cu strategii de cutare neinformate i informate


-

- 74

}
}
IComparer myComparer = new
HeuristicComparer();
StatesToExplore.Sort(myComparer);
}
// verifica daca coordonatele sunt in interiorul
hartii
private bool CoordinatesInsideBounds(int x, int y)
{
if ((x >= 0) && (x < 100) && (y >= 0) && (y <
100))
{
return true;
}
else
{
return false;
}
}
// returneaza urmatorul succesor, adica starea cea
mai apropiata de starea finala
private SearchTreeNode GetNextSuccessor(ArrayList
StatesToExplore)
{
SearchTreeNode state =
(SearchTreeNode)StatesToExplore[0];
StatesToExplore.RemoveAt(0);
return state;
}
Avem nevoie acum de cteva funcii care nu au mai fost ntlnite n cazul
implementrilor anterioare, este vorba de funciile care ncearc mutarea
robotului ntre nodurile arborelui de cutare. Se disting aici dou cazuri
distincte: cazul n care se ncearc mutarea dintr-un nod fiu ntr-un nod printe
sau ntr-un nod care nu este terminal respectiv cazul n care se ncearc
mutarea ntr-un nod terminal. n primul caz drumul este accesibil iar n cel deal doilea caz trebuie verificat dac mutarea poate fi fcut. Funciile
MoveRobotFromChildToParrentNode,
MoveRobotFromParrentToChildNode adreseaz primul caz iar funcia
MoveRobotFromParrentToChildNodeIfPossible adreseaz cel de-

Aplicaii cu strategii de cutare neinformate i informate


-

- 75

al doilea caz. Funcia MoveBetweenTreeNodes folosete cele trei funcii


pentru a deplasa robotul ntre nodurile arborelui de cutare.
// se incearca mutarea robotul intre doua noduri ale
arborelui de cautare
// atentie, pozitia noua este posibil sa nu poata
fi accesata daca este obstacol
private SearchTreeNode
MoveBetweenTreeNodes(SearchTreeNode position,
SearchTreeNode newposition)
{
SearchTreeNode n;
Hashtable pList = new Hashtable();
n = newposition;
// se construieste o lista a parintilor
nodului tinta
while (n != null) { pList.Add(n.id, n); n =
n.parrent; }
n = position;
// robotul este mutat din parinte in parinte
pana cand se gaseste parintele comun
while (!(pList.ContainsKey(n.id))) { position
= MoveRobotFromChildToParrentNode(n); n = n.parrent; }
// acum robotul este in parintele comun
if (position.id == newposition.id)
{
// daca este chiar pozitia noua ne putem
opri
return position;
}
else
{
// altfel continuam deplasarea din parinte
in nodul tinta
Stack sList = new Stack();
SearchTreeNode s;
s = newposition.parrent;
// adaugam intr-o stiva toti parintii
nodului tinta
while (s != n) { sList.Push(s); s =
s.parrent; }
// robotul se muta din parinte in fiu pana
cand ajunge la parintele nodului tinta
while (sList.Count != 0) { s =

Aplicaii cu strategii de cutare neinformate i informate


-

- 76

(SearchTreeNode)sList.Pop(); position =
MoveRobotFromParrentToChildNode(s); }
// acum robotul este in parintele nodului
tinta
// se efectueaza mutarea daca este
posibila
position =
MoveRobotFromParrentToChildNodeIfPossible(newposition);
return position;
}
}
// robotul este mutat din nodul fiu in nodul
parinte
// atentie, aceasta mutare este tot timpul
posibila, deoarece intr-un nod fiu intotdeauna s-a ajuns
dintr-un nod parinte
private SearchTreeNode
MoveRobotFromChildToParrentNode(SearchTreeNode roboNode)
{
return roboNode.parrent;
}
// robotul este mutat din nodul parinte in nodul
fiu
// atentie, aceasta functie este doar pentru cazul
cand nodul fiu este deja explorat si deci accesibil
private SearchTreeNode
MoveRobotFromParrentToChildNode(SearchTreeNode roboNode)
{
return roboNode;
}
// robotul este mutat din nodul fiu in nodul
parinte
// atentie, aceasta mutare nu este tot timpul
posibila, functia testeaza asadar daca nodul fiu este
accesibil
private SearchTreeNode
MoveRobotFromParrentToChildNodeIfPossible(SearchTreeNode
roboNode)
{
SearchTreeNode n = null;
if (m[roboNode.coordX, roboNode.coordY] == 0)

Aplicaii cu strategii de cutare neinformate i informate


-

- 77

// daca pe harta in acest punct nu este un obstacol


{
if ((roboNode.nodeOperator == 0) ||
(roboNode.nodeOperator == 90) || (roboNode.nodeOperator ==
180) || (roboNode.nodeOperator == 270))
{
n = roboNode;
}
else // se interzice pe ramura else ca
mutarea sa se faca in diagonala pe langa un obstacol
{
switch (roboNode.nodeOperator)
{
case 45:
if
((m[roboNode.parrent.coordX, roboNode.parrent.coordY + 1]
== 0) && (m[roboNode.parrent.coordX + 1,
roboNode.parrent.coordY ] == 0))
{
n = roboNode;
}
else
{
n = roboNode.parrent;
}
break;
case 135:
if
((m[roboNode.parrent.coordX, roboNode.parrent.coordY - 1]
== 0) && (m[roboNode.parrent.coordX + 1,
roboNode.parrent.coordY] == 0))
{
n = roboNode;
}
else
{
n = roboNode.parrent;
}
break;
case 225:
if
((m[roboNode.parrent.coordX, roboNode.parrent.coordY - 1]
== 0) && (m[roboNode.parrent.coordX - 1,
roboNode.parrent.coordY] == 0))

Aplicaii cu strategii de cutare neinformate i informate


-

- 78

{
n = roboNode;
}
else
{
n = roboNode.parrent;
}
break;
case 315:
if ((m[roboNode.parrent.coordX
- 1, roboNode.parrent.coordY] == 0) &&
(m[roboNode.parrent.coordX, roboNode.parrent.coordY + 1]
== 0))
{
n = roboNode;
}
else
{
n = roboNode.parrent;
}
break;
}
}
}
else // daca pe harta in acest punct este un
obstacol atunci robotul se va afla tot in nodul parinte
{
n = roboNode.parrent;
}
return n;
}

Urmtoarele funciile sunt din nou similare cu cele din capitolele anterioare.
// verifica daca nodul curent nu este chiar nodul
tinta
private bool Solution(SearchTreeNode node,
SearchTreeNode targetnode)
{
if ((node.coordX == targetnode.coordX) &&
(node.coordY == targetnode.coordY))
{

Aplicaii cu strategii de cutare neinformate i informate


-

- 79

return true;
}
else
{
return false;
}
}
// calculeaza distanta diagonala intre doua puncte
private int DiagonalDistance(SearchTreeNode
current, SearchTreeNode target)
{
int xd = Math.Abs(current.coordX target.coordX);
int yd = Math.Abs(current.coordY target.coordY);
return straigthMovement * (Math.Max(xd, yd) Math.Min(xd, yd)) + diagonalMovement * Math.Min(xd, yd);
}
private void Form1_Load(object sender, EventArgs
e)
{
GenerateMap();
DisplayMapOnPictureBox();
}
private void buttonGenerateMap_Click(object
sender, EventArgs e)
{
GenerateMap();
DisplayMapOnPictureBox();
}
private void buttonSearch_Click(object sender,
EventArgs e)
{
SearchTreeNode x = new SearchTreeNode();
SearchTreeNode y = new SearchTreeNode();
y.coordX =
Convert.ToInt32(textBoxFinalStateX.Text);
y.coordY =
Convert.ToInt32(textBoxFinalStateY.Text);
y.heuristic = 0;

Aplicaii cu strategii de cutare neinformate i informate


-

- 80

y.id = y.coordX + 10000 * y.coordY;


x.coordX =
Convert.ToInt32(textBoxInitialStateX.Text);
x.coordY =
Convert.ToInt32(textBoxInitialStateY.Text);
x.heuristic = DiagonalDistance(x, y);
x.id = x.coordX + 10000 * x.coordY;
x.level = 0;
x.parrent = null;
m[x.coordX, x.coordY] = 0;
m[y.coordX, y.coordY] = 0;
PathFind(x, y);
}

9.1

Exerciii

1. Este algoritmul de cutare descris anterior complet? Dar optimal? Modificai


programul astfel nct agentul s gseasc drumul de cost minim.

Aplicaii cu strategii de cutare neinformate i informate


-

Lucrarea 10

- 81

ntrebri recapitulative i probleme

1. Se consider o tabl de ah de dimensiune nxn i se dorete parcurgerea celor nxn


careuri o singur dat folosind sritura calului. Se cere: a) Care este complexitatea
spaiului strilor pentru aceast problem b) Propunei dou strategii neinformate de
cutare care s fie optimale c) Pentru strategiile propuse n funcie de factorul de
ramificaie aferent problemei i de adncimea cutarii precizai complexitatea de timp
i spaiu d) Este posibil folosirea cutrii limitate n adncime pe aceast problema i
dac da atunci este aceast strategie complet i optimal?
Indicaii pentru rezolvare

( )
2

a) Complexitatea spaiului strilor este O 2n .


b) Strategiile breadth-first i iterative deepening sunt optimale deoacrece costul
operatorilor este egal.
c) Factorul de ramificaie este 8 iar adancimea este n n = n 2 deoarece calul trebuie s
treac prin fiecare careu o singura data. Pentru breadth-first avem
TBF = S BF = O ( b d ) = O 8n
iar pentru iterative-deepening avem TID = O ( b d ) = O 8n ,

( )

( )

S ID = O ( b d ) = O 8 n 2 .

d) Da, cutarea limitat n adncime este complet deoarece se cunoate adncimea


soluiei n 2 i optimal deoarece toate soluiile se afl pe limita de adncime.
2. Se consider spaiul cu obstacole din figura 10.1 i se dorete gsirea unui drum de
la B la A. Numerele supraunitare din careuri reprezint costurile trecerii n poziia
respectiv. Se cere: a) Demonstrai dac euristica distana diagonal este o euristic
admisibil sau nu. b) Propunei dou strategii (una neinformat i una informat)
complete i dou strategii optimale de cutare c) Propunei o euristic care s fie
admisibil d) Explorai cte 3 noduri folosind cele 4 strategii propuse e) Este cutarea
iterativ n adncime optimal pe aceast problem i n caz contrar cum poate fi fcut
optimal?

Figura 10.1 Spaiu cu obstacole

Aplicaii cu strategii de cutare neinformate i informate


-

- 82

Indicaii pentru rezolvare


a) Distana diagonal nu este o euristic admisibil deoarece fiecare careu are asociat
un cost aleator (distana diagonal era o euristic definit pentru spaiul cu obstacole n
cazul cnd diferena de cost aprea doar la deplasarea n linie dreapt fa de
diagonal)
b) Strategii complete: breadth first, bidirectional search, strategii optimale: uniform
cost, A*
c) Pentru a fi admisibil o euristic trebuie s nu supraestimeze costul drumului ntre
dou puncte, astfel innd cont c avem costuri supraunitare, distana ntre dou puncte
este mai mare sau egal cu diferena maxim dintre coordonatele lor. Aceast euristic
se definete astfel: P ( xP , yP ) , B ( xB , yB ) , h ( P, B ) = max { x , y } , x = xP xB ,
y = y P yB .

e) Cutarea iterativ n adncime nu este optimal deoarece costul operatorilor este


diferit. Ea poate fi fcut optimal dac n loc de limita de adancime se utilizeaz o
limit de cost iterativ.
3. a) Explicai cum se calculeaz complexitatea de timp i spaiu a strategiei Iterative
Deepening b) Dai un exemplu de spaiu al strilor pentru care strategia Depth-First
este mai eficient dect Iterative Deepening c) n ce ordine sunt parcurse nodurile dac
la strategia Greedy se folosete euristica h(n)=-g(n), care ar fi caracteristica esenial la
nivelul timpului de calcul (g(n) reprezint costul uniform) d) n ce situaii este A*
optimal, demonstrai si exemplificai.
4. a) Dai un exemplu de problem cu constrngeri (CSP) i justificai alegerea a
minim dou euristici pe aceast problem b) Ce intelegei prin euristic admisibil, ce
se ntmpl dac folosim o euristic ne-admisibil la A* (explicai aspectele pozitive i
negative care exist). Dai un exemplu de spaiu al strilor pentru care strategia DepthLimited este mai eficient dect Iterative Deepening c) Construii o euristic pentru
strategia Greedy astfel nct s fie explorate nti nodurile cele mai scumpe d) Este o
euristic admisibil monoton (exemplificai)? e) Explicai de ce A* nu intr n cicluri
infinite f) Dai un exemplu de spaiu al strilor pentru care strategia Iterative
Deepening este mai eficient dect A* g) Este o euristic monoton admisibil
(exemplificai)? h) Explicai de ce Iterative Deepening nu intr in cicluri infinite.
6. Se consider un spaiu bidimensional reinut ntr-o matrice de dimensiune m n i
un agent (entitate) aflat n punctul A ( x A , y A ) ce dorete s ajung n puctul B ( xB , yB ) ;
x A , xB {1, 2,..., m} , y A , yB {1, 2,..., n} . Fiecare punct din spaiu P ( xP , yP ) are asociat un

cost supraunitar C ( P ( xP , yP ) ) {1, 2,..., } care reprezint costul de acces al locaiei

Aplicaii cu strategii de cutare neinformate i informate


-

- 83

respective i orice cost c > , se consider obstacol i nu poate fi trecut de ctre

agent. Euristica folosit va fi h ( P, B ) = max { x , y } , x = xP xB , y = yP yB iar


pentru costul uniform se utilizeaz costul de acces al fiecrei locaii, deci
g ( P ( xP , yP ) ) = C ( P ( xP , yP ) ) + g ( Parinte( P ) ) unde g ( Parinte( P ) ) este costul nodului
printe al lui P ( xP , yP ) (deci la costul fiului se adaug costul uniform al tatlui).
Valorile m, n, x A , y A , xB , yB , , sunt variabile i se introduc de la tastatur iar costurile
se distribuie aleator pe harta. Se cere:
a) S se implementeze pe aceast problem strategiile de cutare: a) breadth-first b)
depth-first c) depth limited d) iterative deepening e) uniform-cost f) bidirectional
search (breadth first din ambele pri) g) bidirectional search (breadth first dintr-o parte
i depth-first din alta) h) bidirectional search (breadth first dintr-o parte i iterative
deepening din alta) i) bidirectional search (uniform cost din ambele pri) j) greedy k)
A-star l).
b) Se consider c agentul are de parcurs circuitul = { P0 , P1 ,..., Pk } i trebuie s
depun obiecte n fiecare punct Pi respectnd un set de prioriti : {0,1}
unde ( Pi , Pj ) = 1 dac depunerea de obiecte n Pi

este condiionat de depunerea

prealabil n Pj respectiv ( Pi , Pj ) = 0 dac nu exist nici o condiionare ntre Pi i Pj .


Mulimea i funcia (definit sub forma unei matrici) se citesc de la tastatur.
Folosind algoritmul (algoritmii) de la a) dai un traseu pe care agentul poate s l
parcurg astfel nct circuitul s fie parcurs n mod optimal. Observaie: este evident c
mulimea i relaia formeaz un graf orientat aciclic n cazul n care graful ar
contine cicluri problema nu ar mai avea soluie.
Programul va afia si rezultate referitoare la timpul de calcul, memoria utilizat,
numrul de stri atise, etc.

Aplicaii cu strategii de cutare neinformate i informate


-

- 84

Bibliografie
[1] Konar, A., Artificial Intelligence and Soft Computing Behavioral and
Cognitive Modeling of the Human Brain, CRC Press, 1999.
[2] Korf, R.E., Artificial Intelligence Search Algorithms, Computer Science
Department
University
of
California,
Los
Angeles,
1998.
http://citeseer.ist.psu.edu/493289.html .
[3] Russell, S.J., Norvig, P., Artificial Intelligence A Modern Approach, Prentice
Hall, Englewood Cliffs, New Jersey, 1996.
[4] Exemple de Jocuri, Learn4Good, (recomandate in scop didactic) http://www.learn4good.com/games/.
[5] Exemplu A-star http://www.policyalmanac.org/games/aStarTutorial.htm.

Aplicaii cu strategii de cutare neinformate i informate


-

- 85

Anexe
Anexa 1. Elemente de teoria complexitii algoritmilor
O problem este o mulime nevid de ntrebri ntre care exist o relaie, pot fi
una sau mai multe ntrebri i este obligatoriu ca ele s aib o dimensiune finit. De
exemplu factorizarea unui ntreg este o problem cu urmtorul enun: avnd un ntreg n
s se gseasc numerele prime al cror produs este. Un algoritm este un set bine definit
de pai pentru rezolvarea unei probleme. Altfel spus, un algoritm este ansamblul de
pai prin care un set de date de intrare este transformat ntr-un set de date de ieire n
scopul rezolvrii unei probleme. De exemplu pentru rezolvarea problemei factorizrii
ntregului de mai sus se poate folosi urmtorul algoritm: pentru toi ntregii i de la 2 la
radical din n verific dac n este divizibil cu i.
Este evident c eficiena unui algoritm este o funcie care depinde de
dimensiunea datelor de intrare i totodat eficiena unui algoritm trebuie s fie o
caracteristic intrinsec a algoritmului care s nu depind de un anume model al
mainii de calcul. n acest context este impropriu s numim un algoritm ca fiind
eficient n baza faptului c pe un anumit procesor a avut un timp de rulare oarecare, i
mai mult, faptul c pe un procesor a avut un anume timp de rulare nu va spune nimic
cu privire la timpul de rulare n momentul n care dimensiunea datelor de intrare se
dubleaz. S presupunem ca exemplu naiv doi algoritmi care caut un element ntr-un
ir ordonat cresctor, algoritmul A1 implementeaz o cutare naiv n care irul este
parcurs de la un capt la altul element cu element n scopul identificrii elementului
cutat iar A2 implementeaz o cutare binar, prin njumtirea succesiv a irului n
care se face cutarea. S presupunem c timpul de calcul pentru un tablou cu 1.000.000
de elemente este pentru primul algoritm 5 milisecunde i pentru al doilea 5
microsecunde. La dublarea dimensiunii datelor de intrare timpul de calcul pentru
primul algoritm se va dubla n timp ce pentru al doilea va crete nesemnificativ.
Aceasta deoarece, pentru gsirea unui element ntr-un ir de n elemente, primul
algoritm efectueaz cel mult n pai iar cel de-al doilea cel mult log2n pai. n
consecin performana unui algoritm nu trebuie descris n funcie de timpul de rulare
al acestuia ci n funcie de numrul de pai pe care algoritmul i necesit. Aici intr n
joc teoria complexitii care este domeniul care ne ofer un rspuns cu privire la
numrul de pai necesari ca un algoritm s ofere n rezultat.
n general cu privire la un algoritm, sub raportul complexitii, ne intereseaz
att timpul (despre care s-a spus c se msoar n numr de pai) ct i spaiul (care
nseamn cantitate de memorie necesar) de aici i noiunile de complexitate de timp
i complexitate de spaiu. Pentru msurarea complexitii folosim urmtorii indicatori
de performan:

Aplicaii cu strategii de cutare neinformate i informate


i)

- 86

limita asimptotic superioar:

f (n ) = O(g (n) ) c, no a.i. 0 f (n ) c g (n )n n0


ii)

limita asimptotic inferioar:

f (n ) = ( g (n) ) c, no a.i. 0 c g (n ) f (n ), n n0
iii)

limita asimptotic restrns:

f (n ) = ( g (n) ) c1 , c2 , no a.i. c1 g (n ) f (n ) c2 g (n )n n0
iv)

limitele asimptotice relaxate:

f (n ) = o(g (n) ) no a.i. c 0 f (n ) < c g (n )n n0


f (n ) = ( g (n) ) no a.i. c 0 c g (n ) < f (n )n n0

Este important de spus c f = F g ( n ) , unde F este oricare din indicatorii


, , , , nu se citete: f egal F de g(n), ci corect este f este de ordinul F al lui
g(n) sau mai simplu f este F(g(n)). Intuitiv semnul = nu are semnificaia semnului
egal, n acest caz este echivalent cu .
Astfel n funcie de timpul de calcul algoritmii se mpart n clase dup cum
urmeaz:
constant
O(1) ,
logaritmic
O(lg(n ))
(se
observ
c

log c n = (lg n), c > 0 ), poli-logaritmic O ( lg c ( n ) ) , fracional O ( n c ) , 0 < c < 1 ,

( )

liniar O(n ) , liniar logaritmic O ( n log 2 n ) , ptratic (sau cvadratic) O n 2 , cubic

( )

O n 3 , polinomial O(n m ) (cu observaia c: liniar, ptratic, cubic sunt timpi


polinomiali), super-polinomial O c f (n ) (unde c este o constant iar f (n ) nu este
constant dar este mai mic dect O(n ) ), exponenial O c f (n ) (unde c este o constant
iar f (n ) este un polinom de gradul 1), factorial (sau Combinatorial) O ( n !) , dublu

( ).

exponenial O 2c

Urmtoarele proprieti intuitive decurg direct din definiia acestor indicatori:


i)

f (n ) = O( g (n )) g (n ) = ( f (n ))

ii)

f (n ) = (g (n )) f (n ) = O( g (n )) f (n ) = ( g (n ))

iii)

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

iv)

f (n ) = O(h(n )) g (n ) = O(i (n )) ( f g )(n ) = O(h(n ) i (n ))

Aplicaii cu strategii de cutare neinformate i informate


v)
f (n ) = O( f (n )) reflexivitate
vi)

- 87

f (n ) = O( g (n )) g (n ) = O(h(n )) f (n ) = O(h(n )) tranzitivitate


Reinem de asemenea urmtoarele aproximri utile:

( )

i)

f (n ) = a k n k + a k 1 n k 1 + ... + a1 n + a0 f (n ) = n k

ii)

n! = o n n n! = 2 n

iii)

1 < ln ln n < ln n < e

( )

( )
(ln n )(ln ln n )

< n < n c < n ln n < c n < n n < c c

Pentru a ilustra importana cunoaterii complexitii prezentm urmtorul tabel


al unor magnitudini uzuale i de asemenea vom considera 4 algoritmi A1 , A2 , A3 , A4

( ) ( ) ( )

avnd complexitile O (n ) , O n 2 , O n 3 , O 2 n precum i un sistem capabil s


10

execute 10 operaii/secund, n scopul unei comparaii vom evalua timpul necesar


rezolvrii algoritmilor pentru n = 10 6 . Tabelul 1 sintetizeaz aceste rezultate.
Secunde ntr-un an

3 10 7

Vrsta sistemului solar n secunde

2 1017

Electroni n univers

8.37 10 77

Timpul pentru a rezolva A1

110 3

Timpul pentru a rezolva A2

1 10 2

Timpul pentru a rezolva A3

1 108

Timpul pentru a rezolva A4

1 10 303020

Tabel 1. Cteva magnitudini uzuale.