我正在尝试实施Bin Fu's approximate sum algorithm 用真实的语言来更好地了解它的工作原理。
In a nutshell,这是一种有效计算$(1+ \ epsilon)$的算法 - $ s(x)= \ sum_ {i = 1} ^ n x_i $的值的界限 $ x $是排序浮点数的向量。
但是,我必须做错事,因为运行算法会导致错误 (我也不是很熟悉伪算法语言,而且像这样的代码中似乎隐含了一些像数组绑定检查的东西)。
这是我到目前为止的非工作代码,欢迎任何提示/帮助问题 - 我是语言不可知的,我只使用R因为它是1指数(算法是1- index)开源解释语言:
ApproxRegion<-function(x,n,b,delta){
if(x[n]<b) return(NULL)
if(x[n-1]<b) return(c(n,n))
if(x[1]>=b) reurn(c(1,n))
m1<-2
while(x[n-m1**2+1]>=b) m1<-m1**2
i<-1
m1<-m1
r1<-m1
while(m1>(1+delta)){
m1<-sqrt(m1)
if(x[n-floor(m1*r1)+1]>=b){
r1<-m1*r1
} else {
r1=r1
}
i=i+1
}
return(c(n-floor(r1*m1)+1,n))
}
ApproxSum<-function(x,n,epsilon){
if(x[n]==0) return(0)
delta<-3*epsilon/4
r1p<-n
s<-0
i<-1
b1<-x[n]/(1+delta)
while(b1>=((delta*x[n])/(3*n))){
Ri<-ApproxRegion(x=x,n=r1p,b=b1,delta=delta)
r1p<-Ri[1]-1
b1<-x[r1p]/(1+delta)
s1<-(Ri[2]-Ri[1]+1)*b1
s<-s+s1
i<-i+1
}
return(s)
}
n<-100;
x<-sort(runif(n));
ApproxSum(x=x,n=length(x),epsilon=1/10);
sum(x)
作者提到了一个c ++版本,但我无法在线找到它(前面的任何帮助都会很好)。
Modo:我在这里提出问题(而不是在理论上的CS stackexchange站点),因为它是关于实现问题的。随意移动。
原始代码有一个'毛茸茸的'退出条件(x [i] = $ - \ infty $ for $ i \ leq 0 $)。 按照马丁摩根的建议,我通过适当的休息替换了这种情况,产生了以下代码:
ApproxRegion<-function(x,b,delta,n){
if(n<=1) return(NULL)
if(x[n]<b) return(NULL)
if(x[n-1]<b) return(c(n,n))
if(x[1]>=b) return(c(1,n))
m<-2
xit<-0
while(!xit){
if(n-m**2+1<1) break
if(x[n-m**2+1]<b) break
m<-m**2
}
i<-1
r<-m
while(m>=(1+delta)){
m<-sqrt(m)
if(n-floor(m*r)+1>0){
if(x[n-floor(m*r)+1]>=b) r=m*r
}
i<-i+1
}
return(c(n-floor(m*r)+1,n))
}
ApproxSum<-function(x,n,epsilon){
if(x[n]==0) return(0)
delta=3*epsilon/4
rp<-n
s<-0
i<-1
b<-x[n]/(1+delta)
while(b>=delta*x[n]/(3*n)){
R<-ApproxRegion(x,b,delta,rp)
if(is.null(R)) break
if(R[1]<=1) break
rp<-R[1]-1
b<-x[rp]/(1+delta)
si<-(R[2]-R[1]+1)*b
s<-s+si
i<-i+1
}
return(s)
}
现在,它有效:
n<-100;
set.seed(123)
x<-sort(runif(n));
ApproxSum(x=x,n=length(x),epsilon=1/10);
sum(x)
答案 0 :(得分:1)
通过部分答案......有一些边缘条件没有被算法明确处理。例如在ApproxRegion
中,需要保护n = 0(返回值应为NULL?)或1(c(n,n)?)否则第一或第二条件x[n] < b
,{{1将不会按预期进行评估(例如,x [0]返回数字(0))。同样,循环中的测试必须防范x[n - 1] < b
,否则你将用负数来下标。
我认为m1**2 > n + 1
中存在类似问题,尤其是ApproxSum
返回时,例如ApproxRegion
(因此r1p == 0,b1 =整数())。看到更新的实现会很有趣。