有效地计算每个组和子组的最小值

时间:2011-04-16 19:26:24

标签: c

想象一下,我们从某些人群中抽取了一个随机样本y1, y2, ...,yn,因此double y[]int n已知。我们的人口中有一些群体,但我们并不确切地知道哪个观察分配给特定群体。因此,对于每个yi,我们引入了一个分配变量zi,它告诉我们是从哪个组yi绘制的。现在我们假设有int k个组,因此zi e {0, .., k-1} for all i。现在要对组进行推断,我需要迭代我的算法几次,比如50,000或100,000。在每次迭代中,我们将概率性地将每个观察分配给某个组,以便我的分配数组int z[]将发生变化。在这种情况下,计算每组中的观察数量和最小值是非常容易的;

int nj[k], yj_min[k];

/* initializing the variables at each iteration */
for(j=0; j<k; j++){
    nj[j]=0;
    yj_min[j]=y[n]; /* y[] are ordered so y[n] is the maximum*/
} 

for(i=0; i<n; i++){
    nj[z[i]] = nj[z[i]] + 1;
    if(yj_min[z[i]]) < y[z[i]]){
        yj_min[z[i]] = y[z[i]];  
    }
}

但是如果我们为每个观察yi引入另一个分配变量di,它将指示已经采样yi的子组(以及概率性采样)。有m个子组,所以di e {0, .., m-1}。然后(zi=j, di=s)表示观察yi已从小组j和小组s中提取。

我如何有效地计算,因为我必须在每次迭代时执行此操作,yjs_min超过{i:zi=j, di=s}?即最小超过yizi=jdi=sj=0, ..k-1s=0,..,m-1

做一些像

这样的事情会很棒
for(i=0; i<n; i++){
    njs[z[i]][d[i]] = njs[z[i]][d[i]] + 1;
    if(yjs_min[z[i]][d[i]]) < y[z[i]][d[i]]){
        yjs_min[z[i]][d[i]] = y[z[i]][d[i]];  
    }
}

但显然这是不可能的!那么请任何想法?

干杯, 卡洛斯

1 个答案:

答案 0 :(得分:0)

看起来你正试图做一些类似Fisher精确测试或排列测试的事情。如果是这样,您可以尝试使用像R这样的统计软件包,它可以用来做这种事情,并且可能已经内置了最有效的算法。

除此之外,据我了解,您将样本分层为n个子组(y),然后将每个子组分为k个子组。您想要找到每个子子组的最小元素。

一个合理有效的解决方案是:创建n * k个唯一标识符,以及指示每个子子组对应的子子组的映射。然后,随机分配这些数字(使用相同的分布)到您的样本观察(就像您之前一样)。使用有效的就地排序(如带有正确选择的数据透视表的快速排序)按标识符对样本进行排序,以便具有相同标识符的所有元素都存储在连续的内存块中。这需要对数线性时间,所以它应该非常快。

然后,您只需按顺序遍历数组,并找到每个唯一标识符的最小元素。这应该是线性时间和n * k额外空间。

希望有所帮助。