Advertisement
calcpage

StdRandom.java

Jun 12th, 2012
331
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 9.95 KB | None | 0 0
  1. /*************************************************************************
  2.  *  Compilation:  javac StdRandom.java
  3.  *  Execution:    java StdRandom
  4.  *
  5.  *  A library of static methods to generate pseudo-random numbers from
  6.  *  different distributions (bernoulli, uniform, gaussian, discrete,
  7.  *  and exponential). Also includes a method for shuffling an array.
  8.  *
  9.  *
  10.  *  %  java StdRandom 5
  11.  *  seed = 1316600602069
  12.  *  59 16.81826  true 8.83954  0
  13.  *  32 91.32098  true 9.11026  0
  14.  *  35 10.11874  true 8.95396  3
  15.  *  92 32.88401  true 8.87089  0
  16.  *  72 92.55791  true 9.46241  0
  17.  *
  18.  *  % java StdRandom 5
  19.  *  seed = 1316600616575
  20.  *  96 60.17070  true 8.72821  0
  21.  *  79 32.01607  true 8.58159  0
  22.  *  81 59.49065  true 9.10423  1
  23.  *  96 51.65818  true 9.02102  0
  24.  *  99 17.55771  true 8.99762  0
  25.  *
  26.  *  % java StdRandom 5 1316600616575
  27.  *  seed = 1316600616575
  28.  *  96 60.17070  true 8.72821  0
  29.  *  79 32.01607  true 8.58159  0
  30.  *  81 59.49065  true 9.10423  1
  31.  *  96 51.65818  true 9.02102  0
  32.  *  99 17.55771  true 8.99762  0
  33.  *
  34.  *
  35.  *  Remark
  36.  *  ------
  37.  *    - Relies on randomness of nextDouble() method in java.util.Random
  38.  *      to generate pseudorandom numbers in [0, 1).
  39.  *
  40.  *    - This library allows you to set and get the pseudorandom number seed.
  41.  *
  42.  *    - See http://www.honeylocust.com/RngPack/ for an industrial
  43.  *      strength random number generator in Java.
  44.  *
  45.  *************************************************************************/
  46.  
  47. import java.util.Random;
  48.  
  49. /**
  50.  *  <i>Standard random</i>. This class provides methods for generating
  51.  *  random number from various distributions.
  52.  *  <p>
  53.  *  For additional documentation, see <a href="http://introcs.cs.princeton.edu/22library">Section 2.2</a> of
  54.  *  <i>Introduction to Programming in Java: An Interdisciplinary Approach</i> by Robert Sedgewick and Kevin Wayne.
  55.  */
  56. public final class StdRandom {
  57.  
  58.     private static Random random;    // pseudo-random number generator
  59.     private static long seed;        // pseudo-random number generator seed
  60.  
  61.     // static initializer
  62.     static {
  63.         // this is how the seed was set in Java 1.4
  64.         seed = System.currentTimeMillis();
  65.         random = new Random(seed);
  66.     }
  67.  
  68.     // singleton pattern - can't instantiate
  69.     private StdRandom() { }
  70.  
  71.     /**
  72.      * Set the seed of the psedurandom number generator.
  73.      */
  74.     public static void setSeed(long s) {
  75.         seed   = s;
  76.         random = new Random(seed);
  77.     }
  78.  
  79.     /**
  80.      * Get the seed of the psedurandom number generator.
  81.      */
  82.     public static long getSeed() {
  83.         return seed;
  84.     }
  85.  
  86.     /**
  87.      * Return real number uniformly in [0, 1).
  88.      */
  89.     public static double uniform() {
  90.         return random.nextDouble();
  91.     }
  92.  
  93.     /**
  94.      * Return an integer uniformly between 0 and N-1.
  95.      */
  96.     public static int uniform(int N) {
  97.         return random.nextInt(N);
  98.     }
  99.  
  100.     ///////////////////////////////////////////////////////////////////////////
  101.     //  STATIC METHODS BELOW RELY ON JAVA.UTIL.RANDOM ONLY INDIRECTLY VIA
  102.     //  THE STATIC METHODS ABOVE.
  103.     ///////////////////////////////////////////////////////////////////////////
  104.  
  105.     /**
  106.      * Return real number uniformly in [0, 1).
  107.      */
  108.     public static double random() {
  109.         return uniform();
  110.     }
  111.  
  112.     /**
  113.      * Return int uniformly in [a, b).
  114.      */
  115.     public static int uniform(int a, int b) {
  116.         return a + uniform(b - a);
  117.     }
  118.  
  119.     /**
  120.      * Return real number uniformly in [a, b).
  121.      */
  122.     public static double uniform(double a, double b) {
  123.         return a + uniform() * (b-a);
  124.     }
  125.  
  126.     /**
  127.      * Return a boolean, which is true with probability p, and false otherwise.
  128.      */
  129.     public static boolean bernoulli(double p) {
  130.         return uniform() < p;
  131.     }
  132.  
  133.     /**
  134.      * Return a boolean, which is true with probability .5, and false otherwise.
  135.      */
  136.     public static boolean bernoulli() {
  137.         return bernoulli(0.5);
  138.     }
  139.  
  140.     /**
  141.      * Return a real number with a standard Gaussian distribution.
  142.      */
  143.     public static double gaussian() {
  144.         // use the polar form of the Box-Muller transform
  145.         double r, x, y;
  146.         do {
  147.             x = uniform(-1.0, 1.0);
  148.             y = uniform(-1.0, 1.0);
  149.             r = x*x + y*y;
  150.         } while (r >= 1 || r == 0);
  151.         return x * Math.sqrt(-2 * Math.log(r) / r);
  152.  
  153.         // Remark:  y * Math.sqrt(-2 * Math.log(r) / r)
  154.         // is an independent random gaussian
  155.     }
  156.  
  157.     /**
  158.      * Return a real number from a gaussian distribution with given mean and stddev
  159.      */
  160.     public static double gaussian(double mean, double stddev) {
  161.         return mean + stddev * gaussian();
  162.     }
  163.  
  164.     /**
  165.      * Return an integer with a geometric distribution with mean 1/p.
  166.      */
  167.     public static int geometric(double p) {
  168.         // using algorithm given by Knuth
  169.         return (int) Math.ceil(Math.log(uniform()) / Math.log(1.0 - p));
  170.     }
  171.  
  172.     /**
  173.      * Return an integer with a Poisson distribution with mean lambda.
  174.      */
  175.     public static int poisson(double lambda) {
  176.         // using algorithm given by Knuth
  177.         // see http://en.wikipedia.org/wiki/Poisson_distribution
  178.         int k = 0;
  179.         double p = 1.0;
  180.         double L = Math.exp(-lambda);
  181.         do {
  182.             k++;
  183.             p *= uniform();
  184.         } while (p >= L);
  185.         return k-1;
  186.     }
  187.  
  188.     /**
  189.      * Return a real number with a Pareto distribution with parameter alpha.
  190.      */
  191.     public static double pareto(double alpha) {
  192.         return Math.pow(1 - uniform(), -1.0/alpha) - 1.0;
  193.     }
  194.  
  195.     /**
  196.      * Return a real number with a Cauchy distribution.
  197.      */
  198.     public static double cauchy() {
  199.         return Math.tan(Math.PI * (uniform() - 0.5));
  200.     }
  201.  
  202.     /**
  203.      * Return a number from a discrete distribution: i with probability a[i].
  204.      * Precondition: array entries are nonnegative and their sum equals 1.
  205.      */
  206.     public static int discrete(double[] a) {
  207.         double EPSILON = 1E-15;
  208.         double sum = 0.0;
  209.         for (int i = 0; i < a.length; i++) {
  210.             if (a[i] < 0.0) throw new IllegalArgumentException("array entry " + i + " is negative: " + a[i]);
  211.             sum = sum + a[i];
  212.         }
  213.         if (sum > 1.0 + EPSILON || sum < 1.0 - EPSILON)
  214.             throw new IllegalArgumentException("sum of array entries not equal to one: " + sum);
  215.  
  216.  
  217.         double r = uniform();
  218.         sum = 0.0;
  219.         for (int i = 0; i < a.length; i++) {
  220.             sum = sum + a[i];
  221.             if (sum >= r) return i;
  222.         }
  223.         return -1;
  224.     }
  225.  
  226.     /**
  227.      * Return a real number from an exponential distribution with rate lambda.
  228.      */
  229.     public static double exp(double lambda) {
  230.         return -Math.log(1 - uniform()) / lambda;
  231.     }
  232.  
  233.     /**
  234.      * Rearrange the elements of an array in random order.
  235.      */
  236.     public static void shuffle(Object[] a) {
  237.         int N = a.length;
  238.         for (int i = 0; i < N; i++) {
  239.             int r = i + uniform(N-i);     // between i and N-1
  240.             Object temp = a[i];
  241.             a[i] = a[r];
  242.             a[r] = temp;
  243.         }
  244.     }
  245.  
  246.     /**
  247.      * Rearrange the elements of a double array in random order.
  248.      */
  249.     public static void shuffle(double[] a) {
  250.         int N = a.length;
  251.         for (int i = 0; i < N; i++) {
  252.             int r = i + uniform(N-i);     // between i and N-1
  253.             double temp = a[i];
  254.             a[i] = a[r];
  255.             a[r] = temp;
  256.         }
  257.     }
  258.  
  259.     /**
  260.      * Rearrange the elements of an int array in random order.
  261.      */
  262.     public static void shuffle(int[] a) {
  263.         int N = a.length;
  264.         for (int i = 0; i < N; i++) {
  265.             int r = i + uniform(N-i);     // between i and N-1
  266.             int temp = a[i];
  267.             a[i] = a[r];
  268.             a[r] = temp;
  269.         }
  270.     }
  271.  
  272.  
  273.     /**
  274.      * Rearrange the elements of the subarray a[lo..hi] in random order.
  275.      */
  276.     public static void shuffle(Object[] a, int lo, int hi) {
  277.         if (lo < 0 || lo > hi || hi >= a.length)
  278.             throw new RuntimeException("Illegal subarray range");
  279.         for (int i = lo; i <= hi; i++) {
  280.             int r = i + uniform(hi-i+1);     // between i and hi
  281.             Object temp = a[i];
  282.             a[i] = a[r];
  283.             a[r] = temp;
  284.         }
  285.     }
  286.  
  287.     /**
  288.      * Rearrange the elements of the subarray a[lo..hi] in random order.
  289.      */
  290.     public static void shuffle(double[] a, int lo, int hi) {
  291.         if (lo < 0 || lo > hi || hi >= a.length)
  292.             throw new RuntimeException("Illegal subarray range");
  293.         for (int i = lo; i <= hi; i++) {
  294.             int r = i + uniform(hi-i+1);     // between i and hi
  295.             double temp = a[i];
  296.             a[i] = a[r];
  297.             a[r] = temp;
  298.         }
  299.     }
  300.  
  301.     /**
  302.      * Rearrange the elements of the subarray a[lo..hi] in random order.
  303.      */
  304.     public static void shuffle(int[] a, int lo, int hi) {
  305.         if (lo < 0 || lo > hi || hi >= a.length)
  306.             throw new RuntimeException("Illegal subarray range");
  307.         for (int i = lo; i <= hi; i++) {
  308.             int r = i + uniform(hi-i+1);     // between i and hi
  309.             int temp = a[i];
  310.             a[i] = a[r];
  311.             a[r] = temp;
  312.         }
  313.     }
  314.  
  315.  
  316.     /**
  317.      * Unit test.
  318.      */
  319.     public static void main(String[] args) {
  320.         int N = Integer.parseInt(args[0]);
  321.         if (args.length == 2) StdRandom.setSeed(Long.parseLong(args[1]));
  322.         double[] t = { .5, .3, .1, .1 };
  323.  
  324.         StdOut.println("seed = " + StdRandom.getSeed());
  325.         for (int i = 0; i < N; i++) {
  326.             StdOut.printf("%2d "  , uniform(100));
  327.             StdOut.printf("%8.5f ", uniform(10.0, 99.0));
  328.             StdOut.printf("%5b "  , bernoulli(.5));
  329.             StdOut.printf("%7.5f ", gaussian(9.0, .2));
  330.             StdOut.printf("%2d "  , discrete(t));
  331.             StdOut.println();
  332.         }
  333.     }
  334.  
  335. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement