If you want to generate random numbers in Java, the first thing you can think of is Math.random ()
.
However, the values obtained by this are uniformly distributed, and all the values appear with the same probability, so it is not suitable when you want to create the following dummy values.
--Test score ... The average score is most likely to appear, and the farther away from the average score, the less likely it is to appear. → ** Normal distribution ** --Annual household income ... Distribution that extends long to the right from the center of the graph → ** Lognormal distribution **
You can do your best to write the calculation formula (I did my best to write it), but since there was a library, let's use it.
Use nextGaussian
in java.util.Random
.
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class GaussianTest {
@Test
public void nextGaussianTest() {
Random random = new Random();
List<Double> results = IntStream.rangeClosed(1, 100000).boxed()
.map(i -> random.nextGaussian() * 20 + 50) //Standard deviation 20, mean 50
.collect(Collectors.toList());
printResults(results);
}
private void printResults(List<Double> results) {
for (int i = 0; i < 20; i++) {
int start = i * 5;
int end = (i + 1) * 5;
double ratio = results.stream().filter(val -> (val >= start && val < end)).count() / 100000d * 100;
System.out.println(start + "〜" + end + ": " + IntStream.rangeClosed(1, (int) ratio).mapToObj(val -> "■").collect(Collectors.joining("")));
}
}
}
The distribution looks like this.
0〜5:
5〜10: ■
10〜15: ■
15〜20: ■■
20〜25: ■■■
25〜30: ■■■■■
30〜35: ■■■■■■
35〜40: ■■■■■■■■
40〜45: ■■■■■■■■■
45〜50: ■■■■■■■■■
50〜55: ■■■■■■■■■
55〜60: ■■■■■■■■■
60〜65: ■■■■■■■■
65〜70: ■■■■■■
70〜75: ■■■■■
75〜80: ■■■
80〜85: ■■
85〜90: ■
90〜95: ■
95〜100:
# (* The number of spaces is adjusted to align the axes.)
Use the Apache Commons LogNormalDistribution
.
import org.apache.commons.math3.distribution.LogNormalDistribution;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class GaussianTest {
@Test
public void logNormalDistributionTest() {
double MU = 3.0; // ln(x)The larger the average μ of, the longer the right side of the graph
double SIGMA = 1.0; // ln(x)Standard deviation of σ The larger the graph, the wider the graph.
LogNormalDistribution distribution = new LogNormalDistribution(MU, SIGMA);
List<Double> results = IntStream.rangeClosed(1, 100000).boxed()
.map(i -> distribution.sample())
.collect(Collectors.toList());
printResults(results);
}
private void printResults(List<Double> results) {
//Abbreviation
}
}
The result is like this.
0〜5: ■■■■■■■■
5〜10: ■■■■■■■■■■■■■■■■
10〜15: ■■■■■■■■■■■■■■
15〜20: ■■■■■■■■■■■
20〜25: ■■■■■■■■
25〜30: ■■■■■■
30〜35: ■■■■■
35〜40: ■■■■
40〜45: ■■■
45〜50: ■■
50〜55: ■■
55〜60: ■■
60〜65: ■
65〜70: ■
70〜75: ■
75〜80: ■
80〜85:
85〜90:
90〜95:
95〜100:
keisan.casio.jp Normal distribution (graph) keisan.casio.jp Lognormal distribution (graph)
Recommended Posts