我正在尝试在自己的Java程序中实例化StdRandom类(请参见下文),以便通过调用统一方法来生成随机整数。但是,我在编译过程中始终收到此错误:
MyProgram.java:43:StdRandom()在StdRandom中具有私有访问权限
StdRandom random =新的StdRandom();
1个错误
我在代码中注意到这一行,这使我无法实例化StdRandom类:
// singleton pattern - can't instantiate
private StdRandom() { }
我的问题是:我应该如何实例化该类并在自己的程序中使用该类中的方法?为什么上述单例模式包含在此代码中?我应该只注释掉模式并使用它吗?还是有其他方法可以在我的Java程序中访问此类的方法?
/*************************************************************************
* Compilation: javac StdRandom.java
* Execution: java StdRandom
*
* A library of static methods to generate pseudo-random numbers from
* different distributions (bernoulli, uniform, gaussian, discrete,
* and exponential). Also includes a method for shuffling an array.
*
*
* % java StdRandom 5
* seed = 1316600602069
* 59 16.81826 true 8.83954 0
* 32 91.32098 true 9.11026 0
* 35 10.11874 true 8.95396 3
* 92 32.88401 true 8.87089 0
* 72 92.55791 true 9.46241 0
*
* % java StdRandom 5
* seed = 1316600616575
* 96 60.17070 true 8.72821 0
* 79 32.01607 true 8.58159 0
* 81 59.49065 true 9.10423 1
* 96 51.65818 true 9.02102 0
* 99 17.55771 true 8.99762 0
*
* % java StdRandom 5 1316600616575
* seed = 1316600616575
* 96 60.17070 true 8.72821 0
* 79 32.01607 true 8.58159 0
* 81 59.49065 true 9.10423 1
* 96 51.65818 true 9.02102 0
* 99 17.55771 true 8.99762 0
*
*
* Remark
* ------
* - Relies on randomness of nextDouble() method in java.util.Random
* to generate pseudorandom numbers in [0, 1).
*
* - This library allows you to set and get the pseudorandom number seed.
*
* - See http://www.honeylocust.com/RngPack/ for an industrial
* strength random number generator in Java.
*
*************************************************************************/
import java.util.Random;
/**
* <i>Standard random</i>. This class provides methods for generating
* random number from various distributions.
* <p>
* For additional documentation, see <a href="http://introcs.cs.princeton.edu/22library">Section 2.2</a> of
* <i>Introduction to Programming in Java: An Interdisciplinary Approach</i> by Robert Sedgewick and Kevin Wayne.
*/
public final class StdRandom {
private static Random random; // pseudo-random number generator
private static long seed; // pseudo-random number generator seed
// static initializer
static {
// this is how the seed was set in Java 1.4
seed = System.currentTimeMillis();
random = new Random(seed);
}
// singleton pattern - can't instantiate
private StdRandom() { }
/**
* Set the seed of the psedurandom number generator.
*/
public static void setSeed(long s) {
seed = s;
random = new Random(seed);
}
/**
* Get the seed of the psedurandom number generator.
*/
public static long getSeed() {
return seed;
}
/**
* Return real number uniformly in [0, 1).
*/
public static double uniform() {
return random.nextDouble();
}
/**
* Return an integer uniformly between 0 and N-1.
*/
public static int uniform(int N) {
return random.nextInt(N);
}
///////////////////////////////////////////////////////////////////////////
// STATIC METHODS BELOW RELY ON JAVA.UTIL.RANDOM ONLY INDIRECTLY VIA
// THE STATIC METHODS ABOVE.
///////////////////////////////////////////////////////////////////////////
/**
* Return real number uniformly in [0, 1).
*/
public static double random() {
return uniform();
}
/**
* Return int uniformly in [a, b).
*/
public static int uniform(int a, int b) {
return a + uniform(b - a);
}
/**
* Return real number uniformly in [a, b).
*/
public static double uniform(double a, double b) {
return a + uniform() * (b-a);
}
/**
* Return a boolean, which is true with probability p, and false otherwise.
*/
public static boolean bernoulli(double p) {
return uniform() < p;
}
/**
* Return a boolean, which is true with probability .5, and false otherwise.
*/
public static boolean bernoulli() {
return bernoulli(0.5);
}
/**
* Return a real number with a standard Gaussian distribution.
*/
public static double gaussian() {
// use the polar form of the Box-Muller transform
double r, x, y;
do {
x = uniform(-1.0, 1.0);
y = uniform(-1.0, 1.0);
r = x*x + y*y;
} while (r >= 1 || r == 0);
return x * Math.sqrt(-2 * Math.log(r) / r);
// Remark: y * Math.sqrt(-2 * Math.log(r) / r)
// is an independent random gaussian
}
/**
* Return a real number from a gaussian distribution with given mean and stddev
*/
public static double gaussian(double mean, double stddev) {
return mean + stddev * gaussian();
}
/**
* Return an integer with a geometric distribution with mean 1/p.
*/
public static int geometric(double p) {
// using algorithm given by Knuth
return (int) Math.ceil(Math.log(uniform()) / Math.log(1.0 - p));
}
/**
* Return an integer with a Poisson distribution with mean lambda.
*/
public static int poisson(double lambda) {
// using algorithm given by Knuth
// see http://en.wikipedia.org/wiki/Poisson_distribution
int k = 0;
double p = 1.0;
double L = Math.exp(-lambda);
do {
k++;
p *= uniform();
} while (p >= L);
return k-1;
}
/**
* Return a real number with a Pareto distribution with parameter alpha.
*/
public static double pareto(double alpha) {
return Math.pow(1 - uniform(), -1.0/alpha) - 1.0;
}
/**
* Return a real number with a Cauchy distribution.
*/
public static double cauchy() {
return Math.tan(Math.PI * (uniform() - 0.5));
}
/**
* Return a number from a discrete distribution: i with probability a[i].
* Precondition: array entries are nonnegative and their sum equals 1.
*/
public static int discrete(double[] a) {
double EPSILON = 1E-14;
double sum = 0.0;
for (int i = 0; i < a.length; i++) {
if (a[i] < 0.0) throw new IllegalArgumentException("array entry " + i + " is negative: " + a[i]);
sum = sum + a[i];
}
if (sum > 1.0 + EPSILON || sum < 1.0 - EPSILON)
throw new IllegalArgumentException("sum of array entries not equal to one: " + sum);
double r = uniform();
sum = 0.0;
for (int i = 0; i < a.length; i++) {
sum = sum + a[i];
if (sum >= r) return i;
}
return -1;
}
/**
* Return a real number from an exponential distribution with rate lambda.
*/
public static double exp(double lambda) {
return -Math.log(1 - uniform()) / lambda;
}
/**
* Rearrange the elements of an array in random order.
*/
public static void shuffle(Object[] a) {
int N = a.length;
for (int i = 0; i < N; i++) {
int r = i + uniform(N-i); // between i and N-1
Object temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Rearrange the elements of a double array in random order.
*/
public static void shuffle(double[] a) {
int N = a.length;
for (int i = 0; i < N; i++) {
int r = i + uniform(N-i); // between i and N-1
double temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Rearrange the elements of an int array in random order.
*/
public static void shuffle(int[] a) {
int N = a.length;
for (int i = 0; i < N; i++) {
int r = i + uniform(N-i); // between i and N-1
int temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Rearrange the elements of the subarray a[lo..hi] in random order.
*/
public static void shuffle(Object[] a, int lo, int hi) {
if (lo < 0 || lo > hi || hi >= a.length)
throw new RuntimeException("Illegal subarray range");
for (int i = lo; i <= hi; i++) {
int r = i + uniform(hi-i+1); // between i and hi
Object temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Rearrange the elements of the subarray a[lo..hi] in random order.
*/
public static void shuffle(double[] a, int lo, int hi) {
if (lo < 0 || lo > hi || hi >= a.length)
throw new RuntimeException("Illegal subarray range");
for (int i = lo; i <= hi; i++) {
int r = i + uniform(hi-i+1); // between i and hi
double temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Rearrange the elements of the subarray a[lo..hi] in random order.
*/
public static void shuffle(int[] a, int lo, int hi) {
if (lo < 0 || lo > hi || hi >= a.length)
throw new RuntimeException("Illegal subarray range");
for (int i = lo; i <= hi; i++) {
int r = i + uniform(hi-i+1); // between i and hi
int temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Uniformly sample (without replacement) M of the N items from the array a[].
* To make it work with an Object[] argument and return an array of the
* underlying argument type requires some Java minutiae, e.g., using static
* generics and Arrays.copyOf().
*/
public static String[] sample(String[] a, int M) {
int N = a.length;
if (M < 0 || M > N)
throw new RuntimeException("Illegal number of samples");
String[] b = new String[M];
for (int i = 0; i < N; i++) {
int r = uniform(i+1); // between 0 and i
if (r < M) {
if (i < M) b[i] = b[r];
b[r] = a[i];
}
}
return b;
}
/**
* Unit test.
*/
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
if (args.length == 2) StdRandom.setSeed(Long.parseLong(args[1]));
double[] t = { .5, .3, .1, .1 };
StdOut.println("seed = " + StdRandom.getSeed());
for (int i = 0; i < N; i++) {
StdOut.printf("%2d " , uniform(100));
StdOut.printf("%8.5f ", uniform(10.0, 99.0));
StdOut.printf("%5b " , bernoulli(.5));
StdOut.printf("%7.5f ", gaussian(9.0, .2));
StdOut.printf("%2d " , discrete(t));
StdOut.println();
}
String[] a = "A B C D E F G".split(" ");
for (String s : a)
StdOut.print(s + " ");
StdOut.println();
String[] b = StdRandom.sample(a, 3);
for (String s : b)
StdOut.print(s + " ");
StdOut.println();
}
}
最佳答案
所有方法都是静态的,您无需创建该类的实例即可使用它。使用例如random()
方法,使用StdRandom.random()