Generating a sequence of Pseudo-random numbers based on a seed - java

In Java, I want to generate a program that generates a string of around 15 numbers based on a seed. It always needs to be from 1 to 9. It should seem random, but each seed spits out the same sequence.
For example if you type the number 5, it might output 194639573978476, but if you enter 6, it would output 657362047273958, and 5 will always output 194639573978476.
How do i do this?

First :If two instances of Random are created with the same seed, and the same sequence of method calls is made for each, they will generate and return identical sequences of numbers.
Source:Oracle
For this reason the seed needs to be different every time to generate a different numbers. You can use the time as seed. Like this,
Random random = new Random(System.currentTimeMillis());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 15; i++) {
sb.append(Integer.toString((random.nextInt(9) + 1)));
}
System.out.println(sb.toString());
Sample output every time you run the code:
146645139262732
919846574753947
662686147977574
Hope this helps!

First, create an instance of Random and give it your seed as an argument:
Random rand = new Random(seed);
Then just get 15 numbers. You can use a stringbuilder to build the string, or any other way you want. Shouldn't be too hard, but here's a quick and dirty way to do it:
String result = "";
for(int i = 0; i < 15; i++) {
result += rand.nextInt() % 9 + 1;
}
Please note this is some very dirty programming, did it this way for the sake of simplicity and readability. This is very poor style and you shouldn't copy paste this without changing it.

Related

Generating Random integers within a range to meet a percentile in java

I am trying to generate random integers within a range to sample a percentile of that range. For example: for range 1 to 100 I would like to select a random sample of 20%. This would result in 20 integers randomly selected for 100.
This is to solve an extremely complex issue and I will post solutions once I get this and a few bugs worked out. I have not used many math packages in java so I appreciate your assistance.
Thanks!
Put all numbers in a arraylist, then shuffle it. Take only the 20 first element of the arraylist:
ArrayList<Integer> randomNumbers = new ArrayList<Integer>();
for(int i = 0; i < 100; i++){
randomNumbers.add((int)(Math.random() * 100 + 1));
}
Collections.shuffle(randomNumbers);
//Then the first 20 elements are your sample
If you want 20 random integers between 1 and one hundred, use Math.random() to generate a value between 0 and 0.999... Then, manipulate this value to fit your range.
int[] random = new int[20];
for(int i =0; i< random.length;i++)
{
random[i] = (int)(Math.random()*100+1);
}
When you multiply Math.random() by 100, you get a value between 0 and 99.999... To this number you add 1, yielding a value between 1.0 and 100.0. Then, I typecasted the number to an integer by using the (int) typecast. This gives a number between 1 and 100 inclusive. Then, store the values into an array.
If you are willing to go with Java 8, you could use some features of lambdas. Presuming that you aren't keeping 20% of petabytes of data, you could do something like this (number is the number of integers in the range to get) it isn't efficient in the slightest, but it works, and is fun if you'd like to do some Java 8. But if this is performance critical, I wouldn't recommend it:
public ArrayList<Integer> sampler(int min, int max, int number){
Random random = new Random();
ArrayList<Integer> generated = new ArrayList<Integer>();
IntStream ints = random.ints(min,max);
Iterator<Integer> it = ints.iterator();
for(int i = 0; i < number; i++){
int k = it.next();
while(generated.contains(k)){
k = it.next();
}
generated.add(k);
}
ints.close();
return generated;
}
If you really need to scale to petabytes of data, you're going to need a solution that doesn't require keeping all your numbers in memory. Even a bit-set, which would compress your numbers to 1 byte per 8 integers, wouldn't fit in memory.
Since you didn't mention the numbers had to be shuffled (just random), you can start counting and randomly decide whether to keep each number or not. Then stream your result to a file or wherever you need it.
Start with this:
long range = 100;
float percentile = 0.20f;
Random rnd = new Random();
for (long i=1; i < range; i++) {
if (rnd.nextFloat() < percentile) {
System.out.println(i);
}
}
You will get about 20 percent of the numbers from 1 to 100, with no duplicates.
As the range goes up, the accuracy will too, so you really wouldn't need any special logic for large data sets.
If an exact number is needed, you would need special logic for smaller data sets, but that's pretty easy to solve using other methods posted here (although I'd still recommend a bit set).

How can I fix the size of randomly 5 generated numbers?

I am randomly generating numbers using java.util.Random. But, I can not keep the length of the numbers fixed. Can you help me please?
To fix the length of a randomly generated number, generally you'll want to fix the random number generation to a range. For instance, if you'd like to generate a 6 digit long random number, you'll want numbers from 100,000 to 999,999. You can achieve this by using the following formula.
Random r = new Random();
int randomNum = r.nextInt((max - min) + 1) + min;
Where max is the maximum number, such as 999999, and min is your minimum number, such as 100000.
EDIT:
Based on your comment, I see that you're trying to generate a 15-digit number containing only 1-5 inclusive. Here is a simple way to do this:
import java.util.Random;
StringBuilder s = new StringBuilder();
Random r = new Random();
for (int i = 0; i < 15; i++) {
s.append(r.nextInt(5) + 1);
}
System.out.println("The random number is: " + s.toString());
As noted by #MichaelT, a 15 digit number will not fit in an integer. If you need to perform an operation on it, you should store it in a long.
long randomLong = Long.valueOf(s.toString()).longValue();
Rather than thinking of generating an integer, think in terms of generating a String of 15 digits, each in the required range.
You can use nextInt(int) to pick each digit.
The first thing to consider is that an int cannot hold 15 digits. It just can't. It can only go up to 232 -1, which is 9 digits long. A long can hold up to 19 digits - but if one wants to solve for the general case, it is necessary to use the BigInteger package instead.
Remember that BigInteger is an immutable object (like String) and thus you must assign the value back when looping.
package com.michaelt.so.random15;
import java.math.BigInteger;
import java.util.Random;
public class Main {
public static void main(String[] args) {
Random r = new Random();
BigInteger result = BigInteger.ZERO;
for(int i = 0; i < 15; i++) {
result = result.multiply(BigInteger.TEN)
.add(BigInteger.valueOf(r.nextInt(5)+1));
}
System.out.println(result.toString());
}
}
It starts out with the value ZERO, and loops through for 15 times, each time first multiplying the value by 10 (another BigInteger preallocated value) and then adds the new value into the 1's position. It does this 15 times.
When done, one can get its value as a string or long or other format - or continue to use it as a BigDecimal (necessary if you should ever decide you want a 20 digit long value).
Runs of the above code produce output such as:
313455131111333
245114532433152
531153533113523
If you're ok using libraries:
RandomStringUtils.random(15, "12345")
would give you Strings like: 124444211351355 of length 15
I just happened to write a post about that (shameless self-advertising link: http://united-coders.com/nico-heid/generating-random-numbers-strings-java/)

Java random numbers not random?

I was trying to explain the random number generator in Java to a friend when he kept getting the same numbers every time he ran the program. I created my own simpler version of the same thing and I too am getting the same exact numbers he was getting every time I run the program.
What am I doing wrong?
import java.util.*;
public class TestCode{
public static void main(String[] args){
int sum = 0;
Random rand = new Random(100);
for(int x = 0; x < 100; x++){
int num = (rand.nextInt(100)) + 1;
sum += num;
System.out.println("Random number:" + num);
}
//value never changes with repeated program executions.
System.out.println("Sum: " + sum);
}
}
The final five numbers out of the 100 are:
40
60
27
56
53
You have seeded the random generator with a constant value 100. It's deterministic, so that will generate the same values each run.
I'm not sure why you chose to seed it with 100, but the seed value has nothing to do with the range of values that are generated (that's controlled by other means, such as the call to nextInt that you already have).
To get different values each time, use the Random constructor with no arguments, which uses the system time to seed the random generator.
Quoting from the Javadoc for the parameterless Random constructor:
Creates a new random number generator. This constructor sets the seed
of the random number generator to a value very likely to be distinct
from any other invocation of this constructor.
Quoting the actual code in the parameterless Random constructor:
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
This:
Random rand = new Random(100);
You're giving the random number generator the same seed (100) each time you start the program. Give it something like the output from System.currentTimeMillis() and that should give you different numbers for each invocation.
Random number generators are really only pseudo-random. That is, they use deterministic means to generate sequences that appear random given certain statistical criteria.
The Random(long seed) constuctor allows you to pass in a seed that determines the sequence of pseudo-random numbers.
Please see the below code to generate a random number from a pool of random numbers.
Random r = new Random(System.currentTimeMillis());
double[] rand = new double[500];
for(int i=0;i<100;i++){
rand[i] = r.nextDouble();
}
double random_number = rand[randomInt];

Randomly generated numbers in a basic array

I simply need to know what i should do to make so that a basic array is filled with randomly generated numbers. now i know how to do that, what i don't know how to to do is to make it so that the randomly generated numbers are bigger than the last number generated all the way through to the end of the array.
Just generate for the list, and then sort them smallest to largest.
for(int i = 0; i < arr.length; ++i) {
arr[i] = Random.nextInt(100);
}
Arrays.sort(arr);
Generate random numbers, and then sort the array.
You can sort the array using Arrays.sort()
It doesn't make sure that each number is strictly bigger then the previous numbers [it only gurantees <=], so if it is an issue - you will have to make sure you have no dupes in the generated numbers.
You can generate an array of random numbers, and then sort it using Array sort.
There was a comment on the question, I lost the author's name, that recommended adding the randomly generated number to the previous number, which I thought was an interesting approach.
arr[0] = Random.nextInt(100);
for(int i = 1; i < arr.length; ++i) {
arr[i] = arr[i-1] + Random.nextInt(100);
}
This removes the need to sort your result array.
You can have your own algorithm of generating incremental...
For example...
Random each time and add that number to the last one :)
Random class in java does not allow you to have a minim limit where to start.. only one...
For example:
myArray[0] = Random.nextInt(10000);
for(int i=1; i<myArray.length; i++)
{
myArray[i] = myArray[i-1]+Random.nextInt(10000);
}
So.. it's random and you don't have to sort it.. try keeping everything simple...
I'm surprised no one mentioned that we can use SecureRandom API to easily generate random arrays without manually populating it.
For ex. generating a random array of size 100:
SecureRandom random = new SecureRandom();
int arr[] = random.ints(100).toArray();
BTW this should be possible from java 8 onwards.

Random generated number

How would you set up a program using Java to generate a 5 digit number using the following statement:
int n = (int)Math.floor(Math.random()*100000+1)
It also has to print the number generated. I have tried writing this different ways and keep coming up with errors.
There are two ways of looking at your problem. Either you need to make sure the random number generator only produces numbers with exactly five digits (in the range 10000 - 99999) or you need to print the numbers with leading 0s when a number is produced that's too low.
The first approach is best met using Java's Random class.
Random rand = new Random();
int n = rand.nextInt(90000) + 10000;
System.out.println(n);
If you're restricted in some way that you must use the statement in your question, then the second approach is probably what you're after. You can use Java's DecimalFormat class to format a random number with leading zeros before printing.
n = (int)Math.floor( Math.random() * 100000 + 1 );
NumberFormat formatter = new DecimalFormat("00000");
String number = formatter.format(n);
System.out.println("Number with lading zeros: " + number);
One might do:
public class Test {
public static void main(String[] args) {
int n = (int)Math.floor(Math.random()*100000+1);
System.out.println(n);
}
}
However, this really isn't the preferred way of generating random integers. Check out the Random class.
Random r = new Random();
for (;;) {
System.out.println(10000 + r.nextInt(90000));
}
A better idea is to generate the number by successively generating 5 random digits. Making the first digit non-zero ensures that the generated number is always 5-digit. I'm posting pseudocode below, it should be easy to convert it into Java code.
A = List(1,2,3,4,5,6,7,8,9)
B = List(0,1,2,3,4,5,6,7,8,9)
output = 0
output=random.choice(A) //first digit from A, no zeros
for i=0 to 4
output=output*10
output=output+random.choice(B) //next digits from B, can have zero
return output
Look up the API docs for Random if you are stuck.
A way to get a random number 00000 - 99999 is to use the following.
Random r= new Random();
// possibly too obtuse for most readers. ;)
System.out.println((""+(100000+r.nextInt(100000))).substring(1));

Categories