CSI2520, Hiver 2007
Arbres en Prolog
• Un arbre binaire est une structure pouvant contenir des données. Chaque élément de l'arbre contient une donnée et a au plus un 'parent' et deux 'enfants'.
1 / \ 2 3
/ \ / \ 4 5 6 7
CSI2520, Hiver 2007
Arbres en Prolog
On peut representer les arbres avec une structure t(elem, gauche, droit)
ou 'elem' est la valeur de la racine, et gauche et droit sont les sous-arbres à gauche/droite de la racine. Un arbre vide sera represente par 'nil'. Ainsi, un arbre à un seul élément 1: t(1,nil,nil):
1 / \ 2 3 t(1,t(2,nil,nil),t(3,nil,nil)).
CSI2520, Hiver 2007
Un arbre binaire
CSI2520, Hiver 2007
Parcours inordre
printInfo(nul).printInfo(t(RootInfo,LeftSubtr,RightSubtr)) :- printInfo(LeftSubtr), write(RootInfo), write(' '), printInfo(RightSubtr).
?- printInfo(t(73, t(31, t(5, nul, nul), nul), t(101, t(83, nul, t(97, nul, nul)), nul))).5 31 73 83 97 101Yes
CSI2520, Hiver 2007
Recherche dans un arbre
search(Info, t(Info, _, _)).search(Info, t(RootInfo, Left, _Right)) :-
precedes(Info, RootInfo),search(Info, Left).
search(Info, t(RootInfo, _Left, Right)) :-precedes(RootInfo, Info),search(Info, Right).
precedes(Info1, Info2) :- Info1 < Info2 .
CSI2520, Hiver 2007
Insertion dans un arbre
insert(Info, nul, t(Info, nul, nul)).insert(Info, t(RootInfo, Left, Right), t(RootInfo, LeftPlus, Right)) :- precedes(Info, RootInfo), insert(Info, Left, LeftPlus).insert(Info, t(RootInfo, Left, Right), t(RootInfo, Left, RightPlus)) :- precedes(RootInfo, Info), insert(Info, Right, RightPlus).
CSI2520, Hiver 2007
Retrait à la racine d’un arbre
delete(Info, t(Info, nul, Right), Right).delete(Info, t(Info, Left, nul), Left).delete(Info, t(Info, Left, Right), t(NewRoot, NewLeft, Right)) :- removeMax(Left, NewLeft, NewRoot).
% removeMax(Tree,NewTree,Max)
CSI2520, Hiver 2007
Retrait dans un arbre
delete(Info, t(RootInfo, Left, Right), t(RootInfo, LeftSmaller, Right)) :- precedes(Info, RootInfo), delete(Info, Left, LeftSmaller).delete(Info, t(RootInfo, Left, Right), t(RootInfo, Left, RightSmaller)) :- precedes(RootInfo, Info), delete(Info, Right, RightSmaller).
CSI2520, Hiver 2007
Retrait du max élément
removeMax(t(Max, Left, nul), Left, Max).removeMax(t(Root, Left, Right), t(Root, Left, RightSmaller), Max) :- removeMax(Right, RightSmaller, Max).
Recherche en profondeur
CSI2520, Hiver 2007
resoudre(N,[N]) :- but(N).resoudre(N,[N | Solution]) :- successeur(N,Nsuivant), resoudre(Nsuivant,Solution).
Il faut donc définir le but et définir les noeuds successeurs.
Les tours de Hanoi
CSI2520, Hiver 2007
État initial: [A,B,C] = [[1,2,3],[],[]]
but([[],[],_]).
Les tours de Hanoi (mouvements)
CSI2520, Hiver 2007
legal(_,[]).legal(D1,[D2|_]):- D1<D2.successeur([[T|L1],L2,L3],[L1,[T|L2],L3]) :- legal(T,L2). successeur([[T|L1],L2,L3],[L1,L2,[T|L3]]) :- legal(T,L3). successeur([L1,[T|L2],L3],[[T|L1],L2,L3]) :- legal(T,L1). successeur([L1,[T|L2],L3],[L1,L2,[T|L3]]) :- legal(T,L3).successeur([L1,L2,[T|L3]],[[T|L1],L2,L3]) :- legal(T,L1). successeur([L1,L2,[T|L3]],[L1,[T|L2],L3]) :- legal(T,L2).
Les tours de Hanoi (version 1)
CSI2520, Hiver 2007
but([[],[],_]).resoudre(E,[E]) :- but(E). resoudre(E,[E|Solution]) :- successeur(E,Esuivant), resoudre(Esuivant,Solution).
?!
Les tours de Hanoi (version 2)
CSI2520, Hiver 2007
resoudre(Noeud,Solution) :- profondeur([], Noeud,Solution).profondeur(Chemin, Noeud,[Noeud | Chemin]) :- but(Noeud).profondeur(Chemin, Noeud,Sol) :- successeur(Chemin, Noeud1), \+member(Chemin1,Path), profondeur([Chemin | Path], Chemin1, Sol).
Les tours de Hanoi (version 3)
CSI2520, Hiver 2007
resoudre(E,[E],Pmax) :- but(E). resoudre(E,[E|Solution],Pmax) :- Pmax>0, successeur(E,Esuivant), Pmax1 is Pmax-1, resoudre(Esuivant,Solution,Pmax1), write(Esuivant), nl.
Recherche en largeur
CSI2520, Hiver 2007
resoudre(Racine, Solution):- largeur ([[Racine]],Solution).% largeur(liste de chemin, solution)largeur([[Noeud | Chemin] | _],[Noeud | Chemin]):- but(Noeud).largeur([Chemin | Chemins], Solution):- etendre(Chemin,NChemins), conc(Chemins,NChemins,Chemins1), largeur(Chemins1,Solution).etendre([Noeud | Chemin],NChemins):- bagof([NNoeud,Noeud | Chemin], (successeur(Noeud,NNoeud), \+member(NNoeud,[Noeud | Chemin])), NChemins), !.etendre(Chemin,[]).
Les tours de Hanoi (version 4)
CSI2520, Hiver 2007
?- successeur([[1,2,3],[],[]],S).S = [[2, 3], [1], []] ;S = [[2, 3], [], [1]] ;
?- etendre([[[1,2,3],[],[]]],S).S = [[[[2, 3], [1], []], [[1, 2, 3], [], []]], [[[2, 3], [], [1]], [[1, 2, 3], [], []]]].
Les tours de Hanoi (version 4)
CSI2520, Hiver 2007
resoudre(Racine, Solution):- largeur([[Racine]],Solution), voir(Solution).voir([]).voir([Noeud|Chemin]) :- voir(Chemin), nl, write(Noeud). .
?- resoudre([[1,2,3],[],[]],S).[[1,2,3],[],[]][[2,3],[],[1]][[3],[2],[1]][[3],[1,2],[]][[],[1,2],[3]][[1],[2],[3]][[1],[],[2,3]][[],[],[1,2,3]]
Les graphes
CSI2520, Hiver 2007
Représentation: g([Noeud, ...],[arc(Noeud1,Noeud2,Valeur), ...]).
arc(g(Ns,Arcs),N1,N2,Valeur):- member(arc(N1,N2,Valeur),Arcs).
% pour un graphe non-dirigéarc(g(Ns,Arcs),N1,N2,Valeur):- member(arc(N1,N2,Valeur),Arcs); member(arc(N2,N1,Valeur),Arcs).
Voisins dans un graphe
CSI2520, Hiver 2007
voisins(Graphe,Noeud,Voisins):- setof((N,Arc),arc(Graphe,Noeud,N,Arc),Voisins).
?- voisins(g([a,b,c,d,e,f], [arc(a,b,3),arc(a,c,5),arc(a,d,7),arc(e,f,1),arc(d,f,6)]),c,V).V = [ (a, 5)].
?- voisins(g([a,b,c,d,e,f], [arc(a,b,3),arc(a,c,5),arc(a,d,7),arc(e,f,1),arc(d,f,6)]),a,V).V = [ (b, 3), (c, 5), (d, 7)].
Coloriage de graphe
CSI2520, Hiver 2007
coloriage(g(Ns,Arcs),Couleurs,Coloriage):- genere(Ns,Couleurs,Coloriage), test(Arcs,Coloriage).genere([],_,[]).genere([N|Ns],Couleurs,[(N,C)|Q]):- member(C,Couleurs), genere(Ns,Couleurs,Q).test([],_).test([arc(N1,N2,_)|Ns],Coloriage):- member((N1,C1),Coloriage), member((N2,C2),Coloriage), C1\=C2, test(Ns,Coloriage).
Coloriage de graphe
CSI2520, Hiver 2007
?- coloriage(g([a,b,c,d,e,f], [arc(a,b,3),arc(a,c,5),arc(a,d,7),arc(e,f,1),arc(d,f,6)]), [rouge,bleu,blanc,vert],V).V = [ (a, rouge), (b, bleu), (c, bleu), (d, bleu), (e, rouge), (f, blanc)] ;V = [ (a, rouge), (b, bleu), (c, bleu), (d, bleu), (e, rouge), (f, vert)] ;V = [ (a, rouge), (b, bleu), (c, bleu), (d, bleu), (e, bleu), (f, rouge)];
…
Labyrinthe
CSI2520, Hiver 2007
connecte(0,1). % depart = 0connecte(1,2).connecte(2,6).connecte(6,5).connecte(6,7).connecte(5,4).connecte(5,9).connecte(9,8).connecte(8,12).connecte(9,10).connecte(10,11).connecte(9,13).connecte(13,14).connecte(14,15). %fin = 15
0 1 2 3 4 5 6 7 8 9 10 1112 13 14 15
Labyrinthe
CSI2520, Hiver 2007
successeur(A,B):-connecte(A,B).successeur(A,B):-connecte(B,A).but(15).
resoudre([Fin|Chemin],[Fin|Chemin]):-but(Fin).resoudre([Courant|Chemin],Solution):- successeur(Courant,Suivant), \+member(Suivant,Chemin),write(Suivant),nl, resoudre([Suivant,Courant|Chemin],Solution).
Labyrinthe
CSI2520, Hiver 2007
?- resoudre([0],S).126598121011131415S = [15, 14, 13, 9, 5, 6, 2, 1, 0] ;74false.
Top Related