C++ 实施宾府';s近似和算法

C++ 实施宾府';s近似和算法,c++,r,algorithm,language-agnostic,C++,R,Algorithm,Language Agnostic,我正在努力实现 用真实的语言来更好地理解它的工作原理 ,这是一个有效计算$s(x)=\sum_{i=1}^n x_i$值上的$(1+\epsilon)$-界的算法,其中 $x$是已排序浮点的向量 但是,我一定是做错了什么,因为运行算法会导致错误 (我对伪算法语言也不是很精通,有些东西,比如数组绑定检查,似乎在这段代码中是隐含的) 这是我到目前为止所拥有的非工作代码,欢迎对该问题提供任何提示/帮助——我不懂语言,我只是使用R,因为它是一种1-index(algo是1-index)开源解释语言: A

我正在努力实现 用真实的语言来更好地理解它的工作原理

,这是一个有效计算$s(x)=\sum_{i=1}^n x_i$值上的$(1+\epsilon)$-界的算法,其中 $x$是已排序浮点的向量

但是,我一定是做错了什么,因为运行算法会导致错误 (我对伪算法语言也不是很精通,有些东西,比如数组绑定检查,似乎在这段代码中是隐含的)

这是我到目前为止所拥有的非工作代码,欢迎对该问题提供任何提示/帮助——我不懂语言,我只是使用R,因为它是一种1-index(algo是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)

ApproxRegion通过部分答案。。。有些边缘条件不是由算法显式处理的。例如,在
ApproxRegion
中,需要保护n=0(返回值应为NULL?)或1(c(n,n)?),否则第一个或第二个条件
x[n]
x[n-1]
将不会按预期进行计算(例如,x[0]返回数字(0))。同样,循环中的测试必须防止
m1**2>n+1
,否则您将使用负数下标


我认为在
ApproxSum
中也存在类似的问题,特别是当
ApproxRegion
返回时,例如
c(1,1)
(因此r1p==0,b1=integer()。如果能看到更新的实现,那将很有趣。

谢谢您的评论。是的,我同意。我试着尽可能忠实地从论文中复制代码(不要添加混淆级别)。问题是这些数组绑定冲突中至少有一些似乎是退出点!(例如,跟踪变量“s”表明,当算法命中其目标时,它们就会发生)。我不知道在伪algo语言中,这样的复杂退出条件是否很常见:(.欢迎进一步评论。非常感谢。
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)