1

Given that min = 0.00, max = 1400.00, mean = 150.50, standard deviation = 25.00, how does one generates a random value base on these statistics? From my understanding is that this graph is a skewed graph however I am not too sure if it's a log-normal distributed. However from my understanding so far, the following piece of code returns a value that is from a normal distribution.

private static int generateValue(double mean, double stdDev) {
 return (rand.nextGaussian() * stdDev) + mean);
}
pjs
20k4 gold badges30 silver badges64 bronze badges
asked Nov 10, 2021 at 9:38
5
  • 1
    This is a statistical modeling question, not a programming one. Your distribution can't be either normal or log-normal because both of those have infinite support and you specified finite min and max. You need to identify a distribution which is capable of meeting all four constraints simultaneously, which is non-trivial and may not be feasible. Example: we can rule out triangular distributions because mean = (min + mode + max) / 3. With your constraints solving for the mode yields -948.5, but the mode must be a value between min and max so no such triangle exists. Commented Nov 10, 2021 at 15:58
  • understand, however, given these values above, is there a way to properly get a randomly generated value? Commented Nov 11, 2021 at 12:17
  • Not without knowing what distribution to generate from. That’s why I said "You need to identify a distribution..." Commented Nov 11, 2021 at 15:32
  • hi @pjs, given that the distribution is a continuous distribution, is it possible? Commented Nov 12, 2021 at 14:25
  • Figured out a way to do it using a scaled beta distribution. I'm not a java guy for the past 15 years (don't even have it installed on my system), but I can explain with python if you're interested. Commented Nov 12, 2021 at 18:33

2 Answers 2

1

One way to do this is to find a naturally bounded distribution which has mean and variance characterized by two parameters. That reduces the problem from trying to meet four constraints (min, max, mean, and s.d.) simultaneously to solving two equations (for mean and s.d.) in terms of two parameters. The beta distribution meets those needs. It's defined on the range [0, 1], but that can be easily adjusted to your problem by scaling results by 1400. I used the Wikipedia link provided above to refresh my memory on the formulae for mean and variance of a beta, and then headed over to the solver at Wolfram|Alpha to enter enter the formulae using a mean of 150.5/1400 and standard deviation of 25/1400. This yielded solutions of α=32.237057 and β=267.642543, so you can fulfill your requirements by generating values X = 1400 * beta(α, β) using the derived parameter values.

I haven't used Java for over 15 years and don't have it on my machine, so I tested this using python to confirm the parameterization:

from scipy.stats import beta
import math
a = 32.237057
b = 267.642543
n = 100_000_000
mean, var = beta.stats(a, b, moments='mv')
print( f"mean = {mean * 1400}, std dev = {math.sqrt(var) * 1400}" )

which produces

mean = 150.50000000000003, std dev = 25.000000000000004

I'd say that's about as close as you can ask for using floating point arithmetic. I then tried actual generation:

r = beta.rvs(a, b, size=n) * 1400
print( f"For n={n} min and max are {min(r)} and {max(r)}, respectively")

with output:

For n=100000000 min and max are 45.22697720545599 and 327.87270125710194, respectively

You might consider the empirical maximum to be low, but note that 1400 is just shy of 50σ above the mean. Chebyshev's inequality gives a very weak non-parametric upper bound on the probability of getting such a value—it's less than 1/2500. In many cases, including this one, the actual probability is much less than Chebyshev's bound. In other words, the probability of getting an outcome approaching 1400 is essentially zero.

A quick Google search dug up class BetaDistribution available through the Apache Commons library, so it should be straightforward for you to map this approach to Java.

answered Nov 12, 2021 at 20:32
Sign up to request clarification or add additional context in comments.

1 Comment

hi @pjs, i really appreciate the thorough explanation. I will look on the links that you've provided and use the BetaDistribution to solve my question. thank you so much
0

you can use a do while or just while loop and then you can simply use if statements to set the parameters for your numbers and generate a random number!

import java.util.Random;
class GenerateRandom {
public static void main( String args[] ) {
 Random rand = new Random(); //instance of random class
 int upperbound = 25;
 //generate random values from 0-24
 int int_random = rand.nextInt(upperbound); 
 double double_random=rand.nextDouble();
 float float_random=rand.nextFloat();
 
 System.out.println("Random integer value from 0 to" + (upperbound-1) + " : "+ int_random);
 System.out.println("Random float value between 0.0 and 1.0 : "+float_random);
 System.out.println("Random double value between 0.0 and 1.0 : "+double_random);
}
answered Nov 10, 2021 at 9:42

1 Comment

thanks but this code is for the normal generation of a random numbers, what I'm looking at is a log-normal distributed value instead

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.