Skip to content

Instantly share code, notes, and snippets.

@burmanm
Created June 13, 2018 12:52
Show Gist options
  • Select an option

  • Save burmanm/c3038cdaf7a9b2fcd8c716f57e6dcc07 to your computer and use it in GitHub Desktop.

Select an option

Save burmanm/c3038cdaf7a9b2fcd8c716f57e6dcc07 to your computer and use it in GitHub Desktop.
Faster ZipfDistribution
static class ZipfDistribution
{
private ThreadLocalRandom random;
private double alpha;
private int elements;
private double constant;
private double[] sumsOfProbabilities;
public ZipfDistribution(double alpha, int elements)
{
random = ThreadLocalRandom.current();
this.alpha = alpha;
this.elements = elements;
sumsOfProbabilities = new double[elements];
initializeZipf(alpha, elements);
}
private int next()
{
double zipfValue = 0;
double z = 0;
while (z == 0)
{
z = random.nextDouble();
}
int low = 1;
int high = elements;
while (low <= high) {
int mid = (low + high) >>> 1;
if(sumsOfProbabilities[mid] >= z && sumsOfProbabilities[mid - 1] < z) {
zipfValue = mid;
break;
} else if(sumsOfProbabilities[mid] >= z) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return (int) (zipfValue - 1);
}
private void initializeZipf(double alpha, int elements)
{
double norm = 0;
for (int i = 1; i <= elements; i++)
{
norm = norm + (1.0 / Math.pow((double) i, alpha));
}
constant = 1.0 / norm;
sumsOfProbabilities[0] = (double) 0;
for (int i = 1; i < elements; i++)
{
sumsOfProbabilities[i] = sumsOfProbabilities[i - 1] + constant / Math.pow((double) i, alpha);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment