I am currently working on an assignment with creating three heads in a row and I got it working but I am failing the tester assigned to me because it's saying my random number generator needs to take a seed parameter for this particular problem. My code for this is :
public static void threeHeads() {
Random r = new Random();
//int seed = r.nextInt();
int head =0;
while (head!=3) {
Boolean random = r.nextBoolean();
if(random==false) {
System.out.print("H");
head++;
}
else {
System.out.print("T");
head=0;
}
}
System.out.println("\nThree heads in a row!");
}
The random constructor is overloaded with a method: Random(long seed), which allows you to instantiate a random number generator with a preset seed.
Related
I know how to get a range of random numbers between 0 zero and any number.
But what I want to know is, since the random number generator is not truly random, and follows a specific algorithm, for example if you pass a seed of 20. then it will always generate the same sequence of numbers: 17, 292, 0, 9.
So I get that. Since it follows a specific algorithm, is there a way I can force the generator to always start at zero or any other number?
But specifically zero in my case.
No need to hack the Random class, just write your own:
public class RandomGenerator {
private int bound;
private Random random;
private boolean firstCall = true;
public RandomGenerator(int bound, long seed) {
this.bound = bound;
random = new Random(seed)
}
public int next() {
if (firstCall) {
firstCall = false;
return 0;
}
return random.nextInt(bound);
}
}
public static void main (String[] args) throws java.lang.Exception
{
int x = -1;
long seed = 0;
int xxx = 100;
while(x!=0){
Random s = new Random(seed++);
x = s.nextInt(xxx);
}
System.out.println("seed " + (seed-1) + " gives " + new Random(seed-1).nextInt(xxx));
}
This will find a seed that the next int will be zero for a given modulus. (Happens to be 18 for this example).
I have been working to get the headcount variable to be random but cannot figure this out
public class Coin
{
private final int HEADS = 0;
private final int TAILS = 1;
private int face;
private static int seed =0;
private Random r;
public Coin ()
{
r = new Random(seed);
flip();
seed++;
}
public void flip ()
{
face = r.nextInt(2);
}
public int getFace()
{
return face;
}
public void setFace(int newFace)
{
face = newFace;
}
public boolean isHeads ()
{
return (face == HEADS);
}
public String toString()
{
String faceName;
if (face == HEADS)
faceName = "Heads";
else
faceName = "Tails";
return faceName;
}
public static void main(String[] args)
{
Coin myCoin = new Coin();
double randnumber =Math.random();
int headCount=0;
for (int i =1; i<=100; i++)
{
myCoin.flip();
if(myCoin.isHeads())
{
headCount++;
}
}
System.out.println("If I flip my coin 100 times, I get " + headCount + " heads.");
headCount =0;
for (int i =1; i<=100; i++)
{
Coin yourCoin = new Coin();
yourCoin.flip();
if(yourCoin.isHeads())
{
headCount++;
}
}
System.out.println("If I flip 100 coins, I get " + headCount + " tails.");
}
}
Whenever I Compile it and Run the program I get the same output which is
If I flip my coin 100 times, I get 47 heads.
If I flip 100 coins, I get 50 tails.
I dont understand how to make the 47 and 50 to be new random numbers each time you run the program. I have looked int Math.Random and other random variables but am unsure how to implement it into this program.
What you want is:
r = new Random(System.currentTimeMillis());
BTW: Random Numbers generators always start with the same number, given a certain seed.
For example, supposed the "random number" generator added 2 to find the next random number.
seed = 9
r(9) = 11 ; r(11) = 13 ; r(13) = 15.
However, a different seed will lead to a different string of numbers.
seed = 4
r(4) = 6 ;
Random numbers in computer programming aren't really random. They depend on a seed value. If you give it the same seed each time, you'll get the same sequence of "random" values each time.
If, instead, you use the empty constructor for Random, it will create a seed for you that is based on the current system nano time. In this way, you will mitigate the chance that you start with the same seed.
So, as others have already mentioned, either call the empty Random constructor, or create a pseudo-random seed yourself before creating a Random that takes the seed argument.
With all that said, it's probably best to assume the JDK implementers have already thought about how best to generate a seed for you, so you should just use the empty constructor.
If you want to see the Java source for the Random class, you can search for
grepcode java.util.Random.java
and see how the JDK implementers create the seed.
Solve the seed issue by declaring Random in the class directly instead in a method.
private Random r = new Random();
public Coin()
{
int x = r.nextInt();
flip();
}
I have a very strange bug that I am trying to fix. I will try my best to explain it.
I have a class, and in that class I have a method that picks a random number.
The random number generation has to generate the exact same sequence of numbers every time I run the application (different numbers, but appear in the same order no matter when I run the app).
Therefore I need to use seeds.
My code looks something like this:
public class Tree{
Random rand = new Random(12345);
///...code...///
public Tree randomNode() {
//HERE IS THE ERROR
int r = rand.nextInt(this.size);
if (r == 0) {
return this;
}
else if (left != null && 1 <= r && r <= left.size) {
return left.randomNode();
}
else {
return right.randomNode();
}
}
}
I have a helper class that uses this, it looks a bit like this:
public Crossover(Tree p1, Tree p2)
{
Tree subtreeP1 = p1.randomNode();
Tree subtreeP2 = p2.randomNode();
}
My main method looks a bit like this:
for(i=0;i<cross;i++)
{
Crossover c = new Crossover(p1,p2);
}
During the first loop in the main method, the numbers for r generate randomly and are fine. However, on the 2nd loop (and all that follow) is where I encounter the problem.
The problem is on the line int r = rand.nextInt(this.size); - After the 2nd loop I ALWAYS get 0 no matter what.
If I remove the seed, all works well. If I include the seed, I start getting 0 ALWAYS after the first loop.
How can I continue using a seed, but get random numbers? And what am I doing wrong?
**EDIT: **
this.size refers to the size of my tree. I have ensured it is NOT zero when I get r to be 0.
ALSO I would like to point out, that when I simply remove the number seed, it works fine, and random number generation works fine. When I add the seed, I have the problem.
EDIT #2
Ok, so as requested, I've put together a little program that illustrates my problem. Just run it as is. Once with the seed and once without.
import java.util.*;
public class Problem{
public static void main(String args[])
{
for(int i=0; i<100; i++)
{
Clas c1 = new Clas();
Helper h = new Helper(c1);
System.out.println(h.getR());
}
}
}
class Helper
{
int r;
Helper(Clas c)
{
r = c.method();
}
public int getR()
{
return r;
}
}
class Clas
{
Random rand = new Random(1825897);
Clas()
{
}
public int method()
{
int r = rand.nextInt(10);
return r;
}
}
In the loop, you don't want to reset the Random Number Generator, I assume?
In the example, you could do:
Clas c1 = new Clas();
for(int i=0; i<100; i++)
{
Helper h = new Helper(c1);
System.out.println(h.getR());
}
In your original example, you seem to have multiple Tree instances, so you can't use this. But you can declare your Random static, so it is shared among all Trees:
static Random rand = new Random(1825897);
Try using the function Math.random() to generate your random number. Math.random() generates a random number between 0 and 1.
So I am trying to test if a sequence of integers was randomly generated, but it doesn't work...
this is what I've got so far:
public static void main(String[] args) {
Random r = new Random();
int[] sequence = { r.nextInt(), r.nextInt(), r.nextInt() };
System.out.println(isRandomSequence(sequence));
}
public static boolean isRandomSequence(int[] sequence) {
for (long seed = 0; seed < Long.MAX_VALUE; ++seed) {
Random r = new Random(seed);
long tries = 0;
for (int i = 0; tries < Long.MAX_VALUE; ++tries) {
if (sequence[i] == r.nextInt()) {
if (++i == sequence.length) return true;
} else {
i = 0;
}
}
}
return false;
}
Edit: to clarify; I want to know if, for instance the sequence { 4, 5, 6 } was generated by the random number generator. For starters limiting the testing to the java.util.Random (would be nice to have a general solution though if it's possible).
Apart from being intractable, your brute-force technique will only detect a pseudorandom sequence generated by java.util.Random, by far not the only option to generate pseudorandom numbers. Also note the word pseudo: they are not really random, that is why you think you can detect the sequence.
Detecting whether a sequence is truly random is theoretically impossible: the best you can do is perform a barrage of pattern-detecting tests in order to eliminate certain possibilities. There will always be nonrandom sequences that escape detection.
I should also note that there is definitely nothing to say about a sequence of just three integers. I am pretty sure that the output of java.util.Random contains all possible three-integer sequences.
Random only has 2^48 seeds. This means you "only" need explore 2^48 seeds from the start. no more.
All the same, exploring 2^48 seeds will take hours or days to run.
As this is very cpu intensive you could look at using all the CPUs you have available ;)
I think you're thinking about the way seed works incorrectly. That might explain why you aren't getting random sequences.
You don't seed every time. You instantiate the Random with the seed at the start of your process and hang onto it.
If you create a Random inside a method call, with a new seed every time you want a sequence, you're definitely doing it wrong.
I'll bet this works:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
/**
* RandomSequenceGenerator
* #author mduffy
* #since 12/12/12 4:38 PM
*/
public class RandomSequenceGenerator {
private Random random;
public static void main(String[] args) {
RandomSequenceGenerator generator = new RandomSequenceGenerator();
int numSequences = ((args.length > 0) ? Integer.valueOf(args[0]) : 10);
int lenSequence = ((args.length > 1) ? Integer.valueOf(args[1]) : 3);
for (int i = 0; i < numSequences; ++i) {
System.out.println(generator.createRandomSequence(lenSequence));
}
}
public RandomSequenceGenerator() {
this(System.currentTimeMillis());
}
public RandomSequenceGenerator(long seed) {
this.random = new Random(seed);
}
public synchronized List<Integer> createRandomSequence(int length) {
List<Integer> sequence = new ArrayList<Integer>(length);
for (int i = 0; i < length; ++i) {
sequence.add(this.random.nextInt());
}
return sequence;
}
}
My project entails that I create a basic number guessing game that uses the JOptionPane and does not use Math.Random to create the random value. How would you go about doing this? I've completed everything except the random number generator. Thanks!
Here the code for a Simple random generator:
public class SimpleRandom {
/**
* Test code
*/
public static void main(String[] args) {
SimpleRandom rand = new SimpleRandom(10);
for (int i = 0; i < 25; i++) {
System.out.println(rand.nextInt());
}
}
private int max;
private int last;
// constructor that takes the max int
public SimpleRandom(int max){
this.max = max;
last = (int) (System.currentTimeMillis() % max);
}
// Note that the result can not be bigger then 32749
public int nextInt(){
last = (last * 32719 + 3) % 32749;
return last % max;
}
}
The code above is a "Linear congruential generator (LCG)", you can find a good description of how it works here.
Disclamer:
The code above is designed to be used for research only, and not as a
replacement to the stock Random or SecureRandom.
In JavaScript using the Middle-square method.
var _seed = 1234;
function middleSquare(seed){
_seed = (seed)?seed:_seed;
var sq = (_seed * _seed) + '';
_seed = parseInt(sq.substring(0,4));
return parseFloat('0.' + _seed);
}
If you don't like the Math.Random you can make your own Random object.
import:
import java.util.Random;
code:
Random rand = new Random();
int value = rand.nextInt();
If you need other types instead of int, Random will provide methods for boolean, double, float, long, byte.
You could use java.security.SecureRandom. It has better entropy.
Also, here is code from the book Data Structures and Algorithm Analysis in Java. It uses the same algorithm as java.util.Random.