具有多个元素条件的序言排列

时间:2018-11-11 19:19:54

标签: prolog permutation

我有一个程序可以生成列表的所有排列,其中每个2<=i<=n都有一个1<=j<i,其中|v(i)-v(j)|=1

例如,对于[1,2,3],结果为:

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

[1,3,2][3,1,2]是错误的,因为|3-1||1-3|不是1

代码是:

takeout([X|T],X,T).
takeout([H|L],X,[H|T]) :-
    takeout(L,X,T).

takeout1([X|T],P,X,T) :-
    D is abs(X-P),
    D =:= 1.
takeout1([H|L],N,X,[H|T]) :-
    takeout1(L,N,X,T).

perm1([],[]).
perm1(L,[E|T]) :-
    takeout(L,E,R),
    perm_abs(R,E,T).

perm_abs([],_,[]).
perm_abs(L,O,[E|T]) :-
    takeout1(L,O,E,R),
    perm_abs(R,E,T).

perm(N,R):-
    numlist(1,N,L),
    perm1(L,R).

此代码仅给出连续的结果。我想我应该在takeout1上进行一些更改,但是我不知道确切在哪里。

谢谢。

1 个答案:

答案 0 :(得分:1)

valid(R) :-
    forall((nth1(I,R,X), I>1), (nth1(J,R,Y), J<I, 1 =:= abs(X-Y))).

?- forall((N=4, numlist(1,N,L), permutation(L,R), valid(R)),writeln(R)).
[1,2,3,4]
[2,1,3,4]
[2,3,1,4]
[2,3,4,1]
[3,2,1,4]
[3,2,4,1]
[3,4,2,1]
[4,3,2,1]
true.

您可以在中间排列步骤之后添加有效/ 1,以便及早过滤无效配置。