用簡單的方式是生成和測試:在這裏,你讓Prolog的生成置換,但只有在滿足特定條件時才接受。例如:
dif3([_]).
dif3([A,B|T]) :-
D is abs(A-B),
D =< 3,
dif3([B|T]).
,然後定義:
perm3(L,R) :-
perm(L,R),
dif3(R).
這種方法不是很有效:它可以是用於置換的指數數量,只有少數是有效的情況下,這會意味着大量的計算工作。例如,如果元素列表是[2,5,7,9]
,它將生成從[2,9,...]
開始的所有排列,而更智能的方法已經可以看出,永遠不會生成有效的解決方案。
其他更智能的方法是交錯生成並測試。在這裏,您只選擇takeout3/4
這些有效的候選人號碼。您可以定義一個謂詞takeout3(L,P,X,T).
其中L
是最初的名單,P
對上號,X
所選號碼與T
結果列表:
takeout3([X|T],P,X,T) :-
D is abs(X-P),
D =< 3.
takeout3([H|L],N,X,[H|T]) :-
takeout3(L,N,X,T).
現在我們就可以生成排列如下:
perm3([],[]).
perm3(L,[E|T]) :-
takeout(L,E,R),
perm3(R,E,T).
perm3([],_,[]).
perm3(L,O,[E|T]) :-
takeout3(L,O,E,R),
perm3(R,E,T).
注意我們使用perm3
的兩個版本:perm3/2
和perm3/3
,第一個用於生成第一個元素(使用舊的takeout/3
),perm3/3
用於生成使用takeout3/4
的其餘排列組合。
這種方法的完整的源代碼是:
takeout([X|T],X,T).
takeout([H|L],X,[H|T]) :-
takeout(L,X,T).
takeout3([X|T],P,X,T) :-
D is abs(X-P),
D =< 3.
takeout3([H|L],N,X,[H|T]) :-
takeout3(L,N,X,T).
perm3([],[]).
perm3(L,[E|T]) :-
takeout(L,E,R),
perm3(R,E,T).
perm3([],_,[]).
perm3(L,O,[E|T]) :-
takeout3(L,O,E,R),
perm3(R,E,T).
與swipl
運行它給:
?- perm3([2,7,5],L).
L = [2, 5, 7] ;
L = [7, 5, 2] ;
false.
預期的行爲。
你能解釋一下你的'perm'的作品,因爲你把它相當困難。有更直接的方法來做到這一點... –