以Kayles的遊戲爲例,我們的應用程序建議一個經濟的狀態表示將是一個有序整數的有序列表,每個數字代表一串連續的瓶子。
我說的是有序的,因爲遊戲的狀態在這些值的任何排列下是等價的。
可能的舉動因此將包括選擇一個條目並將其減少一到兩個零個,一個或兩個較小的條目。這些較小的條目(如果有的話)應該插入遊戲狀態列表的新「尾部」中的適當位置。
遊戲移動的更大表示的一個構建塊是決定連續的一串X瓶可以減少多少種方式。因此,我們可以與要求入手:
bowls(X,[ ]) :-
(0 is X - 1 ; 0 is X-2).
bowls(X,[W]) :-
(W is X - 1 ; W is X-2),
W > 0.
bowls(X,[Y,Z]) :-
(W is X - 1 ; W is X-2),
W > 1,
bowlsplits(W,Y,Z).
它留給讀者來實現bowlsplits/3以這樣一種方式,它生產的所有可能性,Y + Z = W
與Y >= Z > 0
。
請注意,對於這樣的表示,我們應該跳過任何等於列表中以下條目的條目來避免重複結果,因爲兩個相同的條目會產生相同的可能結果。
kayles([X],R) :- bowls(X,R).
kayles([X,Y|T],R) :-
X > Y,
bowls(X,L),
inSort(L,[Y|T],R).
kayles([X,X|T],[X|L]) :-
kayles([X|T],L).
它也留給讀者來實現inSort/3沿插入的是融合在其前兩個參數的有序列表爲有序列表結合第三個參數的行排序。
請注意,kayles/2是尾遞歸但非確定性。
這些不是排列組合,所以請不要給他們打電話。 – 2011-03-05 17:16:42
他們有正確的名詞嗎? (變化/子列表?) – dig412 2011-03-05 17:24:08
從您的描述來看,子列表似乎是一個更合適的術語。 – 2011-03-05 17:40:40