我有一个程序可以生成列表的所有排列,其中每个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上进行一些更改,但是我不知道确切在哪里。
谢谢。
答案 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,以便及早过滤无效配置。