根据Histogram近似分布,对变量区间进行平均划分
可用在并行排序算法(Parallel Sort by Regular Sampling)中, 根据进程数目对键值进行近似相等划分,保证每个进程获得的记录数近似相等,进而达到负载均衡目的。
理论背景
随机变量
x
x
x概率密度函数(PDF)是
p
(
x
)
p(x)
p(x), 计算
t
<
x
t<x
t<x的概率(CDF)
P
r
(
t
<
x
)
=
y
(
x
)
=
∫
−
∞
x
p
(
t
)
d
t
Pr(t<x)=y(x)=\int_{-\infty}^{x}p(t)dt
Pr(t<x)=y(x)=∫−∞xp(t)dt
得到随机变量 y y y, y y y在区间 [ 0 , 1 ] [0,1] [0,1]均匀分布。采用冯诺依曼方法,可以生成任意分布函数 p ( x ) p(x) p(x)的随机变量 x x x:
在
[
0
,
1
]
[0,1]
[0,1]区间均匀分布生成随机变量y, 根据上面公式反向求解
x
=
x
(
y
)
x=x(y)
x=x(y),
x
x
x既是分布为
p
(
x
)
p(x)
p(x)的随机变量(Inverse Transform Method)
实现程序
给定近似分布数据(histogram),选择合适的划分点(splitters),划分成n个区间,保证每个区间内的概率(面积)近似相等:
template<typename Int, typename Float>
void calcSplitter(__IN__ const Int n,
__IN__ const Int mhist,
__IN__ const Float xhist[], //xhist[mhist+1]
__IN__ const Float histogram[], //histogram[mhist]
__OUT__ Float xi[] //xi[n+1],splitter
)
{
ASSERT(n>0);
ASSERT(mhist>0);
//ASSERT(mhist>10*n);
if(n==1)
{
xi[0]=xhist[0];
xi[1]=xhist[1];
return;
}
//x分布函数(PDF)
Float *pdf=xHistogram;
//x累积分布函数(CDF)
FLoat *cdf=new Float[mhist+1];
cdf[0]=0;
for(Int i=0;i<mhist;i++)
{
cdf[i+1]=pdf[i]+cdf[i];
}
//相邻分割点之间的平均面积
Float bin_area=cdf[mhist]/Float(n);
xi[0]=xhist[0]; //左边界
xi[n]=xhist[mhist]; //右边界
Int j=0;
for(Int i=0;i<n;i++)
{
Float area=bin_area*i;
for(;j<mhist;j++)
{
if(area>=cdf[j]&&area<=cdf[j+1])
break;
}
//线性插值
Float frac=(area-cdf[j])/(cdf[j+1]-cdf[j]);
xi[i]=xhist[j]+frac*(xhist[j+1]-xhist[j]);
}
delete []cdf;
return;
}