我正试图在Prolog中做一个平均谓词,但我遇到了一些问题,
它被称为平均值(N,X),其中N是数字,X是从1到N的平均值的结果。
我试图这样做,但它并不总是运作良好:
average(1,1).
average(N,X) :- K is N-1 ,K>1 , average(K,S1) , X is /(+(S1,N),N).
average(N,X) :- K is N-1 ,K=:=1 , average(K,S1) , X is +(S1,N).
一些帮助?
答案 0 :(得分:5)
让我们看一下1到n之和的一些平均值:
n = 1: 1/1 = 1
n = 2: (1+2)/2 = 3/2
n = 3: (1+2+3)/3 = 2
...
现在从某种意义上说,感觉1和n之间的元素并不重要,总有1/2添加。因此,我们假设(1 + ... n)/ n =(1 + n)/ 2。我们如何为一般的n证明这一点?让我们尝试归纳,即让我们说明我们可以从n = 0到n = 1进行基本步骤然后,假设我们的公式适用于任意n,我们证明公式也适用于的n + 1。
步骤案例:假设(1 + ... + n)/ n =(1 + n)/ 2。我们还需要表明(1 + ... + n +(n + 1))/(n + 1)=(1+(n + 1))/ 2。我们可以将分数分成两部分:
(1+...+n+(n+1))/(n+1) =
(1+...+n)/(n+1) + (n+1)/(n+1) =
(1+...+n)/(n+1) + 1
现在我们需要通过(n + 1)对除法进行一些处理,所以让我们以不同的方式写出分数:
(1+...+n)/(n+1) + 1 =
(1+...+n)/n * (n/(n+1)) + 1
现在我们可以使用(1 + ... + n)/ n =(1 + n)/ 2的假设并简化:
(1+...+n)/n * (n/(n+1)) + 1 =
(1+n)/2 * (n/(n+1)) + 1 =
n/2 + 1 =
(n+2)/2 =
(1 + (n+1))/2
这正是我们想要的!
现在让我们制作一个程序:
avg(N,X) :- X is (1+N)/2.
它给出了预期的结果:
?- between(1,10,C), avg(C,X).
C = X, X = 1 ;
C = 2,
X = 1.5 ;
C = 3,
X = 2 ;
C = 4,
X = 2.5 ;
C = 5,
X = 3 ;
C = 6,
X = 3.5 ;
C = 7,
X = 4 ;
C = 8,
X = 4.5 ;
C = 9,
X = 5 ;
C = 10,
X = 5.5.
此外,它比原始方法更有效!
答案 1 :(得分:3)
想想你的规则......
average(1, 1).
平均值为1。
听起来不错。我要跳到你的第3条规则,这也很具体,但只是冗长:
average(N,X) :- K is N-1 ,K=:=1 , average(K,S1) , X is +(S1,N).
如果
N
为X
,K
为1,则N-1
的平均值为K
,则K
的平均值为S1
X
,S1+N
为N
。
这可以简化很多,因为average(2, X) :- average(1, S1), X is S1 + 2.
在此规则中必然是2:
average(1, S1)
然后,因为我们知道average(2, X) :- X is 3 % X is 1 + 2
的一个结果:
average(2, 3).
然后更进一步,只是:
average(N,X) :- K is N-1 ,K>1 , average(K,S1) , X is /(+(S1,N),N).
所以你不需要你的第三条规则的所有逻辑。
现在让我们看看第二条规则,这是你最常见的情况:
N
如果
X
为K
,N-1
,1到K > 1
的平均值为K
,则S1
的平均值为X
{1}},(S1 + N)/N
为K > 1
。
N > 2
或等效N
的情况。它说我可以将1的平均值设为N-1
,首先将平均值设为1 N
,然后添加N
然后除以N
获得1到N
的平均值。这在数学上是无效的。让我们来看一个简单的反例,其中S1 = average of 1 to 2, = (1+2)/2 = 1.5.
是3:
S = average of 1 to 3 = (S1 + 3)/3 = (1.5+3)/3 = 4.5/3 = 1.5
现在,如果我们说平均1到3是1到2的平均值加3然后除以3,我们得到:
(1+2+3)/3
但是,正确答案为S1
,即6/3或仅为2。
正确的公式是什么?好吧,N-1
是1到N-1
的平均值, 1到N-1
/(S
)的总和。如果我想从那里转到N
,总和为1 N
/ N
,这是1到S1
的平均值,我需要将N-1
乘以N
,然后加N
,再除以average(N,X) :- K is N-1, K > 1 , average(K, S1), X is (S1*(N-1)+N)/N.
。换句话说,你的第二条规则应该是:
average(1, 1).
average(2, 3).
average(N, X) :- K is N-1, K > 1 , average(K, S1), X is (S1*(N-1)+N)/N.
回到1到3的简单例子,我们发现1到2的平均值是1.5。如果我们将它乘以2,然后加3,然后除以3,我们得到:((1.5 * 2)+3)/ 3 =(3 + 3)/ 3 = 6/3 = 2,这是正确的答案。
总之,您的规则变为:
K
但实际上你并不需要第二条规则。如果我们调整N
的第3个规则中的条件(或者实际上只是使其成为average(1, 1).
average(N, X) :- N > 1, K is N-1, average(K, S1), X is (S1*(N-1)+N)/N.
的规则,那么第3个规则和基本案例会为您处理它,这更加清晰)。所以只是:
N
顺便说一句,我认为这只是Prolog中递归的练习,因为已经存在一个简单的公式,用于从1到N*(N+1)/2
((N+1)/2
)的数字之和,因此对于平均值,即:BrowserWindow
。
答案 2 :(得分:2)
只是为了暗示好的图书馆(aggregate)如何提供帮助:
?- aggregate((sum(N),count),member(N,[4,5,6]),(S,C)),Ave is S/C.
S = 15,
C = 3,
Ave = 5.