I am making a java game, and I have heard that when I use the Math.random() method it has greater chances of generating some numbers.

is this true, and if so how can I fix it. If not which method generates numbers unequally?

The Java random number generator, like in all other languages, actually generates pseudorandom numbers. This means the numbers are not truly random, but appear to be so (and for a game are more than sufficiently random). The numbers are not truly random due to the nature of computers: they do …

Just check the Javadocs for Random. There is such a method for integers.

Since the numbers are generated uniformly, that means that for each number in n numbers, the probability of its occurrence is 1/n. Their frequencies should therefore be the same over the long run.

That looks pretty random to me. Were you expecting a perfect flat line (equal occurrences of each value)? - because that would NOT be random!
And as dmanw100 said - Random has a method for random ints in a range

The code I am using currently is

``int rand = new Random ().nextInt(length - 1);``

and when I generate many results it isn't even close to uniform distribution

a number from 0 and 999

generated 600000 times and graphed

whats the value of your length?

and as JamesCherrill …

FYI: If you want to do that, the Collections class has a shuffle method to do it for you.

## All 19 Replies

The Java random number generator, like in all other languages, actually generates pseudorandom numbers. This means the numbers are not truly random, but appear to be so (and for a game are more than sufficiently random). The numbers are not truly random due to the nature of computers: they do not have an operation that, when given the same input, produces different output. For this reason they cannot (easily) produce random numbers; instead a linear congruential generator is normally used. This produces the appearance of randomness, while actually being programmatically generated.

For your question it is important to note that the Java Random class returns uniformly distributed pseudorandom numbers (the link is for nextInt()). This means that no number has a greater chance of being generated than another (or if it does, the chance is negligible).

Hope this helps!

Using the Random class is there a way to limit the range of the random number, because I need numbers between like 1 and 100. Also I am making this for a data game, and I am wondering if I use the Math.ceil(Math.random() * 100) which number is generated least frequently?

Just check the Javadocs for Random. There is such a method for integers.

Since the numbers are generated uniformly, that means that for each number in n numbers, the probability of its occurrence is 1/n. Their frequencies should therefore be the same over the long run.

The code I am using currently is

``int rand = new Random ().nextInt(length - 1);``

and when I generate many results it isn't even close to uniform distribution

a number from 0 and 999

generated 600000 times and graphed

That looks pretty random to me. Were you expecting a perfect flat line (equal occurrences of each value)? - because that would NOT be random!
And as dmanw100 said - Random has a method for random ints in a range

The code I am using currently is

``int rand = new Random ().nextInt(length - 1);``

and when I generate many results it isn't even close to uniform distribution

a number from 0 and 999

generated 600000 times and graphed

whats the value of your length?

and as JamesCherrill said, if you did all the generations to 600000 and all numbers where shown and getting repeated that would not be random would it?

The best i can suggest is say now you need the game to know for sure that sometime it will generate a large number but you cant rely on it happening every time then why not set it so your random number will for example not generate a number from 500-900
then have another that will generate from 0-499. Then make another random number between 1 and 2 and have an if statement which if the random is 1 it will use the 0-499 aand if its 2 it will use 500-900. This should help to get more of all the numbers being generated in your 600000 genarations

this program print random values from 100 to 0 and not repeats any printing value
check that

``````public class Main {
public static void main(String[] args)
{
int RandomNumbers =100;
ArrayList<Integer> numbers = new ArrayList<Integer>();
int number = (int)(Math.random() * RandomNumbers);
for (int i = 0; i < RandomNumbers-1; i++) {
do{
number = (int)(Math.random() * 100);
}while(numbers.indexOf(number)!=-1);

}
for(Integer i: numbers){
System.out.println(i);
}
}
}``````

FYI: If you want to do that, the Collections class has a shuffle method to do it for you.

this program print random values from 100 to 0 and not repeats any printing value
check that

that's not random... A random distribution can have multiple of the same number in it :)

I think it's intended to have each of the numbers 0-n, but in a random order, but it's a spectacularly inefficient way to do it.

that's not random... A random distribution can have multiple of the same number in it :)

I think what James meant is you could populate it manualy with numbers from 0 to 100 and THEN shuffle it, which would give the same effect your program did without possibly waiting a while before hitting the last few numbers that are left towards the end of your algorithm.

Although having a counter keep track of how many tries it took for each number you add to your collection would be interesting and a good study for sirlink99's question.

So If I use the Math.ceil(Math.random() * n)

n being the number of choices, I get a fairly equal number of times it generates each number?

What if I would like to stack the odds of something? Which number should I choose if I use Math.random? I would like it to be "invisible", as if the user reads the code they wouldn't know that some numbers are generated less often, unless they have some computer knowledge?

Thanks

Math.ceil(Math.random() * n)

will generate a random double in the range [0.0,1.0). This means the value in the Math.ceil() call will be between about .999*n and 0. Again, check the JavaDocs. They say

Returned values are chosen pseudorandomly with (approximately) uniform distribution...

If you would like to increase the occurrence of certain events, determine what probabilities you would like to assign to each. Then generate a random double value. Use this value to determine which event to choose.

I believe you missed that I multiply by n

Math.random() will generate a number between 0 and 1. If I multiply by lets say 5 and the random number is 0.1 then my answer will be 1 (0.1 * 5 = 0.5 ceiled = 1).

if the number is 0.5 then my number will be 3 (0.5 * 5 = 2.5 ceiled = 3).

Also I would like to use just Math.random(). which numbers occur the least often?

As I said

the value in the Math.ceil() call will be between about .999*n and 0

This means the final value will be an integer from 0-n.

No number occurs the least often (or they all do, depending on how you look at it). The Math random() method returns a (roughly) uniformly distributed random double.

If you want an int 0 - n, use Random's method
nextInt(int n)
Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence.

Alright here is how to affect your random() result the way you want if i understood correctly what you want.

Lets say i generate a first number, between 0 & .999, then according to predetermined percentages, i set different variables to control the value of my next random() call.

fastest way to do a simple version is this :

``(Math.random()>0.25?Math.random()*20+80:Math.random()*80)``

this would generate a number between 80 and 99.99~ for 75% of its execution, the other 25% will be between 0 and 79.99~

if youd like to get more control then this structure could become heavy quite quickly.
Id suggest setting a if/elseif structure, setting min and max variables...

``````public double getRandom(){
double min = 0;
double max = 1;
double myChance = Math.random();

if(myChance > 0.5){
//i have 50% chance of being here
max=25;
min=15;
}
else if(myChance > 0.25){
//i have 25% chance of being here
max=42;
min=38;
}
else if(myChance > 0.1){
//i have 15% chance of being here
max=60;
min=50;
}
else if(myChance > 0.01){
//i have 9% chance of being here
max=75;
min=75;
}
else{
//i have 1% chance of being here
max=100;
min=100;
}
return (Math.random()*(max-min)+min);
}``````

i hope this helps

If you are looking for random numbers with a bell-shaped distribution - ie a central value that's most likely, with values becoming less and less likely as you move away from the central value, use Random's public double nextGaussian()

thanks. I will try it

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, learning, and sharing knowledge.