Explorați Cărți electronice
Categorii
Explorați Cărți audio
Categorii
Explorați Reviste
Categorii
Explorați Documente
Categorii
-4-
Bogdan Groza1
-5-
CUPRINS
LUCRAREA 1
ARTIFICIALE
1.1
1.2
1.3
1.4
LUCRAREA 3
3.1
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
LUCRAREA 5
STRATEGII NEINFORMATE DE CUTARE: STRATEGIA DE
CUTARE CU COST UNIFORM ............................................................................................42
5.1
5.2
-6-
LUCRAREA 6
STRATEGII INFORMATE DE CUTARE: STRATEGIILE DE
CUTARE BEST FIRST I GREEDY ....................................................................................54
6.1
6.2
6.3
6.4
LUCRAREA 7
7.1
7.2
7.3
LUCRAREA 8
CUTARE A*
8.1
8.2
LUCRAREA 9
9.1
EXERCIII ....................................................................................................................80
LUCRAREA 10
-7-
Cuvnt nainte
Timioara,
Noiembrie 2008
Bogdan Groza
-8-
Lucrarea 1
Introducere n problematica
Inteligenei Artificiale
1.1
-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
Participant uman A
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
- 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
- 11
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
1 2 3
4 5 6
7 8
Stare Finala
- 12
1.4
- 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
- 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
- 15
- 16
- 17
Lucrarea 2
Strategii neinformate de cutare:
strategiile de cutare pe nivel i bidirecional
2.1
2.2
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.
- 18
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
- 19
( )
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
Pasul 2
Pasul 3
Pasul 4
Avantaje i dezavantaje
Avantajul major este faptul c strategia este complet, mai mult este chiar i
optimal n condiiile anterior menionate.
- 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.
Noduri Frontiera
Arbore de cautare BF
Noduri Frontiera
Stare
Initiala
- 21
Stare
Finala
Arbore de cautare BF
d
d/2
d/2
S = 2b
d /2
= O(b
d /2
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
- 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
R3 R2
R3 R1
R2 R1
R2 R3
R1 R2
R1 R3
S=T=O(bd)=68
- 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}
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.
- 24
- 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;
- 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)
- 27
- 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);
}
" +
" +
" +
- 1;
- 29
=
=
=
=
=
- 30
state[8].ToString();
state[10].ToString();
state[12].ToString();
state[14].ToString();
state[16].ToString();
Lucrarea 3
cutare
- 31
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
- 32
- 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.
- 34
Lucrarea 4
Strategii neinformate de cutare:
strategiile de cutare n adncime, adncime
limitat i adncime iterativ
4.1
( )
Completitudine i optimalitate
- 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
4
3
Pasul 1
Pasul 2
Pasul 3
Pasul 4
Stiva:
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
- 36
( )
( )
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
- 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.
( )
( )
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).
- 38
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.
- 39
- 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;
- 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?
- 42
Lucrarea 5
Strategii neinformate de cutare:
strategia de cutare cu cost uniform
5.1
- 43
Lista
ordonata
dupa
cost:
15
15
16
Pasul 1
Pasul 2
Pasul 3
Pasul 4
( )
co
cm
( )
Completitudine i optimalitate
- 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
- 45
- 46
- 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);
}
- 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)
- 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;
- 50
- 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 =
- 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);
}
- 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).
- 54
Lucrarea 6
Strategii informate de cutare:
strategiile de cutare best first i greedy
6.1
Ce este o euristic
1 2 3
4 5 6
7 8
Stare Finala
- 55
3 2 1
4 5 6
8 7
Stare Curenta
6.2
6.3
- 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.
( )
( )
n cel mai
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
- 57
- 58
- 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).
Lucrarea 7
- 60
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
7.2
- 61
- 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).
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
- 63
(1)
Fie un nod n care aparine cii optimale, deoarece h este o euristica admisibil:
co >=f(n)
(2)
(3)
(4)
(5)
(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:
- 64
Oras
Timisora
Recas
Lugoj
Buzias
Farliug
Bocsa
Sag
Voiteg
Deta
hSLD (Resita)
100
90
30
65
30
10
95
40
70
- 65
- 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.
- 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);
}
- 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
- 69
- 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;
}
- 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);
- 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"); }
}
- 73
- 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-
- 75
- 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)
- 77
- 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))
{
- 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;
- 80
9.1
Exerciii
Lucrarea 10
- 81
( )
2
( )
( )
S ID = O ( b d ) = O 8 n 2 .
- 82
- 83
- 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.
- 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:
- 86
f (n ) = ( g (n) ) c, no a.i. 0 c g (n ) f (n ), n n0
iii)
f (n ) = ( g (n) ) c1 , c2 , no a.i. c1 g (n ) f (n ) c2 g (n )n n0
iv)
( )
( )
( ).
exponenial O 2c
f (n ) = O( g (n )) g (n ) = ( f (n ))
ii)
f (n ) = (g (n )) f (n ) = O( g (n )) f (n ) = ( g (n ))
iii)
iv)
- 87
( )
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)
( )
( )
(ln n )(ln ln n )
( ) ( ) ( )
3 10 7
2 1017
Electroni n univers
8.37 10 77
110 3
1 10 2
1 108
1 10 303020