1

我有谓词计算数字 N 的阶乘,但是当时间超过 1 秒时,它被中断:

factorial( 0, 1 ).
factorial( N, Value ) :-
    N > 0,
    Prev is N - 1,
    factorial( Prev, Prevfact ),
    Value is Prevfact * N.

fact(N,V) :-
catch(call_with_time_limit(1, factorial(N,V)  ),
    time_limit_exceeded,
    write('time exceeded!')).

如何在阶乘中断之前获得 V 的最后一个值?

谢谢

4

1 回答 1

1

在计算被中断之前,您的代码中没有最后一个值V- 它还没有被实例化。如果它被实例化,那么计算已经结束并且没有中断。

如果您想找出在一秒钟内可以计算出的最大阶乘,则必须通过某种不会被回溯破坏的机制来保存它(因为catch/3回溯)。

但是按照您的代码编写方式,在计算进行到一半之前,您将没有任何价值可以保存。如果它总共需要 3 秒,这意味着在它的前 1.5 秒运行期间您将没有任何价值可以保存:

factorial( 0, 1 ).
factorial( N, Value ) :-
    N > 0,
    Prev is N - 1,
    factorial( Prev, Prevfact ),
    % here - save the value of Prevfact, e.g. with nb_setval/2
    Value is Prevfact * N.

那是因为它在从递归深度返回的路上计算它的阶乘。

要使其立即计算一些值,请将其更改为使用累加器:

factorial(N,F):- factorial(N,1,1,F).
factorial(N,A,K,F):- K>N -> F=A ; 
  A2 is A*K, K2 is K+1,   % save (A2,K) here
  factorial(N,A2,K2,F).
于 2013-04-18T09:31:07.233 回答