Salta ai contenuti. | Salta alla navigazione

Strumenti personali

CLP 2 apr 2009

Applicazioni di Intelligenza Artificiale - CLP

Dott. Ric. Marco Gavanelli

2 Aprile 2009

Esercizio (8 punti)

Un neonato deve mangiare 10 volte al giorno, ad intervalli di 3 ore al massimo, comprese le ore della notte (anche quelle a cavallo della mezzanotte). Il papà e la mamma hanno deciso di dividersi il compito di dare le poppate al figlio (5 il papà e 5 la mamma), in modo che ciascuno di loro abbia un intervallo di ore in cui riesce a dormire che sia il più lungo possibile.

Si scriva un programma CLP che stabilisce gli orari in cui il bambino riceverà le poppate. Si consideri come funzione obiettivo da massimizzare il numero di ore in cui riesce a dormire il genitore che dorme di meno fra i due.

Ad esempio, se la mamma dà le poppate delle ore 0, 4, 10, 14, 20, vuol dire che riuscirà a dormire 6 ore (dalle 4 alle 10). Se il papà dà le poppate delle 3, 7, 12, 17, 23, vuol dire che ha a disposizione 5 ore di sonno consecutive (ad esempio, dalle 12 alle 17). Il valore della funzione obiettivo è 5, in quanto il genitore che ha meno ore di sonno consecutive è il papà, che dorme 5 ore di seguito.


 

 

 

Soluzione


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

poppate(Mamma,Papa):-
    length(Papa,5), % Poppate date dal papa`
    length(Mamma,5),% Poppate date dalla mamma
    append(Papa,Mamma,L),
    L :: 0..23,     % Definizione domini
    ordered(<,Mamma),   % Impongo che le poppate date 
    % dalla mamma siano ordinate, in quanto non mi 
    % interessano le soluzioni simmetriche
    ordered(<,Papa),
    % Ordinate e` la lista totale delle poppate ordinata
    sorted(L,Ordinate), 
    Ordinate = [Prima|_],
    GiornoDopo #= Prima+24, 
    % Il giorno dopo si deve continuare con lo stesso schema  
    % quindi aggiungo una variabile che rappresenta la prima 
    % poppata del giorno dopo
    append(Ordinate,[GiornoDopo],Tutte),
    max_3ore(Tutte), % Impongo che il bambino mangi ogni 3 ore
    % Calcolo gli intervalli in cui la mamma puo` dormire
    intervalli(Mamma,IntMamma), 
    intervalli(Papa,IntPapa),
    % Trovo l'intervallo massimo in cui dorme la mamma
    maxlist(IntMamma,OreSonnoMamma),
    maxlist(IntPapa,OreSonnoPapa),
    % Calcolo quale dei due genitori dorme di meno
    minlist([OreSonnoMamma,OreSonnoPapa],Fneg), 
    % Inverto la funzione obiettivo perche' ECLiPSe permette 
    % solo di minimizzare ed io devo invece massimizzare
    Fneg+F #= 0, 
    min_max(labeling(L),F).

my_labeling([]).
my_labeling([H|T]):- indomain(H), my_labeling(T).

max_3ore([_]).
max_3ore([A,B|T]):-
    B-A #=< 3,
    max_3ore([B|T]).

intervalli(L,Lint):-
    L= [Prima|_],
    Ultima #= Prima+24,
    append(L,[Ultima],Tot),
    intervalli_tot(Tot,Lint).

intervalli_tot([_],[]).
intervalli_tot([A,B|T],[I|TI]):-
    I #= B-A,
    intervalli_tot([B|T],TI).