Random number generation
Objective #1: Use the Math.random static method for random number generation to create
simulations.
- It is technically impossible to create a truly random value with a computer since any available built-in method or process for creating a random value relies on some determinate mechanism such as the computer's system clock. So it is proper to call these values pseudorandom rather than random.
- The static method named random in the Math class can be used to create a random decimal value that is greater than or equal to 0.0 and less than 1.0.
For example, the following statement displays a random decimal value such as 0.34
System.out.println(Math.random());
- You can manipulate this returned value by turning it into an integer or "spreading out" the range of possible values. Here are some examples:
num = Math.random() * 6; // 0 <= num < 6 such as 0.11, 3.21, 5.99
num = Math.random() * 10; // 0 <= num < 10 such as 2.15, 7.73, 9.99
- By typecasting the result to an integer and truncating the decimal places, we can ensure that only whole numbers are produced as in:
num = (int) (Math.random() * 6); // 0, 1, 2, 3, 4, or 5
num = (int) (Math.random() * 2); // 0 or 1
num = (int) (Math.random() * 6) + 1; // 1, 2, 3, 4, 5, or 6 (simulated dice roll)
num = (int) (Math.random() * 2) + 1; // 1 or 2 (simulated coin flip)
num = (int) (Math.random() * 100) + 1; // 1 <= num <= 100
num = (int) (Math.random() * 10) - 4; // -4 <= num <= 5
be careful to use the extra set of parentheses in the examples above since
num = (int) Math.random() * 6 + 1; // always equals one
- The Math.floor method could be used instead of typecasting with the (int) cast operator as long as you store the returned value into a double variable. In the statement below you must assume that num is a double.
num = Math.floor(Math.random() * 6) + 1
- A general formula to use for generating a random integer over a range of values is
(int) (Math.random() * (HI - LO + 1)) + LO
where HI is the highest integer and LO is the lowest integer in the desired range of integer values.
- If you wanted something to occur based on a probability of say 40% in a Java game or simulation, then you could use the Math.random method like this
if (Math.random() < 0.4)
{
System.out.println("The event occurred.");
}
else
{
System.out.println("The event did not occur.");
}
- The Math.random value does not need to be seeded like some corresponding methods or functions in other computer languages.
- Be careful not to create a logic error when answering a question like the following.
Write a method that returns "win", "lose", or "draw" each 1/3 of the time.
public String gameOutcome()
{
if (Math.floor(Math.random() * 3) == 0)
{
return "win";
}
else if (Math.floor(Math.random() * 3 == 1)
{
return "lose";
}
return "draw";
}
The problem is that Math.random is being called twice and the conditional probability of a lose is not 1/3.
The method should be written the following way:
public String gameOutcome()
{
int prob = Math.floor(Math.random() * 3);
if (prob == 0)
{
return "win";
}
else if (prob == 1)
{
return "lose";
}
return "draw";
}
Objective #2: Use the Math.random static method in methods.
- You can create reusable methods that generate random values. For example,
public static int rollDice()
{
return (int) (Math.random() * 6) + 1;
}
- Here is a method that accepts parameters to simulate a dice roll where the dice has
public static int rollDice(int high)
{
return (int) (Math.random() * high) + 1;
}
- Here is a method that generates a random whole number between two positive integers
public static int generateRandom(int low, int high)
{
return (int) (Math.random() * (high - low + 1)) + low;
}
- Here is a method that generates a random whole number between two positive integers
public static int rollDice(int low, int high)
{
return (int) (Math.random() * (high - low + 1)) + low;
}
- You can also generate and return boolean values instead of integers
public static boolean flipCoin()
{
int num = (int) (Math.random() * 2) + 1;
if (num == 1)
{
return true;
}
return false;
}
- You can generate and return a boolean value based on a desired random percent or percentage. This example, accepts a parameter percent and returns a true percent% of the time.
public static boolean willItSnowOrNot(int percent)
{
int num = (int) (Math.random() * 100) + 1;
if (num <= percent)
{
return true;
}
return false;
}
or this version that accepts a double parameter instead of an int
public static boolean willItSnowOrNot(double percentage)
{
double num = Math.random();
if (num <= percent)
{
return true;
}
return false;
}
- Here's a method that uses a flag variable to count the number of consecutive flips of heads on a coin:
public static int numConsecutiveFlips()
{
boolean firstTailsFlip = false;
int count = 0; // number of consecutive heads
while (!firstTailsFlip)
{
int num = (int) (Math.random() * 2) + 1; // 1 for tails, 2 for heads
if (num == 1)
{
firstTailsFlip = true;
}
else
{
count++;
}
}
return count;
}
You will not be tested on the information below and it is not covered on the AP Computer Science exam.
Objective #2: Use the Random class for random number generation to create simulations.
- You can also create random numbers by using the Random class of the Java API library.
1 import java.util.Random;
2
3 public class RandomNumbers
4 {
5 public static void main(String[] args)
6 {
7 Random dice = new Random();
8 int diceRoll = dice.nextInt(6) + 1;
9 }
10 }
- On line #7 of the example above, the object named dice with the type Random is declared. The Random class's nextInt method is then used with an argument of 6 on line #8 to generate a pseudorandom number between or including 0 and 5. Since 1 is added to that value, a resulting value between or including 1 and 6 is stored into the int variable named diceRoll. To use a Random object, you must import the Random class with the import statement in line #1.
- The nextDouble method of the Random class can be used to generate pseudorandom floating-point numbers. The statement
double randomDecimal = dice.nextDouble();
would generate a random decimal value between 0 (inclusive) and 1 (exclusive).
- When you instantiate a Random object
you may specify a seed
value with
an "other" constructor.
Using the instantiation statement
Random dice = new Random(1);
rather than
Random dice = new Random();
causes the same sequence of pseudorandom values to be generated with nextInt or
nextDouble. Normally, you would not want a
game or a simulation program that uses random numbers to use the same exact
sequence of random numbers
every time the program executes. It would be boring and predictable for a
game to always play the same way. However, while your debugging a program
or testing the effect of other conditions and parameters, you may want to
control the sequence of random values so that the same exact sequence is used.
This helps you focus on the bug that you're trying to fix or focus on the
effect of the parameter or conditions that you are changing. Any positive
integer can be used in the constructor as the seed value.