Tehnici de rezolvare a problemelor de satisfacere a constrângerilor
Culori:
galben
A E
roşu
albastru
B
C D
Fig.1. Colorarea unei hărţi
B ne=”nu e egal”
ne
ne C
ne
ne
A D
ne
ne E ne
Fig.2. O reprezentare grafică a problemei
colorării hărţii
R
R
R
R
Fig.3. Soluţie a problemei celor 4 regine
Tehnica generare-testare
Schema generală
gasire(Variabile,Constr,Solutia):-
generare(Variabile,Solutia),
testare(Constr,Solutia).
1
generare([],[]).
generare([V,D|RestVariabile],[V,X|SolPartiala]):-
selectare_valoare(X,D),
generare(RestVariabile,SolPartiala).
testare([],_).
testare([C|RestConstr],Solutia):-
test_constr(C,Solutia),
testare(RestConstr,Solutia).
Tehnica generare testare pentru colorarea hărţii
% colorare1(+Graf,+Culori,-Colorare)
colorare1(g(Ns,Ms),Culori,Colorare):-
gener(Ns,Culori,Colorare),
test(Ms,Colorare).
% gener(+Noduri,+Culori,-Colorare)
gener([],_,[]).
gener([N|Ns],Culori,[N,C|T]):-
% generarea nondeterministică a culorilor
apartine(C,Culori),
gener(Ns,Culori,T).
% test(+Muchii,+Colorare)
test([],_).
test([m(N1,N2)|Ms],Colorare):-
% găsim culoarea nodului N1
apartine(N1,C1,Colorare),
% găsim culoarea nodului N2
apartine(N2,C2,Colorare),
% testam diferenţa de culori
not(egal(C1,C2)),
test(Ms,Colorare).
Tehnica generare testare pentru problema celor N regine
regine(N,Regine):-
sir(1,N,Ns),
permutare(Ns,Regine),
nepericulos(Regine).
nepericulos([Regina|Regine]):-
nepericulos(Regine),
not(ataca(Regina,Regine)).
nepericulos([]).
ataca(R,Rs):-ataca(R,1,Rs).
ataca(X,N,[Y|_]):-X=Y+N.
ataca(X,N,[Y|_]):-X=Y-N.
ataca(X,N,[_|Ys]):-
N1=N+1,
2
ataca(X,N1,Ys).
sir(M,N,[M|Ns]):-
M<N,
M1=M+1,
sir(M1,N,Ns).
sir(N,N,[N]).
Tehnica backtracking
Schema generală a acestei tehnici poate arăta:
bcktr([V,D|RestVariabile],Constr,SolPartial,Solutia):-
selectare_valoare(X,D),
egal(SolNouaPartial,[V,X|SolPartiala]),
testare(Constr,SolNouaPartial,RestConstr),
bcktr(RestVariabile,RestConstr,SolNouaPartial,Solutia).
testare([],_,[]).
testare([C|RestConstr],SolPartial,ConstrNontest):-
poate_fi_testata(C,SolPartial),!,
test_constr(C,SolPartial),
egal(ConstrNontest,Constr)
testare(RestConstr,SolPartial,Constr).
testare([C|RestConstr],SolPartial,ConstrNontest):-
egal(ConstrNontest,[C|Constr])
testare(RestConstr,SolPartial,Constr).
poate_fi_testata(C,SolPartial):-
variabile(C,Variabile),
sunt_instant(Variabile,SolPartial).
Tehnica backtracking pentru colorarea hărţii
% colorare2(+Graf,+Culori,-Colorare)
colorare2(g(Ns,Ms),Culori,Colorare):-
% generare si testare
g_t(Ns,Ms,Culori,[],Colorare).
% g_t(Noduri,Muchii,Culori,NoduriColorate,ColorareFinala)
g_t([],_,_,Colorare,Colorare).g_t([N|Ns],Ms,Cs,Acc,Colorare):-
% generare culoare pentru N
apartine(C,Cs),
% testare validităţii colorării curente
not(invalida(Ms,N,C,Acc)),
g_t(Ns,Ms,Cs,[N,C|Acc],Colorare).
% invalida(+Muchii,+Nod,+Culoare,+ColorareCurenta)
invalida([m(N1,N2)|_],N,C,ColorareC):-
egal(N,N1),
3
apartine(N2,C,ColorareC),!.
invalida([m(N1,N2)|_],N,C,ColorareC):-
egal(N,N2),
apartine(N1,C,ColorareC),!.
invalida([_|Ms],N,C,ColorareC):-
invalida(Ms,N,C,ColorareC).
Tehnica backtracking pentru cele N regine
regine(N,Regine):-
sir(1,N,Ns),
regine(Ns,[],Regine).
regine(RegineNeplasate,RegineNepericuloase,Regine):-
eliminare_elem(Regina,RegineNeplasate,RegineNeplasate1),
not(ataca(Regina,RegineNepericuloase)),
regine(RegineNeplasate1,[Regina|RegineNepericuloase],Regine).
regine([],Regine,Regine).
Fig.4. Soluţia problemei celor 4 regine (backtracking)
Rezolvarea enigmelor logice
Deci vom formula prima regulă care de obicei defineşte structura de date.
regula(1,[prieten(_,_,_),prieten(_,_,_),prieten(_,_,_)]).
Luând în consideraţie că lista de prieteni e ordonată, condiţia joacă mai bine poate fi definită
de predicatul joaca_mai_bine(Prieten1,Prieten2,Lista_de_prieteni) care poate avea doar trei variante.
joaca_mai_bine(P1,P2,[P1,P2,_]).
joaca_mai_bine(P1,P3,[P1,_,P3]).
joaca_mai_bine(P2,P3,[_,P2,P3]).
Fraza “Michel preferă baschetul şi joacă mai bine decât americanul” capătă forma regulii 2
4
regula(2,Prieteni):-
joaca_mai_bine(Prieten1,Prieten2,Prieteni),
Prieten1=prieten(michel,_,baschet),
Prieten2=prieten(_,sua,_).
iar “Israileanul Simon joacă mai bine decât tenismenul” se transformă în regula 3
regula(3,Prieteni):-
joaca_mai_bine(Prieten1,Prieten2,Prieteni),
Prieten1=prieten(simon,israel,_),
Prieten2=prieten(_,_,tenis).
Cheia “Jucătorul în crichet a ocupat primul loc” e redată de
regula(4,[Prieten1|_]):-
Prieten1=prieten(_,_,crichet).
Acum întrebarea “Cine este australian?” la rândul său include următoarele constrângeri
intrebare1(Nume,Prieteni):-
apartine(prieten(Nume,australia,_),Prieteni).
iar întrebarea “Ce sport practică Richard” presupune constrângerile
intrebare2(Sport,Prieteni):-
apartine(prieten(richard,_,Sport),Prieteni).
Aici pentru construirea întrebărilor s-a folosit cunoscutul predicat apartine/2.
Atunci predicatul care va determina numele australianului şi sportul practicat de Richard se
defineşte
solutie(Nume,Sport):-
regula(1,Prieteni),
regula(2,Prieteni),
regula(3,Prieteni),
regula(4,Prieteni),
intrebare1(Nume,Prieteni),
intrebare2(Sport,Prieteni).
activarea_regulilor(Ns,Prieteni).
5
Problema Analogy
Fig.5. A se raportă la B ca C la …
Schema generală
analogie(A,B,C,X,Raspunsuri):-
comparare(A,B,Regula),
comparare(C,X,Regula),
apartine(X,Raspunsuri).
Binarizarea constrângerilor
X
XY
YZ XY XZ
XZ
Y Z
YZ
Fig.4. Un sistem şi o reţea de constrângeri
Transformarea cu păstrarea variabilelor originale
[5,6] Z
Z=3lea(U)
U={(X,Y,Z),X+Y=Z} U [(1,4,5),(2,3,5),(2,4,6)]
X=1ul(U) Y=2lea(U)
X Y
[1,2] X<Y [3,4]
[Link]ă de satisfacere a constrângerilor
binară 6
Transformarea fără variabile originale
[Link]ă binară fără variabile originale
Tehnici consistente
revizuire/3, face un arc dat să fie consistent. În
Programul ce urmează, reprezentat de predicatul
predicatul revizuire/3 Xi şi Xj reprezintă nodurile, P indică predicatul de consistenţă asupra nodurilor
Xi şi Xj. Împreună ele reprezintă un arc al grafului de constrângeri. Lista de variabile, VarL, este lista
de perechi variabilă-domeniu, unde domeniul la rândul său este o listă de valori ce le poate primi
variabila asociată. Lista nouă de variabile este aceeaşi listă de variabile cu excepţia valorilor eliminate
din domenii.
%revizuire(+Arc,+ListaVariabile,-ListaVariabileNoua)
revizuire(arc(Xi,Xj,P),VarL,[vrbl(Xi,NouDiL)|RestVar]):-
eliminare_elem(vrbl(Xi,DiL),VarL,RestVar),
apartine(vrbl(Xj,DjL),RestVar),
verif_constr(DiL,DjL,P,NouDiL),!.
Predcatul verif_constr/4 elimină din domeniul D(Xi) acele valori care nu sunt în relaţia P cu
vre-o valoare din D(Xj). Rezultatul aste acumulat în argumentul al patrulea – domeniul nou pentru
variabila Xi.
%verif_constr(+Domeniul_i,+Domeniul_j,+Predicat,-Domeniul_iNou)
verif_constr([],_,_,[]).
verif_constr([Di|DiL],DjL,P,[Di|Di1L]):-
apartine(Dj,DjL),
constrangere(P,Di,Dj),
verif_constr(DiL,DjL,P,Di1L).
verif_constr([_|DiL],DjL,P,Di1L):-
verif_constr(DiL,DjL,P,Di1L).
Pentru colorarea unei hărţi, de exemplu, predicatul constrangere/3 are forma
constrangere(_,Di,Dj):-Di<>Dj.
Algoritmul AC1
%ac1(+ListaVariabile,+ListaArce,-ListaNouaVariabile)
7
ac1(VarL,ArcL,NouVarL):-!,
ac1sub(VarL,ArcL,ArcL,0,NouVarL).
ac1sub(VarL,_,[],0,VarL):-!.
ac1sub(VarL,InitArcL,[],1,NouVarL):-
ac1sub(VarL,InitArcL,InitArcL,0,NouVarL).
ac1sub(VarL,InitArcL,ArcL,Flag,NouVarL):-
eliminare_elem(arc(Xi,Xj,P),ArcL,NouArcL),
revizuire(arc(Xi,Xj,P),VarL,TempVarL1),
revizuire(arc(Xj,Xi,P),TempVarL1,TempVarL2),
detectare_schimbari(Flag,VarL,TempVarL2,Flag1),
ac1sub(TempVarL2,InitArcL,NouArcL,Flag1,NouVarL).
detectare_schimbari(_,VarL,TempVarL2,1):-
not(submultime(VarL,TempVarL2)),!.
detectare_schimbari(Flag,_,_,Flag).
Urmează rezultatul aplicării predicatului ac1/3 asupra problemei colorării hărţii de la începutul
capitolului.
?-ac1([vrbl(c,[galben,rosu,albastru]),
vrbl(a,[galben,rosu,albastru]),
vrbl(d,[galben,rosu,albastru]),
vrbl(b,[galben,rosu,albastru]),
vrbl(e,[galben,rosu,albastru])],
[arc(a,b,1),arc(a,c,1),arc(a,d,1),
arc(a,e,1),arc(b,c,1),arc(c,d,1),arc(d,e,1)],R)
R=[vrbl(e,[rosu,albastru]),vrbl(d,[rosu,albastru]),
vrbl(c,[rosu,albastru]),vrbl(b,[rosu,albastru]),
vrbl(a,[galben])],
Algoritmul AC3
ac3(VarL,ArcL,NouVarL):-!,
ac3sub(VarL,ArcL,ArcL,NouVarL).
ac3sub(VarL,_,[],VarL):-!.
ac3sub(VarL,InitArcL,ArcL,NouVarL):-
eliminare_elem(arc(Xi,Xj,P),ArcL,TempArcL),
revizuire(arc(Xi,Xj,P),VarL,TempVarL1),
revizuire(arc(Xj,Xi,P),TempVarL1,TempVarL2),
submultime(VarL,TempVarL2),!,
ac3sub(TempVarL2,InitArcL,TempArcL,NouVarL).
ac3sub(VarL,InitArcL,ArcL,NouVarL):-
eliminare_elem(arc(Xi,Xj,P),ArcL,TempArcL),
revizuire(arc(Xi,Xj,P),VarL,TempVarL1),
revizuire(arc(Xj,Xi,P),TempVarL1,TempVarL2),
findall(ARC,arc_suspect(Xi,Xj,InitArcL,ARC),ArceSuspecte),
uniunea(TempArcL,ArceSuspecte,UrmatoareArce),
ac3sub(TempVarL2,InitArcL,UrmatoareArce,NouVarL).
arc_suspect(Xi,Xj,InitArcL,arc(Xk,Xi,P)):-
apartine(arc(Xk,Xi,P),InitArcL),
8
Xk<>Xi,Xk<>Xj.
Propagarea constrângerilor
Tehnica verificarea înainte
Fig.4. Soluţia problemei celor 4 regine (verificarea înainte)
Tehnica verificare înainte pentru colorarea hărţii
%colorare4(+Graf,+Culori-Colorare)
colorare4(g(Ns,Ms),Culori,Colorare):-
instant(Ns,Culori,ColorateNs),
gtb(ColorateNs,Ms,[],Colorare),!.
% instant(+Noduri,+Culori,-SuperColorare)
instant([],_,[]).
instant([N|Ns],Culori,[d(N,Culori)|CNs]):-
instant(Ns,Culori,CNs).
% gtb(+SuperColorare,+Muchii,+PartialaColorare,-Colorare)
gtb([],_,Colorare,Colorare).
gtb([d(N,Cs)|Ns],Ms,Acc,Colorare):-
apartine(C,Cs), % selectare o culoare
ver_in(Ms,N,C,Ns,ConstranseNs),% verificare inainte
gtb(ConstranseNs,Ms,[N,C|Acc],Colorare).
% ver_in(+Muchii,+Nod,+NodCuloare,+InputSuperColorare,-OutputSuperColorare)
ver_in([],_,_,Ns,Ns).
ver_in([m(N1,N2)|Ms],N,C,Ns,ConstrNs):-
egal(N,N1),
constr(Ns,N2,C,NoiNs),
ver_in(Ms,N,C,NoiNs,ConstrNs).
ver_in([m(N1,N2)|Ms],N,C,Ns,ConstrNs):-
egal(N,N2),
constr(Ns,N1,C,NoiNs),
ver_in(Ms,N,C,NoiNs,ConstrNs).
ver_in([_|Ms],N,C,Ns,ConstrNs):-
9
egal(NoiNs,Ns),
ver_in(Ms,N,C,NoiNs,ConstrNs).
% constr(+InputSuperColorare,+Nod,+NodInterzisaCuloare,-OutputSuperColorare)
constr([d(N,Cs)|Ns],N,C,[d(N,NoiCs)|Ns]):-
eliminare(C,Cs,NoiCs),
not(egal(NoiCs,[])).
constr([d(N1,Cs)|Ns],N,C,[d(N1,Cs)|NoiNs]):-
not(egal(N,N1)),
constr(Ns,N,C,NoiNs).
constr([],_,_,[]).
Aici predicatul eliminere/3 are forma
eliminare(_,[],[]).
eliminare(X,[X|Xs],Xs).
eliminare(X,[Y|Ys],[Y|NouYs]:-
not(egal(X,Y)),
eliminare(X,Ys,NouYs).
adică el nu eşuează dacă elementul ce trebuie eliminat nu este în listă.
Tehnica anticiparea
Tehnica anticiparea (look ahead) combină tehnica verificarea înainte cu consistenţa arcelor.
Tehnica anticiparea taie unele ramuri ce duc spre eşec ale arborelui de căutare a soluţiei mai
înainte decât tehnica verificarea înainte. În fig.4 este reprezentat arborele de căutare pentru problema
celor 4 regine în cazul aplicării tehnicii de anticipare.
Fig.4. Soluţia problemei celor 4 regine (anticiparea)
Fig.5 arată constrângerile testate în tehnicile considerate mai sus.
10
11