我正在使用clpfd,并且我有5个变量,如何确保这5个变量中的最多3个相同?
例如:
1,1,1,2,2->允许
1,1,1,2,3->允许
1,1,1,1,4->不允许
...
我认为它会像这样工作:
number(N1),
number(N2),
number(N3),
number(N4),
number(N5),
((N1 #= N2 #/\ N1 #= N3) #==> (N1 #\= N4 #/\ N1 #\= N5)) #\/ ((N1 #= N2 #/\ N1 #= N4) #==> (N1 #\= N3 #/\ N1 #\= N5)) #\/ ...
但是这个解决方案似乎太长了,我想知道是否可以用更少的代码来解决它。
答案 0 :(得分:0)
你去了!
代码:
:-use_module(library(clpfd)).
check([H1,H2,H3,H4]):- #\(H1#=H2#/\H2#=H3#/\H3#=H4),!.
check([H1,H2,H3,H4|T]):- #\(H1#=H2#/\H2#=H3#/\H3#=H4),check([H2,H3,H4|T]).
count_frequencies([],_,LIST,LIST).
count_frequencies([HEAD|TAIL],PREVIOUS,INIT,LIST):-
HEAD\=PREVIOUS,
count_frequencies(TAIL,HEAD,[HEAD-1|INIT],LIST).
count_frequencies([HEAD|TAIL],HEAD,[HEAD-F|T],LIST):-
F2 is F+1,
count_frequencies(TAIL,HEAD,[HEAD-F2|T],LIST).
max_frequency_is_3(NUMBERS,DOMAIN,RESULT):-
length(LIST,NUMBERS),
LIST ins DOMAIN,
chain(LIST,#=<),
check(LIST),
label(LIST),
count_frequencies(LIST,false,[],LIST2),
length(RESULT,NUMBERS),
global_cardinality(RESULT,LIST2),
label(RESULT).
示例查询:
?- max_frequency_is_3(5,1..5,LIST).
结果:
L = [1, 1, 1, 2, 2] ;
L = [1, 1, 2, 1, 2] ;
L = [1, 1, 2, 2, 1] ;
L = [1, 2, 1, 1, 2] ;
L = [1, 2, 1, 2, 1] ;
...
max_frequency_is_3 / 3的参数是..
数字:您拥有的数字数量-在您的情况下为5
DOMAIN:您的数字所取值的域(例如1..10、3..7等)
结果:返回列表/输出。