Sunteți pe pagina 1din 18

Lucrarea 6 Bazele inteligenei artificiale

- 1 -



n acest laborator ne vom concentra atenia asupra unor jocuri de tip
puzzle i a altor probleme de inteligen artificial care pot fi rezolvate de o
singur persoan.

Probleme rezolvate

1. Problema labirintului.
Primul exemplu de puzzle este un labirint simplu. Scopul este acela
de a gsi o cale de parcurgere a labirintului de la un capt (Intrare Start) la
cellalt (Ieire - Sosire). n primul rnd, trebuie s reprezentm labirintul
ntr-o form pe care limbajul Prolog o poate nelege. Labirintul a fost
construit pe o hrtie milimetric i are 6 ptrele lime i 6 ptrele
lungime. ncepem prin a numerota aceste ptrele (Figura 6.1).


Figura 6.1 Un labirint simplu n interiorul cruia sunt numerotate locaiile

Tratnd Intrare(Start) i Ieire(Sosire) ca poziii n labirint, rezult
c avem n total 38 de poziii. De la fiecare din acestea ne putem deplasa
spre alte poziii posibile. Dac putem trece dintr-o poziie n alta, spunem c
aceste dou poziii sunt conectate. Pentru aceasta introducem predicatul
conecteaza pentru fiecare pereche de locaii conectate. Apoi definim
predicatul conectate folosind predicatul conecteaza:
conect eaza( pl ecar e, 2) .
conect eaza( 1, 7) .
Lucrarea 6 Bazele inteligenei artificiale

- 2 -
conect eaza( 2, 8) .
. . . . . . . . . . . . . . . . . . . . . . . . . . .
conect eaza( 32, sosi r e) .
conect at e( Locat i e1, Locat i e2) : - conect eaza( Locat i e1, Locat i e2) .
conect at e( Locat i e1, Locat i e2) : - conect eaza( Locat i e2, Locat i e1) .

O cale prin labirint reprezint o list de poziii cu start la un capt al
listei i sosire la cellalt capt, astfel nct fiecare poziie din list este
conectat la poziiile dinainte i de dup ea. Iniial, calea conine un singur
punct start, pe care l plasm ntr-o list. De la acest punct iniial vom
genera o cale complet (start, , sosire). La fiecare pas intermediar n
cutarea soluiei labirintului, avem o list a poziiilor pe care deja le-am
vizitat. Primul membru al acestei liste este poziia curent (LocatieCurenta).
Avansm, cutnd o poziie nou la care s ajungem de la poziia curent.
Pentru a evita nvrtirea n cerc sau deplasarea nainte i napoi, ntre
(trecnd prin) aceleai poziii, trebuie ca noua poziie s nu existe deja n
calea pe care ncercm s o construim.

cale([LocatieCurenta|RestulCaii], Solutie):-
conectate(LocatieCurenta, urmatoareaLocatie),
\+ member(UrmatoareaLocatie, RestulCaii),
cale([UrmatoareaLocatie,
LocatieCurenta|RestulCaii],Solutie).

Dac funcia cale atinge un punct din care nu poate gsi o nou
poziie, atunci limbajul Prolog se va ntoarce (napoi) pe acelai drum
(metoda backtracking). Poziiile vor fi plasate n faa cii pe care am
construit-o, pn cnd atingem o poziie nou. Apoi, cutarea va avansa,
pn cnd atingem sosire sau alt punct final (capt). Din moment ce
labirintul are o soluie, aplicaia Prolog o va gsi (evident dac am definit
corect procedura de cutare).
Vom construi un fiier labirint-bd.pl, ce conine baza de cunotine
(tabelul de conexiuni pentru labirintul din figura 6.1). Fiierul are urmtorul
coninut:

Lucrarea 6 Bazele inteligenei artificiale

- 3 -



Codul surs SWI-Prolog pentru fiierul rezolva-labirint.pl este
urmtorul (predicatul \+ are sensul de not):



La testare, rspunsul sistemului este:

Lucrarea 6 Bazele inteligenei artificiale

- 4 -


2. Problema misionarilor i a canibalilor.
Cel de-al doilea puzzle propus n acest laborator se refer la
problema misionarilor i a canibalilor. Trei misionari i trei canibali trebuie
s traverseze un ru, dar singura barc disponibil poate duce doar doi
oameni la un moment dat. Nu exist pod, rul nu poate fi trecut not i barca
nu poate trece rul fr cineva n ea. Canibalii vor mnca misionarii dac
sunt mai muli ca ei pe unul dintre maluri. Problema const n trecerea
tuturor persoanelor pe malul cellalt fr nici un misionar mncat.
Asemenea problemei labirintului, vom ncepe prin a decide cum vom
reprezenta problema n Prolog. Am desemnat un mal al rului ca fiind malul
stng, iar cellalt malul drept i presupunem c, la nceput, barca,
misionarii i canibalii se afl pe malul stng. La fiecare etap de traversare a
misionarilor i a canibalilor peste ru, vom avea nite misionari pe malul
stng si pe malul drept, nite canibali pe malul stng i pe malul drept, iar
barca va fi, fie pe malul stng, fie pe cel drept. Putem reprezenta aceast
informaie printr-o structur care s ne spun ci misionari sunt pe malul
stng, ci canibali sunt pe malul stng i locaia brcii: etapa(M, C, B).
Aici, variabilele M i C pot lua valori ntre 0 i 3, iar variabila B poate lua
valoarea s (malul stng) sau d (malul drept).
Structura etapa(3, 3, s) reprezint situaia de la nceputul puzzle-
ului, iar structura etapa(0, 0, d) reprezint situaia la care vrem s ajungem.
O soluie a puzzle-ului ar fi o list de situaii cu etapa(3, 3, s) la un capt al
listei i etapa(0, 0, d) la cellalt. Din moment ce programul produce o list
de etape n ordinea invers celei n care se ntmpl, vom pune programul s
inverseze soluia naintea afirii ei.

canibal :- solutie_canibal([etapa(3,3,s)], Solutie),
reverse(Solutie, [], SolutieOrdonata),
afisare_etape(SolutieOrdonata).

Oricare dou etape succesive din soluie vor trebui s satisfac o
serie de condiii:
n primul rnd, barca va fi pe maluri diferite ale rului n cele
dou etape. Asta deoarece nimeni nu poate traversa rul fr
barc.
Lucrarea 6 Bazele inteligenei artificiale

- 5 -
n al doilea rnd, canibalii nu vor fi niciodat mai muli ca
misionarii pe nici un mal al rului.
n al treilea rnd, fiecare etap va rezulta din cealalt prin
trimiterea brcii cu misionari i canibali peste ru, n direcia
potrivit.
Vom rezolva acest puzzle n aproape acelai mod n care am rezolvat
problema labirintului, cu excepia faptului c, la fiecare etap din cutarea
soluiei, restriciile pentru urmtoarea mutare vor fi mult mai complicate.
Vrem ca Prolog-ul s exploreze toate combinaiile posibile de treceri peste
ru pn va gsi una potrivit. La orice moment din acest proces, vom avea
o list de stri care rezult din trecerile care au fost fcute pn atunci.
Primul membru al acestei liste este starea curent. Vrem ca Prolog-ul s
caute o nou stare care poate fi ajuns din starea curent. Starea curent
trebuie s fie rezultatul unei treceri legale din starea curent, nu trebuie s
pun n pericol nici un misionar i trebuie s fie o stare care nu a mai fost.
Ultima cerin mpiedic Prolog-ul s mute aceiai oameni de pe un mal pe
altul fr a face nici un progres. Pentru a ndeplini acestea, adugm dou
clauze la definiia solutie_canibal, una pentru momentul cnd barca este pe
malul stng i cealalt atunci cnd este pe malul drept, astfel:
solutie_canibal([etapa(M1, C1, s) | Etapele_anterioare], Solutie):-
membru([M,C],[[0,1],[1,0],[1,1],[0,2],[2,0]]), %Condiia 1
M1>=M, %Condiia 2
C1>=C, %Condiia 3
M2 is M1-M, %Condiia 4
C2 is C1-C, %Condiia 5
membru([M2,C2],[[3,_],[0,_],[N,N]]), %Condiia 6
\+ membru(etapa(M2,C2,d),Etapele_anterioare), %Cond 7
solutie_canibal([etapa(M2, C2, d), etapa(M1, 1, s) |
Etapele_anterioare], Solutie).

solutie_canibal([etapa(M1, C1, d)|Etapele_anterioare], Solutie) :-
membru([M,C],[[0,1],[1,0],[1,1],[0,2],[2,0]]),
3-M1>=M, 3-C1>=C,
M2 is M1+M, C2 is C1+C,
membru([M2,C2],[[3,_],[0,_],[N,N]]),
\+membru(etapa(M2,C2,s),Etapele_anterioare),
Lucrarea 6 Bazele inteligenei artificiale

- 6 -
solutie_canibal([etapa(M2,C2,s),etapa(M1,C1,d)|Etapele_anterioare]
, Solutie).

Pentru a nelege programul trebuie s nelegem condiiile din prima
clauz prezentat mai sus.
Condiia 1 arat c barca trebuie s care cel puin unul i cel mult
doi indivizi peste ru.
Condiiile 2 i 3 asigur c nu vor intra pe barc mai muli misionari
i canibali dect cei prezeni pe malul stng al rului.
Condiiile 4 i 5 determin ci misionari i ci canibali vor fi pe
malul stng dup urmtoarea traversare.
Condiia 6 verific dac misionarii sunt teferi dup traversare. O
stare este sigur dac toi misionarii sunt pe acelai mal (i, deci, nu pot fi
mai puini dect canibalii) sau dac este un numr egal de canibali i
misionari pe malul stng (deci i un numr egal pe malul drept).
n final, condiia 7 garanteaz c programul nu se ntoarce la o stare
anterioar.
Dac solutie_canibal ajunge la un moment de unde nu mai poate
gsi o trecere n siguran care va produce o situaie care nu a fost ncercat
nc, Prolog se ntoarce (pe ci dintre calea iniial i calea curent) la un
punct unde este posibil o nou situaie. Apoi cutarea continu, din nou,
nainte.
O posibil implementare n Prolog a problemei misionarilor i a
canibalilor este urmtoarea (fiierul Canibal.pl):






Lucrarea 6 Bazele inteligenei artificiale

- 7 -






Lucrarea 6 Bazele inteligenei artificiale

- 8 -
Afim o soluie a problemei printr-o serie de imagini. Aceasta
presupune inversarea listei soluiei pentru ca strile s fie afiate n ordinea
corect generat. Predicatul afisare_etape i auxiliarele lui fac acest lucru,
desennd imagini cu ordinarele caractere ASCII aa cum este prezentat n
Figura 6.2.


Figura 6.2 O soluie la problema misionarilor i a canibalilor


3. Problema triunghiului (triangle puzzle).
Puzzle-ul Triunghiul, numit si Puzzle-ul Pomului de Crciun,
este jucat cu cincisprezece bee de culori diferite amplasate pe o machet.
Macheta are 15 guri amplasate ntr-un format triunghiular (figura 6.3).

Figura 6.3 Macheta de joc

Iniial, exist un b n fiecare gaur. Juctorul elimin un b, apoi sare
de la un b la altul i, la fiecare sritur, elimin bul peste care a srit. Un
salt trebuie ntotdeauna s se realizeze n linie dreapt. La un moment dat un
Lucrarea 6 Bazele inteligenei artificiale

- 9 -
singur b poate fi srit. Scopul jocului este de a termina cu un singur b pe
macheta de joc.
O soluie a puzzle-ului este reprezentat de o succesiune de panouri
cu paisprezece bee n panoul iniial i un b n panoul final.
Programul nostru are la nceput o procedur, triunghi (N), care
elimin al N-lea b din triunghi. Procedura denumit rezolva_triunghi
gsete soluia i o afieaz sub form de triunghi.

t r i unghi ( N) : -
el i mi na_bat ( N, Tr i unghi St ar t ) ,
r ezol va_t r i unghi ( 14, [ Tr i unghi St ar t ] , Sol ut i e) ,
nl , nl ,
af i s_t r i unghi ( Sol ut i e) .

Procedura rezolva_triunghi utilizeaz, ca prim argument, un numr
pentru a ine evidena numrului de bee din triunghiul curent. O soluie a
problemei a fost atins n cazul n care exist un singur b rmas pe
macheta de joc. Dac sunt mai multe bee rmase, procedura
rezolva_triunghi caut, printr-un salt legal, un triunghi ce poate fi generat
din triunghiul curent i l adaug la lista de triunghiuri. Procedura afieaz
numrul de bee rmase n noul triunghi. n continuare procedura se repet
pn cnd se obine un triunghi cu un singur b.

r ezol va_t r i unghi ( 1, Sol ut i e, Sol ut i e) .
r ezol va_t r i unghi ( Cont or , [ Tr i unghi Cur ent ] , Sol ut i e) : -
sal t ( Tr i unghi Cur ent , Tr i unghi Ur mat or ) ,
Cont or Nou i s Cont or - 1,
wr i t e( Cont or Nou) , nl ,
r ezol va_t r i unghi ( Cont or Nou, [ Tr i unghi Ur mat or ] , Sol ut i e) .

nainte de a putea utiliza rezolva_triunghi, avem nevoie de o
modalitate de a calcula triunghiurile ce rezult din salturile realizate n
triunghiul curent. Exist mai multe ci de a realiza acest lucru, dar una
dintre cele mai simple este prezentat n cele ce urmeaz.
n primul rnd, vom reprezenta fiecare triunghi printr-o list de
cincisprezece guri. Fiecare gaur este reprezentat de o variabil:

[A,
B, C,
D, E, F,
G, H, I, J,
K, L, M, N, P].

Lucrarea 6 Bazele inteligenei artificiale

- 10 -
Reprezentnd un salt ca o transformare de la un triunghi la altul, vom
observa c doar trei guri ntr-un triunghi sunt afectate la fiecare salt. Restul
de guri, rmn goale sau ocupate, aa cum au fost nainte de salt. Vom
utiliza 1 pentru a reprezenta o gaur n care se afl un b i 0 pentru a
reprezenta o gaur goal (n care nu se afl un b).


Astfel vom putea defini un predicat binar al saltului (salt), folosind un
set de clauze cum ar fi urmtoarele:

sal t ( t r i unghi ( 1,
1, C,
0, E, F,
G, H, I , J ,
K, L, M, N, P) ,
t r i unghi ( 0,
0, C,
1, E, F,
G, H, I , J ,
K, L, M, N, P) ) .

Avem nevoie de o astfel de clauz pentru fiecare salt posibil. Tot ceea ce
rmne de fcut este de a defini o procedur care va elimina bul iniial i
rutine pentru afiarea soluiei finale.

Codul surs SWI-Prolog pentru fiierul puzzleTriunghi.pl este
urmtorul:


Lucrarea 6 Bazele inteligenei artificiale

- 11 -






Lucrarea 6 Bazele inteligenei artificiale

- 12 -



Lucrarea 6 Bazele inteligenei artificiale

- 13 -


Lucrarea 6 Bazele inteligenei artificiale

- 14 -
Rezultate obinute la testare:










4. Problema colorrii hrilor.
Se consider o hart care cuprinde n ri din care unele au grani
comun. S se coloreze harta utiliznd s culori (s < n) astfel nct oricare
dou ri cu grani comun s fie colorate diferit.
Problema const deci, n colorarea fiecrei regiuni a hrii cu o culoare
(dintr-un set de culori) astfel nct dou ri vecine s fie colorate diferit
(condiiile interne).
Pentru rezolvarea problemei vom utiliza dou fiiere:
Un fiier denumit Europa.pl ce conine baza de cunotine
(numele rilor i nlnuirea acestora).
Un al doilea fiier denumit harta.pl ce implementeaz
algoritmul backtracking pentru colorarea hrii.
Lucrarea 6 Bazele inteligenei artificiale

- 15 -
Codul surs SWI-Prolog pentru fiierul harta.pl este urmtorul:








Lucrarea 6 Bazele inteligenei artificiale

- 16 -
Fiierul Europa.pl are urmtorul coninut:






Rezultate obinute la testare:

3 ?- harta.

Lucrarea 6 Bazele inteligenei artificiale

- 17 -
6.3 Probleme propuse

1. Se vor studia problemele rezolvate (problemele prezentate pe
parcursul acestui laborator), ncercnd gsirea altor posibiliti de
soluionare a acestora. Utilizai i alte scopuri (interogri) pentru a
testa definiiile predicatelor introduse.
2. Se vor rezolva urmtoarele probleme propuse i se va urmri
execuia lor corect.
Construii un labirint care are mai multe soluii i mai multe
ci prin labirint. Definii o procedur ceaMaiScurtaCale,
care gsete cea mai scurt cale prin labirint.
Creai un listing similar celui din fiierul Europa.pl, care s
se numeasc Africa.pl, n care s introducei date geografice
ale continentului african. Acesta va fi folosit cu aplicaia
harta.pl. Rulai aceasta aplicaie cu ajutorul datelor din
Africa.pl i verificai corectitudinea rezultatelor obinute.
Putei colora o hart a Europei sau a Africii, folosind doar
trei culori? Explicai. Cum putei modifica programul
harta.pl., astfel nct Prolog sa rspund acestei ntrebri?
Realizai o aplicaie care s gseasc soluia pentru un puzzle
triunghi cu 10 guri. Gurile sunt aranjate astfel:

Precizai dac exist soluii pentru acest tip de machet de
joc.
Problema ranului. Un ran trebuie s transporte peste un
ru o vulpe, o gsc i o traist cu gru. ranul poate
traversa not rul lund un singur element sau nici unul. Dac
vulpea rmne pe acelai mal cu gsca i ranul este pe
cellalt mal, gsca va fi mncat de vulpe. Acelai lucru se
ntmpl i cu gsca i traista de gru. Scriei un program
Prolog care s caute i s afieze toate soluiile de rezolvare a
acestui puzzle. Programul va fi apelat prin interogarea

S se scrie un program n Prolog pentru a rezolva problema
"Jocul Vieii". ntr-o matrice, fiecare celul este reprezentat
cu 1, dac este vie, i cu 0, dac este moart. Regulile
sunt urmtoarele:
Lucrarea 6 Bazele inteligenei artificiale

- 18 -
Dac celula este vie la timpul t, va rmne vie i
la timpul t+1, dac i numai dac are 2 vecini vii
sau 3 vecini vii.
Dac celula este moart la timpul t, va nvia la
timpul t + 1, dac i numai dac are 3 vecini vii.

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