2017-09-29 62 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