public abstract class AbstractRNG extends java.lang.Object implements IRNG
IRNG
without so much busy-work.
You need to provide implementations for the abstract methods nextInt()
, next(int)
,
nextLong()
, nextBoolean()
, nextDouble()
, nextFloat()
, copy()
, and
toSerializable()
, many of which may be built off of each other and some of which have sample code in their
documentation strings in this class.
Constructor and Description |
---|
AbstractRNG() |
Modifier and Type | Method and Description |
---|---|
double |
between(double min,
double max)
Returns a value from a uniform distribution from min (inclusive) to max
(exclusive).
|
int |
between(int min,
int max)
Returns a value between min (inclusive) and max (exclusive) as ints.
|
long |
between(long inner,
long outer)
Returns a value between inner (inclusive) and outer (exclusive) as longs.
|
abstract IRNG |
copy()
Creates a copy of this IRNG; it will generate the same random numbers, given the same calls in order, as this
IRNG at the point copy() is called.
|
<T> T |
getRandomElement(java.util.Collection<T> coll)
Returns a random element from the provided Collection, which should have predictable iteration order if you want
predictable behavior for identical RNG seeds, though it will get a random element just fine for any Collection
(just not predictably in all cases).
|
<T> T |
getRandomElement(java.util.List<T> list)
Returns a random element from the provided list.
|
<T> T |
getRandomElement(T[] array)
Returns a random element from the provided array and maintains object
type.
|
abstract int |
next(int bits)
Get up to 32 bits (inclusive) of random output; the int this produces
will not require more than
bits bits to represent. |
abstract boolean |
nextBoolean()
Get a random bit of state, interpreted as true or false with approximately equal likelihood.
|
abstract double |
nextDouble()
Gets a random double between 0.0 inclusive and 1.0 exclusive.
|
double |
nextDouble(double outer)
This returns a random double between 0.0 (inclusive) and outer (exclusive).
|
abstract float |
nextFloat()
Gets a random float between 0.0f inclusive and 1.0f exclusive.
|
float |
nextFloat(float outer)
This returns a random float between 0.0f (inclusive) and outer (exclusive).
|
abstract int |
nextInt()
Get a random integer between Integer.MIN_VALUE to Integer.MAX_VALUE (both inclusive).
|
int |
nextInt(int bound)
Returns a random non-negative integer below the given bound, or 0 if the bound is 0 or
negative.
|
abstract long |
nextLong()
Get a random long between Long.MIN_VALUE to Long.MAX_VALUE (both inclusive).
|
long |
nextLong(long bound)
Exclusive on bound (which must be positive), with an inner bound of 0.
|
int |
nextSignedInt(int outerBound)
Returns a random non-negative integer between 0 (inclusive) and the given bound (exclusive),
or 0 if the bound is 0.
|
long |
nextSignedLong(long outerBound)
Exclusive on bound (which may be positive or negative), with an inner bound of 0.
|
int[] |
randomOrdering(int length)
Generates a random permutation of the range from 0 (inclusive) to length (exclusive).
|
int[] |
randomOrdering(int length,
int[] dest)
Generates a random permutation of the range from 0 (inclusive) to length (exclusive) and stores it in
the dest parameter, avoiding allocations.
|
<T> T[] |
randomPortion(T[] data,
T[] output)
Gets a random portion of data (an array), assigns that portion to output (an array) so that it fills as much as
it can, and then returns output.
|
<T> java.util.ArrayList<T> |
shuffle(java.util.Collection<T> elements)
Shuffles a
Collection of T using the Fisher-Yates algorithm and returns an ArrayList of T. |
<T> java.util.ArrayList<T> |
shuffle(java.util.Collection<T> elements,
java.util.ArrayList<T> buf)
Shuffles a
Collection of T using the Fisher-Yates algorithm and puts it in a buffer. |
<T> T[] |
shuffle(T[] elements)
Shuffle an array using the Fisher-Yates algorithm and returns a shuffled copy, freshly-allocated, without
modifying elements.
|
<T> T[] |
shuffle(T[] elements,
T[] dest)
Shuffle an array using the Fisher-Yates algorithm.
|
<T> java.util.List<T> |
shuffleInPlace(java.util.List<T> elements)
Shuffles a Collection of T items in-place using the Fisher-Yates algorithm.
|
<T> T[] |
shuffleInPlace(T[] elements)
Shuffles an array in-place using the Fisher-Yates algorithm.
|
protected static <T> void |
swap(T[] arr,
int pos1,
int pos2)
Mutates the array arr by switching the contents at pos1 and pos2.
|
abstract java.io.Serializable |
toSerializable()
Gets a view of this IRNG in a way that implements
Serializable , which may simply be this IRNG if it
implements Serializable as well as IRNG. |
public abstract int next(int bits)
bits
bits to represent.next
in interface IRNG
next
in interface RandomnessSource
bits
- an int between 1 and 32, both inclusivepublic abstract int nextInt()
public int nextInt(int bound)
public abstract long nextLong()
nextLong
in interface IRNG
nextLong
in interface RandomnessSource
public long nextLong(long bound)
nextLong()
; subclasses can generate two ints instead of one long if they prefer.public abstract boolean nextBoolean()
next(int)
to get 1 bit,
returning next(1) == 1
, but others will get much better results with a sign check by calling their choice
of nextInt()
or nextLong()
and returning nextInt() < 0
or nextLong < 0L
. For
example, an implementation that uses a linear congruential generator without truncating some lower bits will have
very-low-period results for the bottom bit (alternating true and false), but perfectly fine results from a sign
check. There are tested issues on the bottom (at least 2) bits of XoRoRNG
, but again not on a sign check.nextBoolean
in interface IRNG
public abstract double nextDouble()
(nextLong() & 0x1fffffffffffffL) * 0x1p-53
, which is recommended if
longs are fast to produce.nextDouble
in interface IRNG
public double nextDouble(double outer)
nextDouble
in interface IRNG
outer
- the outer exclusive bound as a double; can be negative or positivepublic abstract float nextFloat()
(nextInt() & 0xffffff) * 0x1p-24f
,
(nextLong() & 0xffffffL) * 0x1p-24f
, or next(24) * 0x1p-24f
, any of which can work when the
method they call is high-quality and fast. You probably would want to use nextInt() or next() if your
implementation is natively 32-bit and is slower at producing longs, for example.public float nextFloat(float outer)
public long nextSignedLong(long outerBound)
nextLong()
, where rejection sampling
would sometimes advance by one call, but other times by arbitrarily many more.
nextLong()
; subclasses that are better at generating ints can override this and generate two ints
instead of one long that needs separating internally.nextSignedLong
in interface IRNG
outerBound
- the outer exclusive bound; can be positive or negativepublic int nextSignedInt(int outerBound)
nextSignedInt
in interface IRNG
outerBound
- the outer bound (exclusive), can be negative or positivepublic int between(int min, int max)
min
and max
happen to be the same, min
is returned
(breaking the exclusive behavior, but it's convenient to do so).public long between(long inner, long outer)
inner
and outer
happen to be the same, inner
is returned
(breaking the exclusive behavior, but it's convenient to do so).
public double between(double min, double max)
public <T> T getRandomElement(T[] array)
getRandomElement
in interface IRNG
T
- the type of the returned objectarray
- the array to get an element frompublic <T> T getRandomElement(java.util.List<T> list)
LinkedList
or similar classes
that need to iterate one-by-one in their List.get(int)
method.getRandomElement
in interface IRNG
T
- the type of the returned objectlist
- the list to get an element frompublic <T> T getRandomElement(java.util.Collection<T> coll)
getRandomElement(Queue)
,
since Queue implements Collection and the older Queue-using implementation was probably less efficient.
getRandomElement(List)
whenever possible, or in some cases you can use
methods that get a random value on the Collection (or Map, in the case of OrderedMap) itself.getRandomElement
in interface IRNG
T
- the type of the returned objectcoll
- the Collection to get an element from; remember, Map does not implement Collectionprotected static <T> void swap(T[] arr, int pos1, int pos2)
arr
- an array of T; must not be nullpos1
- an index into arr; must be at least 0 and no greater than arr.lengthpos2
- an index into arr; must be at least 0 and no greater than arr.lengthpublic <T> T[] shuffle(T[] elements)
public <T> T[] shuffleInPlace(T[] elements)
shuffle(Object[], Object[])
.
shuffleInPlace
in interface IRNG
T
- can be any non-primitive type.elements
- an array of T; will be modifiedpublic <T> T[] shuffle(T[] elements, T[] dest)
shuffle
in interface IRNG
T
- can be any non-primitive type.elements
- an array of T; will not be modifieddest
- Where to put the shuffle. If it does not have the same length as elements
, this will
throw an IllegalArgumentException.dest
after modificationspublic <T> java.util.ArrayList<T> shuffle(java.util.Collection<T> elements)
Collection
of T using the Fisher-Yates algorithm and returns an ArrayList of T.
public <T> java.util.ArrayList<T> shuffle(java.util.Collection<T> elements, java.util.ArrayList<T> buf)
Collection
of T using the Fisher-Yates algorithm and puts it in a buffer.
The result is allocated if buf
is null or if buf
isn't empty,
otherwise elements
is poured into buf
.
shuffle
in interface IRNG
T
- can be any non-primitive type.elements
- a Collection of T; will not be modifiedbuf
- a buffer as an ArrayList that will be filled with the shuffled contents of elements;
if null or non-empty, a new ArrayList will be allocated and returnedbuf
public <T> java.util.List<T> shuffleInPlace(java.util.List<T> elements)
shuffle(Collection)
, which returns a List as well.
shuffleInPlace
in interface IRNG
T
- can be any non-primitive type.elements
- a Collection of T; will be modifiedpublic int[] randomOrdering(int length)
randomOrdering
in interface IRNG
length
- the size of the ordering to producepublic int[] randomOrdering(int length, int[] dest)
randomOrdering
in interface IRNG
length
- the size of the ordering to produce; the smaller of dest.length
and length will be useddest
- the destination array; will be modifiedpublic <T> T[] randomPortion(T[] data, T[] output)
nextLong()
, regardless of
the data being randomized.
LowStorageShuffler
, but without any object or array allocations.randomPortion
in interface IRNG
T
- can be any non-primitive type.data
- an array of T; will not be modified.output
- an array of T that will be overwritten; should always be instantiated with the portion lengthMath.min(output.length, data.length)
unique items have been put into it from datapublic abstract IRNG copy()
UnsupportedOperationException
or return a new
IRNG of the same type but with a random seed, with the latter meant as a partial defense against cheating.
copy
in interface RandomnessSource
public abstract java.io.Serializable toSerializable()
Serializable
, which may simply be this IRNG if it
implements Serializable as well as IRNG.
RNG
initialized by calling
RNG(long)
with nextLong()
if you are unable to save the current state of this IRNG and the
caller still needs something saved. This won't preserve the current state or the choice of IRNG implementation,
however, so it is simply a last resort in case you don't want to throw an exception.toSerializable
in interface IRNG
Serializable
view of this IRNG or a similar one; may be this
Copyright © Eben Howard 2012–2022. All rights reserved.