【问题标题】:A combination of a list given a length followed by a permutation in Prolog?给定长度的列表后跟Prolog中的排列的组合?
【发布时间】:2018-12-07 11:43:52
【问题描述】:

我需要一个谓词来返回一个包含输入列表的所有组合的列表,并且列表结果大小在第二个参数中,谓词应该是这样的

permutInListN( +inputList, +lengthListResult, -ListResult), 

示例:

permutInListN([1,2,3],2,L).
? L=[1,2].
? L=[2,1].
? L=[1,3].
? L=[3,1].
? L=[2,3].
? L=[3,2].

列表中[1,2,3] 的组合L 与长度2。 没有重复可能使用偏移。

这是我的代码,但它根本不起作用,没有生成所有解决方案

permutInListN(_, 0, []).
permutInListN([X|Xs], N, [X|Ys]) :- N1 is N-1, permutInListN(Xs,N1,Ys).
permutInListN([_|Xs], N, Y) :- N>0, permutInListN(Xs,N,Y).

?permutInListN([1,2,3],2,L).
L = [1, 2]
L = [1, 3]
L = [2, 3]

提前致谢。

【问题讨论】:

  • 我的错,去掉了标志

标签: list prolog combinations permutation


【解决方案1】:

你想要的是一个组合,然后是一个排列。

组合:

comb(0,_,[]).

comb(N,[X|T],[X|Comb]) :-
    N>0,
    N1 is N-1,
    comb(N1,T,Comb).

comb(N,[_|T],Comb) :-
    N>0,
    comb(N,T,Comb).

例子:

?- comb(2,[1,2,3],List).
List = [1, 2] ;
List = [1, 3] ;
List = [2, 3] ;
false.

对于排列,只需在库列表中使用 SWI-Prolog permutation/2

:- use_module(library(lists)).

?- permutation([1,2],R).
R = [1, 2] ;
R = [2, 1] ;
false.

把它们放在一起

comb_perm(N,List,Result) :-
    comb(N,List,Comb),
    permutation(Comb,Result).

根据您的查询

?- comb_perm(2,[1,2,3],R).
R = [1, 2] ;
R = [2, 1] ;
R = [1, 3] ;
R = [3, 1] ;
R = [2, 3] ;
R = [3, 2] ;
false.

为你的谓词修改

permutInListN(List,N,Result) :-
    comb(N,List,Comb),
    permutation(Comb,Result).

例子

?- permutInListN([1,2,3],2,R).
R = [1, 2] ;
R = [2, 1] ;
R = [1, 3] ;
R = [3, 1] ;
R = [2, 3] ;
R = [3, 2] ;
false.

【讨论】:

  • SWI-Prolog 中的permutation/2 谓词是谓词,而不是内置谓词。
  • @PauloMoura 谢谢。
【解决方案2】:

排列结果

您的permutInListN/3 谓词基本上以有序 的方式从给定列表中获取N 元素,但所选择元素的顺序与原始顺序相同。

因此,我们可以通过查找所选元素的所有排列来对该列表进行后处理,例如:

permutInListN(L, N, R) :-
    takeN(L, N, S),
    permutation(S, R).

takeN/3 几乎等同于您定义的谓词:

takeN(_, 0, []).
takeN([X|Xs], N, [X|Ys]) :-
    N > 0,
    N1 is N-1,
    takeN(Xs,N1,Ys).
takeN([_|Xs], N, Y) :-
    N > 0,
    takeN(Xs,N,Y).

permutation/3 [swi-doc] 是来自lists library [swi-doc] 的谓词。

使用 N select/3s

我们也可以使用select/3 predicate [swi-doc] 来解决问题N 次。 select(X, L, R) 从列表中获取元素 X,而 R 是一个列表,没有该元素。因此,我们可以递归地传递列表并每次删除一个元素,直到我们删除 N 元素,例如:

permutInListN(_, 0, []).
permutInListN(L, N, [X|T]) :-
    N > 0,
    N1 is N-1,
    select(X, L, R),
    permutInListN(R, N1, T).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多