source: proiecte/HadoopJUnit/hadoop-0.20.1/src/test/org/apache/hadoop/io/file/tfile/RandomDistribution.java @ 120

Last change on this file since 120 was 120, checked in by (none), 14 years ago

Added the mail files for the Hadoop JUNit Project

  • Property svn:executable set to *
File size: 6.6 KB
Line 
1/**
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with this
4 * work for additional information regarding copyright ownership. The ASF
5 * licenses this file to you under the Apache License, Version 2.0 (the
6 * "License"); you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 */
17package org.apache.hadoop.io.file.tfile;
18
19import java.util.ArrayList;
20import java.util.Arrays;
21import java.util.Collections;
22import java.util.Random;
23
24/**
25 * A class that generates random numbers that follow some distribution.
26 */
27public class RandomDistribution {
28  /**
29   * Interface for discrete (integer) random distributions.
30   */
31  public static interface DiscreteRNG {
32    /**
33     * Get the next random number
34     *
35     * @return the next random number.
36     */
37    public int nextInt();
38  }
39
40  /**
41   * P(i)=1/(max-min)
42   */
43  public static final class Flat implements DiscreteRNG {
44    private final Random random;
45    private final int min;
46    private final int max;
47
48    /**
49     * Generate random integers from min (inclusive) to max (exclusive)
50     * following even distribution.
51     *
52     * @param random
53     *          The basic random number generator.
54     * @param min
55     *          Minimum integer
56     * @param max
57     *          maximum integer (exclusive).
58     *
59     */
60    public Flat(Random random, int min, int max) {
61      if (min >= max) {
62        throw new IllegalArgumentException("Invalid range");
63      }
64      this.random = random;
65      this.min = min;
66      this.max = max;
67    }
68   
69    /**
70     * @see DiscreteRNG#nextInt()
71     */
72    @Override
73    public int nextInt() {
74      return random.nextInt(max - min) + min;
75    }
76  }
77
78  /**
79   * Zipf distribution. The ratio of the probabilities of integer i and j is
80   * defined as follows:
81   *
82   * P(i)/P(j)=((j-min+1)/(i-min+1))^sigma.
83   */
84  public static final class Zipf implements DiscreteRNG {
85    private static final double DEFAULT_EPSILON = 0.001;
86    private final Random random;
87    private final ArrayList<Integer> k;
88    private final ArrayList<Double> v;
89
90    /**
91     * Constructor
92     *
93     * @param r
94     *          The random number generator.
95     * @param min
96     *          minimum integer (inclusvie)
97     * @param max
98     *          maximum integer (exclusive)
99     * @param sigma
100     *          parameter sigma. (sigma > 1.0)
101     */
102    public Zipf(Random r, int min, int max, double sigma) {
103      this(r, min, max, sigma, DEFAULT_EPSILON);
104    }
105
106    /**
107     * Constructor.
108     *
109     * @param r
110     *          The random number generator.
111     * @param min
112     *          minimum integer (inclusvie)
113     * @param max
114     *          maximum integer (exclusive)
115     * @param sigma
116     *          parameter sigma. (sigma > 1.0)
117     * @param epsilon
118     *          Allowable error percentage (0 < epsilon < 1.0).
119     */
120    public Zipf(Random r, int min, int max, double sigma, double epsilon) {
121      if ((max <= min) || (sigma <= 1) || (epsilon <= 0)
122          || (epsilon >= 0.5)) {
123        throw new IllegalArgumentException("Invalid arguments");
124      }
125      random = r;
126      k = new ArrayList<Integer>();
127      v = new ArrayList<Double>();
128
129      double sum = 0;
130      int last = -1;
131      for (int i = min; i < max; ++i) {
132        sum += Math.exp(-sigma * Math.log(i - min + 1));
133        if ((last == -1) || i * (1 - epsilon) > last) {
134          k.add(i);
135          v.add(sum);
136          last = i;
137        }
138      }
139
140      if (last != max - 1) {
141        k.add(max - 1);
142        v.add(sum);
143      }
144
145      v.set(v.size() - 1, 1.0);
146
147      for (int i = v.size() - 2; i >= 0; --i) {
148        v.set(i, v.get(i) / sum);
149      }
150    }
151
152    /**
153     * @see DiscreteRNG#nextInt()
154     */
155    @Override
156    public int nextInt() {
157      double d = random.nextDouble();
158      int idx = Collections.binarySearch(v, d);
159
160      if (idx > 0) {
161        ++idx;
162      }
163      else {
164        idx = -(idx + 1);
165      }
166
167      if (idx >= v.size()) {
168        idx = v.size() - 1;
169      }
170
171      if (idx == 0) {
172        return k.get(0);
173      }
174
175      int ceiling = k.get(idx);
176      int lower = k.get(idx - 1);
177
178      return ceiling - random.nextInt(ceiling - lower);
179    }
180  }
181
182  /**
183   * Binomial distribution.
184   *
185   * P(k)=select(n, k)*p^k*(1-p)^(n-k) (k = 0, 1, ..., n)
186   *
187   * P(k)=select(max-min-1, k-min)*p^(k-min)*(1-p)^(k-min)*(1-p)^(max-k-1)
188   */
189  public static final class Binomial implements DiscreteRNG {
190    private final Random random;
191    private final int min;
192    private final int n;
193    private final double[] v;
194
195    private static double select(int n, int k) {
196      double ret = 1.0;
197      for (int i = k + 1; i <= n; ++i) {
198        ret *= (double) i / (i - k);
199      }
200      return ret;
201    }
202   
203    private static double power(double p, int k) {
204      return Math.exp(k * Math.log(p));
205    }
206
207    /**
208     * Generate random integers from min (inclusive) to max (exclusive)
209     * following Binomial distribution.
210     *
211     * @param random
212     *          The basic random number generator.
213     * @param min
214     *          Minimum integer
215     * @param max
216     *          maximum integer (exclusive).
217     * @param p
218     *          parameter.
219     *
220     */
221    public Binomial(Random random, int min, int max, double p) {
222      if (min >= max) {
223        throw new IllegalArgumentException("Invalid range");
224      }
225      this.random = random;
226      this.min = min;
227      this.n = max - min - 1;
228      if (n > 0) {
229        v = new double[n + 1];
230        double sum = 0.0;
231        for (int i = 0; i <= n; ++i) {
232          sum += select(n, i) * power(p, i) * power(1 - p, n - i);
233          v[i] = sum;
234        }
235        for (int i = 0; i <= n; ++i) {
236          v[i] /= sum;
237        }
238      }
239      else {
240        v = null;
241      }
242    }
243
244    /**
245     * @see DiscreteRNG#nextInt()
246     */
247    @Override
248    public int nextInt() {
249      if (v == null) {
250        return min;
251      }
252      double d = random.nextDouble();
253      int idx = Arrays.binarySearch(v, d);
254      if (idx > 0) {
255        ++idx;
256      } else {
257        idx = -(idx + 1);
258      }
259
260      if (idx >= v.length) {
261        idx = v.length - 1;
262      }
263      return idx + min;
264    }
265  }
266}
Note: See TracBrowser for help on using the repository browser.