Salta ai contenuti. | Salta alla navigazione

Strumenti personali

CLP 27 lug 2009

Applicazioni di Intelligenza Artificiale - CLP

Prof. Marco Gavanelli

27 Luglio 2009

Esercizio (6 punti)

Dato un numero intero N, è possibile costruire N quadrati, di dimensione 1×1, 2×2, ... N ×N. Si costruisca un programma CLP che, dato un numero N e due dimensioni X e Y, dice se è possibile inserire i quadrati 1×1, 2×2, ... N ×N all'interno di un rettangolo X ×Y senza che i quadrati si sovrappongano vicendevolmente.

Facoltativo (2 punti)

Si trovi il rettangolo di area minima che contiene gli N quadrati senza che si sovrappongano.

 

 

 


 

Soluzione

Vedi anche la discussione su questo esercizio nelle FAQ.

 


:- lib(fd).

rett(X,Y,Lx,Ly,N):-
    length(Lx,N),
    length(Ly,N),
    numeri(Dim,1,N), % Costruisco la lista [1,2,3,...,N]
% Prendo una dimensione sufficientemente grande per il rettangolo contenitore
% Se metto in fila tutti i quadrati, ho una larghezza totale di 1+2+3+...+N=N*(N+1)/2
% 'fix' e` per portare tutto in virgola fissa
% Non e` indispensabile usare questo calcolo: andava bene qualunque dimensione
% abbastanza grande, anche un numero predefinito
    N2 is fix(N*(N+1)/2),
    [X|Lx]::0..N2,
    [Y|Ly]::0..N2,
    no_overlap(Lx,Ly,Dim,Dim),
    max_dim(Lx,Dim,X), % Tutti i quadrati stanno entro la X
    max_dim(Ly,Dim,Y), % Tutti i quadrati stanno entro la Y
    Area #= X*Y, % Area del rettangolo contenitore
    flatten([X,Y,Lx,Ly],All),
    min_max(labeling(All),Area).

max_dim([],[],_).
max_dim([X1|Lx],[D|Ld],Max):-
    X1+D #=< Max,
    max_dim(Lx,Ld,Max).

numeri([N],N,N):-!.
numeri([N|T],N,M):-
    N1 is N+1,
    numeri(T,N1,M).

% Impone che i quadrati non si sovrappongano a due a due
no_overlap([],[],[],[]).
no_overlap([X|Lx],[Y|Ly],[W|Lw],[H|Lh]):-
    no_overlap_loop(X,Y,W,H,Lx,Ly,Lw,Lh),
    no_overlap(Lx,Ly,Lw,Lh).

no_overlap_loop(_,_,_,_,[],[],[],[]).
no_overlap_loop(X1,Y1,W1,H1,[X2|Lx],[Y2|Ly],[W2|Lw],[H2|Lh]):-
    X1+W1 #=< X2 #\/ % il primo quadrato e` a sinistra del secondo
    X2+W2 #=< X1 #\/ % il primo quadrato e` a destra del secondo
    Y1+H1 #=< Y2 #\/ % il primo quadrato e` sopra il secondo
    Y2+H2 #=< Y1,    % il primo quadrato e` sotto il secondo
    no_overlap_loop(X1,Y1,W1,H1,Lx,Ly,Lw,Lh).