从列表[n,k]中,我想返回一组从1到k的所有可能列表,以便所有列表的长度为n。
示例:列表[2,4]
应返回:
[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
答案 0 :(得分:3)
n_k_lists(N, K, Ls) :-
findall(L, ( length(L, N), maplist(between(1,K), L), ascending(L) ), Ls).
ascending([]).
ascending([E|Es]) :-
ascending_(Es, E).
ascending_([], _E).
ascending_([E|Es], F) :-
E > F,
ascending_(Es, F).
元素应该是升序只是你的例子的间接推论。使用library(clpfd)
这个例子会更好。
(我不是findall/3
的忠实粉丝,但在这种情况下,这很好。)
答案 1 :(得分:2)
你也可以使用有限域,@ false" s"升序"谓语。在GNU Prolog中,它将是:
nk_lists(N, K, Ls) :- findall(L, nk_list(N, K, L), Ls).
nk_list(N, K, L) :-
length(L, N),
fd_domain(L, 1, K),
ascending(L),
fd_labeling(L).
% @false's ascending...
ascending([]).
ascending([E|Es]) :-
ascending_(Es, E).
ascending_([], _E).
ascending_([E|Es], F) :-
E #> F,
ascending_(Es, F).
如果需要的话,我将把它作为练习转录成SWI Prolog有限域谓词。
答案 2 :(得分:0)
这是一些有效的代码。我不确定它是否非常有效,但它能完成这项工作。要以列表形式获得答案,您需要致电findall/3
findall(Z,list_combo([2,4],Z),X).
list_combo([0,_],[]).
list_combo([X,Y],L) :-
length(L,X),
L=[A|As],
n_ups(Y,Ints), &the numbers for our permutations
member(A,Ints),
not_member(As,A), &each element must be unique
Length is X-1,
list_combo([Length,Y],As),
ordered(L). &must be in ascending order
n_ups(N, Xs) :-
length(Xs, N),
numbered_from(Xs, 1).
numbered_from([], _).
numbered_from([I0|Is], I0) :-
I1 is I0+1,
numbered_from(Is, I1).
not_member([], _).
not_member([N|Ns], M) :-
dif(N, M),
not_member(Ns, M).
ordered([_|[]]).
ordered([X,Y|Ys]) :-
ordered([Y|Ys]),
X =< Y.