从给定的列表(例如[2,4]),我想得到[[1,2],[1,3],[1,4] ...]

时间:2015-06-24 09:36:23

标签: prolog

从列表[n,k]中,我想返回一组从1到k的所有可能列表,以便所有列表的长度为n。

示例:列表[2,4]应返回:

[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]

3 个答案:

答案 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.