2017-09-29 70 views
2

我想計算列表的最小值,使用失敗導致回溯。我如何改變min(Min,X,Min),使其工作。計算分使用失敗,回溯查找列表的最小值序言

solve([Head|Rest], Ans) :- 
    solve(Rest, Till), 
    min(Ans, Head, Till). 

%min(X, A, B) X is the min of A, B 
min(X, X, Y) :- X =< Y. 
min(Y, X, Y) :- Y < X. 

member(X, [X|_]). 
member(X, [_|Ys]) :- 
    member(X,Ys). 

program :- 
    Min is 1000, 
    (member(X, [1, 2, 3, 4]), 
    writeln(X), 
    min(Min, X, Min), %This is wrong ! 
    fail; 
    writeln(Min), 
    true). 

我以前的工作代碼,但我不想這樣做,因爲調用解決,我做這樣的事情

program :- 
    findall(X, solve(List, X), Z). 

這是導致找到X的所有解決方案並存儲在內存中。這種方法不適用於大量輸入,因而死亡。

因此,我想計算每個解決呼叫的最小值,而不是像使用findall那樣存儲。

+1

首先,'is'對你在'='程序的第一行沒有做任何事情。其次,我認爲你希望重新分配'Min'的值,就好像它是另一種編程語言中的變量,但這不是Prolog中變量的工作原理。 –

回答

1

如果你擔心內存使用情況,你不應該使用猜測和檢查隱喻(使用失敗意味着你正在使用)。有一個O(n)算法根本不需要失敗。

minlist(Min, [X|Xs]) :- minlist(X, Xs, Min). 

minlist(Min, [], Min). 
minlist(MinSoFar, [X|Xs], Min) :- 
    min(NextMin, MinSoFar, X), 
    minlist(NextMin, Xs, Min). 
+0

最有教育意義的( - + 1)。 SWIPL替代方法:'minlist(Min,L): - 聚合(min(M),member(M,L),Min)。 – CapelliC