Prolog 序言:总结系列程序

Prolog 序言:总结系列程序,prolog,meta-predicate,Prolog,Meta Predicate,我一直在努力解决我在一本书中发现的这个问题,但我无法在头脑中理解它。该问题要求我使用系列(N,总计)进行此过程; 1 + 1/2 + 1/3 + 1/4 + ... + 1/(N-1)。任何能帮助我理解这个问题的人都将不胜感激!非常感谢 我不明白你有什么问题 解决这个问题的一个简单方法是定义一个递归谓词 可以使用和处理小数 其总和为1/1至1/(B-1): 据我所知,您需要一个计算此函数的谓词: 在过程语言中,您可以编写如下迭代解决方案: static double iterative_har

我一直在努力解决我在一本书中发现的这个问题,但我无法在头脑中理解它。该问题要求我使用
系列(N,总计)
进行此过程;
1 + 1/2 + 1/3 + 1/4 + ... + 1/(N-1)。任何能帮助我理解这个问题的人都将不胜感激!非常感谢

我不明白你有什么问题

解决这个问题的一个简单方法是定义一个递归谓词

可以使用和处理小数

其总和为1/1至1/(B-1):


据我所知,您需要一个计算此函数的谓词:

在过程语言中,您可以编写如下迭代解决方案:

static double iterative_harmonic_number( int n )
{
  if ( n < 1 ) throw new ArgumentOutOfRangeException("n");

  double r = 0.0 ;

  while ( n > 0 )
  {
    r += 1.0 / n-- ;
  }

  return r ;
}
static double recursive_harmonic_number( int n )
{
  if ( n < 1 ) throw new ArgumentOutOfRangeException("n");

  double h = (1.0 / n) ;
  if ( n > 1 ) { h += recursive_harmonic_number(n-1) ; } ;

  return h ;

log是最适合递归解决方案的,所以让我们来看一看。你有

  • 1个终止递归的特殊情况(n=1),以及
  • 一般情况(n>1)
我们可以在序言中非常直接地表达这一点:

f( 1 , 1.0 ) .     % the terminating special case
f( N , R   ) :-    % the general case:
  N > 1 ,          % - N must be positive (and greater than 1),
  N1 is N-1 ,      % - compute N-1
  f(N1,T) ,        % - recursively evaluate it
  R is T + 1.0 / N % - add that result to the current N's reciprocal
  .                % Easy!

到目前为止给出的答案可以使用
foldl/4
进行模拟

就像我不会使用浮动,但是。 与浮点数不同,有理数的加法是可交换和结合的。所以当求有理数的和时,任何加法的顺序都会得到相同的结果

我建议与两个元谓词一起使用,如下所示:

seriesR(N,Val) :-
   init1(\I^E^(E is rdiv(1,I)),N-1,Rs),
   reduce(\X^Y^XY^(XY is X+Y),Rs,Val).
示例查询:

?- seriesR(4,Val).
Val = 11 rdiv 6.

为了证明
reduce/3
有助于加快总结速度——尽管它本身有一些内部开销——让我们对一些大的
N
直接运行
seriesR/2
series/3

?- time((series(10000,_),false)). % 40,001 inferences, 2.805 CPU in 2.804 seconds (100% CPU, 14259 Lips) false. ?- time((seriesR(10000,_),false)). % 180,019 inferences, 0.060 CPU in 0.060 seconds (100% CPU, 3014245 Lips) false. 运行
seriesR/2
seriesR2/2
直达我们得到:

?- time((between(1,10000,_),seriesR(10,V),false)).
% 1,750,001 inferences, 0.389 CPU in 0.389 seconds (100% CPU, 4500790 Lips)
false.

?- time((between(1,10000,_),seriesR2(10,V),false)).
% 820,001 inferences, 0.137 CPU in 0.137 seconds (100% CPU, 5999216 Lips)
false.

在本例中,使用lambda表达式会产生大约3倍的最坏情况开销。重要的大概但是数量级比使用
foldl
而不是
reduce
要少

你试过什么吗?没有,正如我说的,我不明白这个问题。我以前做过一个列表练习,但这次不同。我是一周前开始学习的,所以我还是个呆子。不是应该是1/(N+1)吗?利用上一次练习的经验,现在用1/(n+1)进行计算,我想这几乎是一样的,也许更详细一点?这个问题的确切措辞是什么?你应该看看numlist和foldlHi,谢谢你的回答。不过,这个问题想让你用两个术语来解释。我在这里看到三个?然后添加一个谓词
series(N,Total):-series(1,N,Total)。
fractional->rational。这些有理数是特定于IF、SWI和YAP的。啊,一个支持有理数的致命论点。它是有效的,但你还没有学会联合国大学的@错误-修复了它。我在回答时一定把重要的部分删掉了。我的坏B^(
?- seriesR(4,Val).
Val = 11 rdiv 6.
?- time((series(10000,_),false)). % 40,001 inferences, 2.805 CPU in 2.804 seconds (100% CPU, 14259 Lips) false. ?- time((seriesR(10000,_),false)). % 180,019 inferences, 0.060 CPU in 0.060 seconds (100% CPU, 3014245 Lips) false.
num_num_sum(X,Y,Sum) :-
   Sum is X+Y.

r_reciprocal(X,Y) :-
   Y is rdiv(1,X).

seriesR2(N,Val) :-
   init1(r_reciprocal,N-1,Rs),
   reduce(num_num_sum,Rs,Val).   
?- time((between(1,10000,_),seriesR(10,V),false)).
% 1,750,001 inferences, 0.389 CPU in 0.389 seconds (100% CPU, 4500790 Lips)
false.

?- time((between(1,10000,_),seriesR2(10,V),false)).
% 820,001 inferences, 0.137 CPU in 0.137 seconds (100% CPU, 5999216 Lips)
false.