All Downloads are FREE. Search and download functionalities are using the official Maven repository.

squidpony.squidmath.IRNG Maven / Gradle / Ivy

Go to download

SquidLib platform-independent logic and utility code. Please refer to https://github.com/SquidPony/SquidLib .

There is a newer version: 3.0.6
Show newest version
package squidpony.squidmath;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * Interface for full-featured random number generators to implement (it does more than, and includes all of,
 * {@link RandomnessSource}). It's a stripped down version of the original {@link RNG}. It's an interface instead of a
 * class, to be able to implement using random number generators that don't implement RandomnessSource, like libGDX's
 * RandomXS128, or to hard-code the RandomnessSource to avoid overhead or use some methods differently (like preferring
 * 32-bit math or optimizing for GWT, as {@link GWTRNG} does). You can use any IRNG as a RandomnessSource, but that only
 * allows its {@link #next(int)}, {@link #nextLong()}, and {@link #copy()} methods to be called, so most usage that can
 * benefit from methods like {@link #nextDouble()} or {@link #between(int, int)} should prefer IRNG for parameter types.
 *
 * @author Eben Howard - http://squidpony.com - [email protected]
 * @author Tommy Ettinger
 * @author smelC
 */
public interface IRNG extends RandomnessSource {

    /**
     * Get up to 32 bits (inclusive) of random output; the int this produces
     * will not require more than {@code bits} bits to represent.
     *
     * @param bits an int between 1 and 32, both inclusive
     * @return a random number that fits in the specified number of bits
     */
    int next(int bits);

    /**
     * Get a random integer between Integer.MIN_VALUE to Integer.MAX_VALUE (both inclusive).
     *
     * @return a 32-bit random int.
     */
    int nextInt();

    /**
     * Returns a random non-negative integer below the given bound, or 0 if the bound is 0 or
     * negative.
     *
     * @param bound the upper bound (exclusive)
     * @return the found number
     */
    int nextInt(final int bound);

    /**
     * Get a random long between Long.MIN_VALUE to Long.MAX_VALUE (both inclusive).
     *
     * @return a 64-bit random long.
     */
    long nextLong();
    
    /**
     * Returns a random long below the given bound, or 0 if the bound is 0 or
     * negative.
     *
     * @param bound the upper bound (exclusive)
     * @return the found number
     */
    long nextLong(final long bound);

    /**
     * Get a random bit of state, interpreted as true or false with approximately equal likelihood.
     * @return a random boolean.
     */
    boolean nextBoolean();

    /**
     * Gets a random double between 0.0 inclusive and 1.0 exclusive.
     * This returns a maximum of 0.9999999999999999 because that is the largest double value that is less than 1.0 .
     *
     * @return a double between 0.0 (inclusive) and 0.9999999999999999 (inclusive)
     */
    double nextDouble();
    /**
     * This returns a random double between 0.0 (inclusive) and outer (exclusive). The value for outer can be positive
     * or negative. Because of how math on doubles works, there are at most 2 to the 53 values this can return for any
     * given outer bound, and very large values for outer will not necessarily produce all numbers you might expect.
     *
     * @param outer the outer exclusive bound as a double; can be negative or positive
     * @return a double between 0.0 (inclusive) and outer (exclusive)
     */
    double nextDouble(final double outer);

    /**
     * Gets a random float between 0.0f inclusive and 1.0f exclusive.
     * This returns a maximum of 0.99999994 because that is the largest float value that is less than 1.0f .
     *
     * @return a float between 0f (inclusive) and 0.99999994f (inclusive)
     */
    float nextFloat();
    /**
     * This returns a random float between 0.0f (inclusive) and outer (exclusive). The value for outer can be positive
     * or negative. Because of how math on floats works, there are at most 2 to the 24 values this can return for any
     * given outer bound, and very large values for outer will not necessarily produce all numbers you might expect.
     *
     * @param outer the outer exclusive bound as a float; can be negative or positive
     * @return a float between 0f (inclusive) and outer (exclusive)
     */
    float nextFloat(final float outer);
    /**
     * Exclusive on bound (which may be positive or negative), with an inner bound of 0.
     * If bound is negative this returns a negative long; if bound is positive this returns a positive long. The bound
     * can even be 0, which will cause this to return 0L every time. This uses a biased technique to get numbers from
     * large ranges, but the amount of bias is incredibly small (expected to be under 1/1000 if enough random ranged
     * numbers are requested, which is about the same as an unbiased method that was also considered). It may have
     * noticeable bias if the generator's period is exhausted by only calls to this method. Unlike all unbiased methods,
     * this advances the state by an equivalent to exactly one call to {@link #nextLong()}, where rejection sampling
     * would sometimes advance by one call, but other times by arbitrarily many more.
     * 
* Credit for this method goes to Rafael Baptista's blog, * with some adaptation for signed long values and a 64-bit generator. This method is drastically faster than the * previous implementation when the bound varies often (roughly 4x faster, possibly more). It also always gets at * most one random number, so it advances the state as much as {@link #nextInt(int)} or {@link #nextLong()}. * @param bound the outer exclusive bound; can be positive or negative * @return a random long between 0 (inclusive) and bound (exclusive) */ long nextSignedLong(long bound); /** * Returns a random non-negative integer between 0 (inclusive) and the given bound (exclusive), * or 0 if the bound is 0. The bound can be negative, which will produce 0 or a negative result. *
* Credit goes to Daniel Lemire, http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/ * * @param bound the outer bound (exclusive), can be negative or positive * @return the found number */ int nextSignedInt(final int bound); /** * Returns a value between min (inclusive) and max (exclusive) as ints. *
* The inclusive and exclusive behavior is to match the behavior of the similar * method that deals with floating point values. *
* If {@code min} and {@code max} happen to be the same, {@code min} is returned * (breaking the exclusive behavior, but it's convenient to do so). * * @param min * the minimum bound on the return value (inclusive) * @param max * the maximum bound on the return value (exclusive) * @return the found value */ int between(int min, int max); /** * Returns a value between min (inclusive) and max (exclusive) as longs. *
* The inclusive and exclusive behavior is to match the behavior of the similar * method that deals with floating point values. *
* If {@code min} and {@code max} happen to be the same, {@code min} is returned * (breaking the exclusive behavior, but it's convenient to do so). * * @param min * the minimum bound on the return value (inclusive) * @param max * the maximum bound on the return value (exclusive) * @return the found value */ long between(long min, long max); /** * Returns a value from a uniform distribution from min (inclusive) to max * (exclusive). * * @param min the minimum bound on the return value (inclusive) * @param max the maximum bound on the return value (exclusive) * @return the found value */ double between(double min, double max); /** * Returns a random element from the provided array and maintains object * type. * * @param the type of the returned object * @param array the array to get an element from * @return the randomly selected element */ T getRandomElement(T[] array); /** * Returns a random element from the provided list. If the list is empty * then null is returned. * * @param the type of the returned object * @param list the list to get an element from * @return the randomly selected element */ T getRandomElement(List list); /** * 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). If you give this a Set, it should be a LinkedHashSet or some form of sorted * Set like TreeSet if you want predictable results. Any List or Queue should be fine. Map does not implement * Collection, thank you very much Java library designers, so you can't actually pass a Map to this, though you can * pass the keys or values. If coll is empty, returns null. *
* Requires iterating through a random amount of coll's elements, so performance depends on the size of coll but is * likely to be decent, as long as iteration isn't unusually slow. This replaces {@code getRandomElement(Queue)}, * since Queue implements Collection and the older Queue-using implementation was probably less efficient. *
* You should generally prefer {@link #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. * @param the type of the returned object * @param coll the Collection to get an element from; remember, Map does not implement Collection * @return the randomly selected element */ T getRandomElement(Collection coll); /** * Shuffle an array using the Fisher-Yates algorithm and returns a shuffled copy, freshly-allocated, without * modifying elements. *
* Wikipedia has more on this algorithm. * * @param elements an array of T; will not be modified * @param can be any non-primitive type. * @return a shuffled copy of elements */ T[] shuffle(final T[] elements); /** * Shuffles an array in-place using the Fisher-Yates algorithm. * If you don't want the array modified, use {@link #shuffle(Object[], Object[])}. *
* Wikipedia has more on this algorithm. * * @param elements an array of T; will be modified * @param can be any non-primitive type. * @return elements after shuffling it in-place */ T[] shuffleInPlace(T[] elements); /** * Shuffle an array using the Fisher-Yates algorithm. DO NOT give the same array for both elements and * dest, since the prior contents of dest are rearranged before elements is used, and if they refer to the same * array, then you can end up with bizarre bugs where one previously-unique item shows up dozens of times. If * possible, create a new array with the same length as elements and pass it in as dest; the returned value can be * assigned to whatever you want and will have the same items as the newly-formed array. *
* Wikipedia has more on this algorithm. * * @param elements an array of T; will not be modified * @param can be any non-primitive type. * @param dest Where to put the shuffle. If it does not have the same length as {@code elements}, this will use the * randomPortion method of this class to fill the smaller dest. MUST NOT be the same array as elements! * @return {@code dest} after modifications */ T[] shuffle(T[] elements, T[] dest); /** * Shuffles a {@link Collection} of T using the Fisher-Yates algorithm and returns an ArrayList of T. *
* Wikipedia has more on this algorithm. * @param elements a Collection of T; will not be modified * @param can be any non-primitive type. * @return a shuffled ArrayList containing the whole of elements in pseudo-random order. */ ArrayList shuffle(Collection elements); /** * Shuffles a {@link Collection} of T using the Fisher-Yates algorithm and puts it in a buffer. * The result is allocated if {@code buf} is null or if {@code buf} isn't empty, * otherwise {@code elements} is poured into {@code buf}. *
* Wikipedia has more on this algorithm. * @param elements a Collection of T; will not be modified * @param buf 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 returned * @param can be any non-primitive type. * @return a shuffled ArrayList containing the whole of elements in pseudo-random order, which may be {@code buf} */ ArrayList shuffle(Collection elements, /*@Nullable*/ ArrayList buf); /** * Shuffles a Collection of T items in-place using the Fisher-Yates algorithm. * This only shuffles List data structures. * If you don't want the array modified, use {@link #shuffle(Collection)}, which returns a List as well. *
* Wikipedia has more on this algorithm. * * @param elements a Collection of T; will be modified * @param can be any non-primitive type. * @return elements after shuffling it in-place */ List shuffleInPlace(List elements); /** * Generates a random permutation of the range from 0 (inclusive) to length (exclusive). * Useful for passing to OrderedMap or OrderedSet's reorder() methods. * * @param length the size of the ordering to produce * @return a random ordering containing all ints from 0 to length (exclusive) */ int[] randomOrdering(int length); /** * Generates a random permutation of the range from 0 (inclusive) to length (exclusive) and stores it in * the dest parameter, avoiding allocations. * Useful for passing to OrderedMap or OrderedSet's reorder() methods. * * @param length the size of the ordering to produce * @param dest the destination array; will be modified * @return dest, filled with a random ordering containing all ints from 0 to length (exclusive) */ int[] randomOrdering(int length, int[] dest); /** * 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. Will only use a given position in the given data at most once. * * @param data an array of T; will not be modified. * @param output an array of T that will be overwritten; should always be instantiated with the portion length * @param can be any non-primitive type. * @return output, after {@code Math.min(output.length, data.length)} unique items have been put into it from data */ T[] randomPortion(T[] data, T[] output); /** * 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. The copy will not share references with this IRNG. If this IRNG does not * permit copying itself, it is suggested to either throw an {@link 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. * * @return a copy of this IRNG */ IRNG copy(); /** * Gets a view of this IRNG in a way that implements {@link Serializable}, which may simply be this IRNG if it * implements Serializable as well as IRNG. *
* For implementors: It is suggested to return an {@link RNG} initialized by calling * {@link RNG#RNG(long)} with {@link #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. * @return a {@link Serializable} view of this IRNG or a similar one; may be {@code this} */ Serializable toSerializable(); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy