我试图使用回溯来实现探索算法。目的是找到可能被称为“链条”的链条。使用两个规则的单词:
[a,b,b,a,b]
我们需要[a,_,_,b,_]
[a,c,c,c,b]
我们会[a,_,_,_,b]
所以abyxzbzxxcb将首先选择ab ... b ... cb。
我的想法是使用2个谓词的相互递归:
find_another
:找到另一个具有相同字母的元素; find_palindrome
:从末尾选择等距离的元素。我正在使用find_loop([a,b,y,x,z,b,z,x,x,c,b],Loop).
对此进行测试,但未能获得中间(5,b)
,并且在第一个结果后停止。我认为在find_another
中没有正确回溯以继续寻找更多b
s,我担心即使这样做,我也会在途中丢失部分Hist(ory)。
或许更好的方法是在findall
中使用find_another
,然后将每个结果传递给find_palindrome
,但我想我可以通过回溯来完成所有操作。
find_loop(Word, Loop) :-
zip(Word, 0, WZ),
length(Word, WL), Word_length is WL - 1,
[X|_] = WZ,
find_another(X, Word_length, WZ, [X], Loop).
/*
Get a element with same letter
if not in history, explore further via its palindrome
else search for existing element's palindrome
*/
find_another((N,L), Word_length, Word, Hist_in, Hist_out) :-
member((X,L), Word),
(
\+ member((X,L), Hist_in),
find_another((N_palindrome,X), Word_length, Word, [(N_palindrome,X)| Hist_in], Hist_out)
;
find_palindrome((N,L), Word_length, Word, Hist_in, Hist_out)
).
/*
Finds the palindrome element, and then looks for others with new letter
*/
find_palindrome((N,L), Word_length, Word, Hist_in, Hist_out) :-
N_palindrome is Word_length - N,
member((N_palindrome,X), Word),
(
\+ member((N_palindrome,X), Hist_in) ->
Hist_next = [(N_palindrome,X)| Hist_in],
find_another((N_palindrome,X), Word_length, Word, Hist_next, Hist_out)
;
Hist_out = Hist_in
).
%% [a,b,c,...] becomes [(0,a),(1,b),...]
zip([], _, []).
zip([H | T], C, [(C,H)|Z] ) :-
C1 is C + 1,
zip(T,C1,Z).
答案 0 :(得分:0)
好的,所以我仍然不太确定为什么相互递归不起作用,但我想我可以看到回溯应该删除历史的一部分(我实际上需要保留),所以回溯是错误的方式解决这个问题。考虑到这一点,我通过让find_another获得具有相同字母的所有其他元素然后递归列表来使概念更简单。这提供了正确的解决方案。希望我可以在这里概括我的学习,以避免再次出现这个错误! ; - )
find_another((_,L), Word_length, Word, Hist_in, Hist_out) :-
findall((N1,L), member((N1,L), Word), Others),
find_another_from_list(Others, Word_length, Word, Hist_in, Hist_out).
find_another_from_list([], _, _, Hist_out, Hist_out).
find_another_from_list([H|T], Word_length, Word, Hist_in, Hist_out) :-
find_palindrome(H, Word_length, Word, Hist_in, Hist_tmp),
find_another_from_list(T, Word_length, Word, Hist_tmp, Hist_out).