我有一个学校要做的作业,如下: 安妮(Anne)和米歇尔(Michel)是与一群人一起组织晚餐的人 夫妻。它们必须面对面地放在桌子上。
男人也必须与女人交往,已婚人士不能 邻居,对于不相容的人也是如此。最后,邻居们 必须分享至少一项嗜好。
我的解决方案似乎有效,但是我有两个问题: 首先,当我使用“ go”生成解决方案时。然后按“;”,我收到了太多的解决方案(似乎要绕圈...)。其次,当我删除一对夫妇(在注释部分中)时,解决方案在很长一段时间后出现了……我看不到任何有关这些行为的解释,但是我两个月前才发现Prolog。任何帮助将不胜感激。
:- use_module(library(clpfd)).
% ---------------------------------------------------------------------- %
% %
% MAIN PREDICATE %
% %
% ---------------------------------------------------------------------- %
go :- Guests = [ manon, alice, juliette, lucie, charlotte, olivia, margaux,
jules, hugo, tom, louis, paul, jean, antoine ],
%go :- Guests = [ alice, juliette, lucie, charlotte, olivia, margaux,
% hugo, tom, louis, paul, jean, antoine ],
produce_table(Guests).
produce_table(Guests) :-
length([anne, michel|Guests],Nb),
produce_assoc_list([anne, michel|Guests],La,Nb),
reduce_domain(La,Nb),
different_places(La),
label_places(La),
sort(2,@<,La,La_trie),
print_table(La_trie).
% ---------------------------------------------------------------------- %
% %
% ASSOCIATIVE LIST %
% %
% ---------------------------------------------------------------------- %
produce_assoc_list([],[],_) :- !.
produce_assoc_list([N|L],[pers(N,P)|La],Nb) :-
P in 1..Nb,
( N == anne -> P#=1
; true),
( N == michel -> P*2 #>= Nb, P*2 #=< Nb+2
; true),
produce_assoc_list(L,La,Nb).
% ---------------------------------------------------------------------- %
% %
% CONSTRAINTS %
% %
% ---------------------------------------------------------------------- %
reduce_domain_aux(_,[],_) :- !.
reduce_domain_aux(pers(N1,P1),[pers(N2,P2)|T],Nb) :-
gender(N1,S1),gender(N2,S2),
( S1==S2 -> separate_neighbors(P1,P2,Nb)
; true),
hobby(N1,H1),hobby(N2,H2),
intersection(H1,H2,I),
( I==[] -> separate_neighbors(P1,P2,Nb)
; true),
( married(N1,N2) -> separate_neighbors(P1,P2,Nb)
; true),
( incompatibles(N1,N2) -> separate_neighbors(P1,P2,Nb)
; true),
reduce_domain_aux(pers(N1,P1),T,Nb).
reduce_domain([],_) :- !.
reduce_domain([H|T],Nb) :-
reduce_domain_aux(H,T,Nb),
reduce_domain(T,Nb).
% Persons at different places
% ----------------------------------
vars_list([],[]) :- !.
vars_list([pers(_,P)|T],[P|L]) :-
vars_list(T,L).
different_places(Lp) :-
vars_list(Lp,Lv),
all_distinct(Lv).
% ---------------------------------------------------------------------- %
% %
% LABELING %
% %
% ---------------------------------------------------------------------- %
label_places(Lp) :-
vars_list(Lp,Lv),
label(Lv).
% ---------------------------------------------------------------------- %
% %
% USEFULL PREDICATES %
% %
% ---------------------------------------------------------------------- %
married(X,Y) :-
spouses(X,Y);spouses(Y,X), !.
incompatibles(X,Y) :-
incompatible(X,Y); incompatible(Y,X), !.
separate_neighbors(P1,P2,Nb) :-
P1 #\= (P2+1) mod Nb,
P1 #\= (P2-1) mod Nb.
% ---------------------------------------------------------------------- %
% %
% PRINT RESULTS %
% %
% ---------------------------------------------------------------------- %
print_table([]) :- !, nl.
print_table([pers(N,P)|T]) :-
nl, format('~w ~d ~w ~a ',['Place ',P, ' :', N]),
print_table(T).
% ---------------------------------------------------------------------- %
% %
% DATABASE %
% %
% ---------------------------------------------------------------------- %
spouses(anne,michel).
spouses(manon,jules).
spouses(alice,hugo).
spouses(juliette,tom).
spouses(lucie,louis).
spouses(charlotte,paul).
spouses(olivia,jean).
spouses(margaux,antoine).
gender(anne,f).
gender(manon,f).
gender(alice,f).
gender(juliette,f).
gender(lucie,f).
gender(charlotte,f).
gender(olivia,f).
gender(margaux,f).
gender(michel,m).
gender(jules,m).
gender(hugo,m).
gender(tom,m).
gender(louis,m).
gender(paul,m).
gender(jean,m).
gender(antoine,m).
hobby(anne,[sport,jardinage,voyages]).
hobby(manon,[jardinage,voyages]).
hobby(alice,[jardinage,voyages]).
hobby(juliette,[sport,voyages]).
hobby(lucie,[jardinage]).
hobby(charlotte,[jardinage]).
hobby(olivia,[sport,jardinage]).
hobby(margaux,[sport]).
hobby(michel,[sport,jardinage,voyages]).
hobby(jules,[sport,jardinage]).
hobby(hugo,[sport,jardinage]).
hobby(tom,[sport,voyages]).
hobby(louis,[sport,jardinage]).
hobby(paul,[sport]).
hobby(jean,[sport,jardinage]).
hobby(antoine,[sport,jardinage]).
incompatible(manon,louis).
incompatible(charlotte,antoine).
incompatible(margaux,hugo).