Salta ai contenuti. | Salta alla navigazione

Strumenti personali

CLP 19 giu 2009

Applicazioni di Intelligenza Artificiale - CLP

Prof. Marco Gavanelli

19 giugno 2009

Esercizio (8 punti)

Sia dato un file graph.pl che contiene la rappresentazione di un grafo non orientato. Per ogni nodo del grafo è presente un fatto  node(N) e per ogni arco che connette i nodi I e J è presente un fatto edge(I,J), dove I < J.

Una clique è un sottoinsieme dei nodi del grafo in cui il grafo indotto è completo, cioè ogni coppia di nodi nella clique è connessa da un arco. 
Quindi per ogni coppia di nodi (I,J) appartenente alla clique, l'arco (I,J) deve appartenere al grafo.

Si scriva un programma CLP che calcola la clique di dimensione massima (ovvero contenente il massimo numero di nodi) del grafo dato.

 


Soluzione


:- lib(fd).
:- lib(fd_global).

:- [graph].

clique(L,Dim):-
    % Trovo il numero dei nodi N
    findall(Node,node(Node),Lnodes),
    length(Lnodes,N),
    % Costruisco la lista di variabili
    % Ogni nodo puo` entrare o no nella clique
    length(L,N),
    L::0..1,
    vincolo(L,1),
    sumlist(L,Dim),
    F #= -Dim,
    minimize(labeling(L),F).

% vincolo(L,Start)
% Impongo che gli elementi della lista L formino una clique,
% sapendo che il primo nodo della lista ha indice Start
vincolo([],_).
vincolo([X|L],N):-
    N1 is N+1,
    vincolo_loop(X,L,N,N1),
    vincolo(L,N1).

% vincolo_loop(X,L,Ix,M)
% Impone il vincolo di clique fra l'elemento X e gli elementi della lista L
% sapendo che Ix e` l'indice dell'elemento X
% ed Iy e` l'indice dell'elemento Y
vincolo_loop(_,[],_,_).
vincolo_loop(X,[_|T],Ix,Iy):-
% Se c'e` un arco, allora posso prendere entrambi i nodi X e Y nella clique
% quindi non impongo vincoli
    edge(Ix,Iy),!,
    M is Iy+1,
    vincolo_loop(X,T,Ix,M).
vincolo_loop(X,[Y|T],Ix,Iy):-
% Se non c'e` un arco, solo uno dei due nodi X e Y puo` essere nella clique
    X+Y #< 2,
    M is Iy+1,
    vincolo_loop(X,T,Ix,M).