public class ZipfSelect
{
static Random rng = null;
int numDataElements;//数据元素总数
double[] sums;
bool defaultSelectZipf = true;
double a = 1.0;//(1/r^a)
public ZipfSelect(int numDataElements,double e)
{
a = e;
this.numDataElements = numDataElements;
sums = new double[numDataElements];
double sum = 0.0;
for (int i = 0; i < sums.Length; i++)
{
//SkipNet加2,为什么不是加1或其他数字?本人尚不清楚
sum += 1.0 / Math.Pow((double)(i+2),a);
}
for (int i = 0; i < sums.Length; i++)
{
if (i == 0)
sums[i] = 1.0 / Math.Pow((double)(i+2),a)/ sum;
else
sums[i] = sums[i-1] + 1.0 / Math.Pow((double)(i+2),a)/ sum;
}
}
public static void SetRandomSeed(int seed)
{
r = new Random(seed + 13);
}
public void SetDefaultToUniform()
{
this.defaultSelectZipf = false;
}
public int Pick()
{
return Pick(this.defaultSelectZipf);
}
//取得数据元素索引
public int Pick(bool zipfSelect)
{
int indx;
if (zipfSelect)
{
double u = r.NextDouble();
indx = 0;
while (u > sums[indx]) indx++;
}
else
{
indx = r.Next(this.numDataElements);
}
return indx;
}
}