passing variable from random number generator class - java

Instead of writing:
Random randomGenerator = new Random();
for (int idx = 5; idx <= 15; ++idx){
int randomInt = randomGenerator.nextInt(1);
each time I need a random number in a function, Is it possible to just pass or call the result from a random number generator class into the function?
For Example, I have one function in particular which is receiving variables from another class
favoriteTracks(String fromExampleClass1, String fromExampleClass1again)
could I do
favoriteTracks(String fromExampleClass1, String fromExampleClass1again, Long fromRNGclass)
for clarification:
My one function "favoriteTracks" requires variables passed from "ExampleClass1".
At the same time, I want it to receive a random number as a variable (or call it, whichever is easiest). generated in another class by
public static long randomNum(){
Random randomGenerator = new Random();
for (int idx = 5; idx <= 15; ++idx){
int randomInt = randomGenerator.nextInt(1);

The simplest approach would be to encapsulate the behaviour you want in a singleton:
public class MyRandom {
public static final MyRandom myRandom = new MyRandom();
private Random randomGenerator = new Random();
public int makeRandom() {
// put your for loop here if you want, but it is not necessary
return 5 + randomGenerator.nextInt(11);
}
}
somewhere else ...
x = MyRandom.myRandom.makeRandom();
That looks like a possible solution for what you are trying to do.

Related

Java Random Generator's seed producing different outputs

While trying to create a Coin object class using two specific seeds passed into the object upon creation, I have noticed that when passing in the seed to an int "seed", the seed variable produces a different variable than just inputting the specific number into the random number generator. Here's some code from the Coin class:
public int headCount;
public int tailCount;
public int seed;
public Coin( int n ){
seed = n;
headCount = 0;
tailCount = 0;
}
public Random flipGenerator = new Random(seed);
public String flip(){
String heads = "H";
String tails = "T";
boolean nextFlip = flipGenerator.nextBoolean();
if (nextFlip == true)
{
headCount++;
return heads;
}
if (nextFlip == false)
{
tailCount++;
return tails;
}
return null;
}
Here's from the file that creates and prints the Coin objects:
Coin coin1 = new Coin( 17 );
Coin coin2 = new Coin( 13 );
The code in that file prints out the outcome of the random flips 20 times using the 17 seed, 10 times with the 13 seed and finally 35 times with the 17 seed again. However the output is incorrect when using
public Random flipGenerator = new Random(seed);
as opposed to
public Random flipGenerator = new Random(17);
or
public Random flipGenerator = new Random(13);
Why is this happening?
Instance fields are initialized before the constructor is called.
In terms of execution order, this code:
public int headCount;
public int tailCount;
public int seed;
public Coin( int n ){
seed = n;
headCount = 0;
tailCount = 0;
}
public Random flipGenerator = new Random(seed);
is functionally equivalent to this:
public int headCount;
public int tailCount;
public int seed;
public Random flipGenerator = new Random(seed);
public Coin( int n ){
seed = n;
headCount = 0;
tailCount = 0;
}
In Java, any fields which were not explicitly initialized are given a value of zero/null/false, so you are always doing flipGenerator = new Random(0). By the time you initialize seed in your constructor, the Random object has already been created. The fact that the instance field was declared after the constructor is irrelevant, because all instance fields and their initialization expressions are executed before a constructor is invoked.
Whenever you initialize the Coin class it will use 0 as the seed. Regardless if you put the flipGenerator initialization below the constructor, it will still get called in the constructor since it is an instance variable.
Coin coin1 = new Coin( 17 );
Coin coin2 = new Coin( 13 );
This code is using 0 because, by the time you pass the seed, the flipGenerator was initialized with the default seed of 0.
You need to do this
public int headCount;
public int tailCount;
public int seed;
public Random flipGenerator;
public Coin( int n ){
seed = n;
headCount = 0;
tailCount = 0;
flipGenerator = new Random(seed);
}
...
}

Java RNG seeding

My question concerns the Java RNG; use the following code:
for (int s = 0; s < 600; s++) {
Random r = new Random(s);
System.out.println(r.nextDouble());
System.out.println(r.nextDouble() + "\n-----");
}
This will result in 600 random numbers being generated. I know this is a bit odd, but I require a new random number generator each time in my actual project. The seed I receive is sequential. The first random double that is generated is extremely close for any of the seeds, is this because of the linear congruential formula that is used as initialization?
The second double generated actually looks like it is actually properly random, is this safe to assume so? Is it OK practice to first generate an unused random number, and after that moment start to use it for the actual reason it was created?
Thank you in advance
EDIT:
Let me clarify:
int possibleRoutes = 7;
void handlePacket(Packet p) {
int chosenRoute = p.hash % possibleRoutes;
// ...Other code...
}
vs.
int possibleRoutes = 7;
void handlePacket(Packet p) {
Random r = new Random(p.hash);
int chosenRoute = r.nextInt() % possibleRoutes;
// ...Other code...
}
}
vs.
int possibleRoutes = 7;
void handlePacket(Packet p) {
Random r = new Random(p.hash);
r.nextInt();
int chosenRoute = r.nextInt() % possibleRoutes;
// ...Other code...
}
A guarantee is that each packet must take the same route. The packet hash is inherently sequential at the moment. There are too many possible hashes to keep any type of state to speed this up.
why do you give a special number as a seed? just leave it empty, so the Random constructor will choose a seed for you.
for (int s = 0; s < 600; s++) {
Random r = new Random();
System.out.println(r.nextDouble());
System.out.println(r.nextDouble() + "\n-----");
}
see Role of seed in random number generation
Call the default constructor which uses the nanoTime as a seed. This way you won't need to generate a new seed to create your object each iteration.
//loop through number of numbers needed
for(int i = 0; i < 100; i +)
//Calls default constructor
Random r = new Random();
System.out.println(r.nextDouble()*.5);
An alternative is to use a master random to seed all the subsiduary randoms in the loop:
Random masterRand = new Random();
for (int s = 0; s < 600; s++) {
Random r = new Random(masterRand.nextLong());
System.out.println(r.nextDouble());
System.out.println(r.nextDouble() + "\n-----");
}

How to call if statements on arrays in java

import java.util.Random;
public class Console {
public static void main(String[] args) {
while (3>2) {
Random rand1 = new Random();
Random rand2 = new Random();
Random rand3 = new Random();
Random rand4 = new Random();
Random rand5 = new Random();
Random rand6 = new Random();
Random rand7 = new Random();
Random rand8 = new Random();
int onenum = rand1.nextInt(2);
int twonum = rand2.nextInt(2);
int threenum = rand3.nextInt(2);
int fournum = rand4.nextInt(2);
int fivenum = rand5.nextInt(2);
int sixnum = rand6.nextInt(2);
int sevennum = rand7.nextInt(2);
int eightnum = rand8.nextInt(2);
int binary[] = {onenum, twonum, threenum, fournum, fivenum, sixnum, sevennum, eightnum};
System.out.println(java.util.Arrays.toString(binary));
How can I check if, say the first number of the binary array is one?
Currently if I run, i get an output of like {1, 0, 1} ect
You can do it by using an index to access to an element in a specific position of an array:
if (someArray[position] == something)
In your case, to check the first element, it would be:
if (binary[0] == 1)
Note:
Indices in most programming languages start with 0 so the first element would be in the index 0 of the array. The second in the index 1. And so on.
Gosh i can reduce your code so much!! Analyse and see that this code does same as yours.
while (3>2) {
Random rand = new Random();
int[] binary = new int[8];
for(int i=0;i<8;i++)
binary[i] = rand.nextInt(2);
if(binary[0] == 1)
//if first number is 1
}
You can simply do:
if(binary[0] == 1) {
//do something
}
0 is the first element in array, since the fact of Arrays is a 0 based.
Side note: You don't have to declare a new object from Random to get a number, you can use the same object like:
Random rand = new Random();
int onenum = rand.nextInt(2);
int twonum = rand.nextInt(2);
int threenum = rand.nextInt(2);
// and so on
Just do this to check if first element equals to 1:
if (binary[0] == 1)
{
//do whatever here..
}
Other issues about your codes
I realized you use while (3>2). You can use while(true) if you want it to be an infinite loop.
You only need to create one random object to create multiple random numbers. Do it like this..
.
Random rnd = new Random();
oneNum = rnd.nextInt(2);
twoNum = rnd.nextInt(2);
threeNum = rnd.nextInt(2);
You can even do it this way (using an array to store the random numbers):
Random rnd = new Random();
int[] num = new int[8];
for (int x=0; x<num.length; x++)
num[x] = rnd.nextInt(2);

How to use Random.nextInt()?

I try to get random integer but i get nullpointerexception. I want to get ArrayList with first element what i add at the beggining and this is correct. Next elements i want to get three random String from answersdata[10]. I checked that in answersdata are elements what i want.
answersdata is String[]
I have error in this line:
nr1 = rand.nextInt(10);
All code of this method:
private void set_answer(int nrquestion) {
int nr1, nr2, nr3;
answers.add(answersdata[nrquestion]);
do{
nr1 = rand.nextInt(10);
}while(nr1==nrquestion);
answers.add(answersdata[nr1]);
do{
nr2 = rand.nextInt(10);
}while(nr2==nrquestion|| nr2==nr1);
answers.add(answersdata[nr2]);
do{
nr3 = rand.nextInt(10);
}while(nr3==nrquestion|| nr3==nr1 || nr3==nr2);
answers.add(answersdata[nr3]);
Collections.shuffle(answers);
}
When i write static number its working for example:
nr1 = 5;
It seems as though you forgot to initialize rand with a Random object.
Random rand = new Random(); //before trying to make calls on rand
Perhaps showing a quick method would explain how it works better than an actual explanation:
public int generateRandomNumberBetween(int min, int max){
return min + new Random().nextInt(max - min + 1);
}
The method above will generate a number between [min, max] (inclusive). It is encouraged you create a constant Random instance somewhere so you don't have to keep creating a new 1 upon each method invocation.

static arrays are not the same [java]

I'm trying to create a Java program that generates an amount of seats taken in an airplane. So far, I have been able to do this, but my problem is every time I run the client the numbers generated are different. I need them to be the same every time...
I'm not sure what I'm doing wrong, can anybody help me?
import java.util.Random;
import java.util.Arrays;
public class Airplane {
public static Random randomNumbers = new Random();
public static int[] oSeatLeft = new int[10];
public static int[] mSeatLeft = new int[10];
public static int[] wSeatLeft = new int[10];
public static int oSeat = 0;
public static int mSeat = 0;
public static int wSeat = 0;
public static final int sCheck = 0;
public void genWSeats() {
int randSeatFill = 0;
if (wSeat == 0) {
for (int counter = 0; counter < wSeatLeft.length; counter++) {
randSeatFill = randomNumbers.nextInt(2);
if (randSeatFill == 1) {
wSeatLeft[counter] = 1;
}
}
if (wSeat == 0) {
wSeat++;
}
}
}
public int[] getWSeats() {
System.out.println(java.util.Arrays.toString(wSeatLeft));
return wSeatLeft;
}
}
The purpose of static int wSeat is supposed to be a checker. If wSeat is greater than zero, then it should not randomly generate numbers for the array. Not sure exactly what is going wrong here....
Use the Random constructor with seed
public static Random randomNumbers = new Random(42);
This way always the same sequence of random numbers is generated.
42 is only an example, you can use any value you want.
Pass a seed on initialization with Random(long seed). This will guarantee that the sequence of numbers generated is always the same (since it's a pseudo-random number generator).
Pass Seed in constructor of Random it will generate the same number every time

Categories

Resources