Reveance Posted March 29, 2017 Share Posted March 29, 2017 (edited) I might make this more organized and add some more algorithms if I find a need to. I originally made this after a distribution that resembles reaction times and so it'd probably be useful after conditional waits and stuff as a simulation of reaction time...but generally also more believable for clicking. This is what the distribution looks like after generating ~5000 clicks with random between 200 and 1000: Oh, and it's also important to note that if you are going to use this, you'd need a larger random span than normal, for example 200-1000, because as you can see in the graph the chance is already very low at the center. Code V.1 import java.util.Random; /** * Generates randoms by using a generalized extreme value distribution * * @author Reveance * */ public class GEVRandom { private Random random = null; public GEVRandom() { this(new Random()); } public GEVRandom(Random random) { this.setRandom(random); } /** * Attempts to make a proper distribution of randoms where the function * returns the numbers at the tails approximately 0 times when run for * ~100000 times. * * @param min * @param max * @return A random value between min and max based on the distribution */ public int between(int min, int max) { int span = (max - min); int rand; do { double val = getRandomDouble((span / 3) - (span / 7), span / 14) + min; rand = (int) Math.round(val); } while (rand < min || rand > max); return rand; } public double getRandomDouble(double location, double scale) { double u = getRandom().nextDouble(); double x = getQuantile(u, location, scale); return x; } public double getQuantile(double p, double a, double b) { return a - b * Math.log(-Math.log(p)); } public Random getRandom() { return random; } public void setRandom(Random random) { this.random = random; } } I updated the class, this is actually the real Generalized extreme value distribution, which also allows for changing the shape (e.g. putting the top to the end etc.). This is what it looks like after 50000 calls to between(0, 1800): And here's the updated code: import java.util.Random; /** * Generates randoms by using a generalized extreme value distribution * * @author Reveance * */ public class GEVDRandom { private Random random = null; public GEVDRandom() { this(new Random()); } public GEVDRandom(Random random) { this.setRandom(random); } /** * Attempts to make a proper distribution of randoms where the function * returns the numbers at the tails approximately 0 times when run for * ~100000 times. * * @param min * @param max * @return A random value between min and max based on the distribution */ public int between(int min, int max) { int span = (max - min); int rand; do { double val = getRandomDouble(0 + span / 7, span / 14, -0.00000001); rand = (int) Math.round(val); } while (rand < min || rand > max); return rand; } public double getRandomDouble(double location, double scale, double shape) { double u = getRandom().nextDouble(); double x = getQuantile(u, location, scale, shape); return x; } public double getQuantile(double p, double u, double o, double e) { double log1dp = Math.log10(1 / p); if (e == 0) { return u + o * Math.log10(1 / log1dp); } else { return u + o * (Math.pow(log1dp, -e) - 1) / e; } } public Random getRandom() { return random; } public void setRandom(Random random) { this.random = random; } } Edited April 4, 2017 by Reveance Code update 2 Quote Link to comment Share on other sites More sharing options...
Reveance Posted March 29, 2017 Author Share Posted March 29, 2017 Updated the algorithm for better results Quote Link to comment Share on other sites More sharing options...