Simple deterministic method to generate an array of random numbers? - java

I am looking for a simple method to populate a large int[] testArray with data. Method should accept a single parameter to generate a deterministic sequence of integers, but look like noise at a first glance.
Something like this comes to mind, but data might have patterns.
public int[] populate(int arraySize, int somePrime){
int[] testArray = new int[arraySize];
int offset = -100000;
long fib = 0; long fibm1 = 1; long fibm2 = 1;
//...
for(int i = offset; i< testArray.length; i++){
fib= fibm1+ fibm2;
fibm2= fibm1;
fibm1= fib;
if(i >= 0){ testArray[i] = (int) fib%somePrime; }
}
return testArray[i];
}
What would be a better method?

You can do this by initializing a random number generator with a fixed seed. The sequence it generates will look random to someone who doesn't know the seed, but you will be able to reconstruct the sequence by using the same seed again.
For example:
Random r = new Random(mySeed);
int[] testArray = new int[arraySize];
for(int i=0; i<arraySize; i++) {
testArray[i] = r.nextInt();
}
Update: This method is susceptible to someone guessing your seed by trial and error, especially if it's a small number or otherwise predictable. You could also store a secret, fixed seed and combine the two into a longer seed. But you should be careful about how you do this, as there are pitfalls. See Deterministically combine more than one source of entropy.

You could use SecureRandom. Then you could use your number to generate a seed:
int seed = 1234;
Random rand = new SecureRandom(SecureRandom.getSeed(seed));
int number = rand.nextInt();

Related

How to initialize an Integer Array with multiple values while using "for"

While I was trying to create a small GUI in Java, I've stumbled onto this small issue with arrays.
I've tried inserting Random Integers into an one dimensional array, only to find out that the Random Integers won't get assigned.
//Declaring an Integer Array
int[] wuerfel = new int[2];
//It will loop once while assigning a random number to the array
for(int i = 0; i <= 1; i++) {
Random rand = new Random(6);
int zahlen = rand.nextInt(6) + 1;
wuerfel[i] = zahlen;
}
System.out.println(Arrays.toString(wuerfel));
I expect the output from the array to be a number between 1 - 6.
However, I keep receiving [2,2] as a result every time I try to rerun.
The constructor call new Random(6) doesn't do what you think it does: 6 is the seed, rather than the range of possible outputs. Therefore it will produce the same output every time.
Possible solutions:
Use the no-argument constructor for Random() instead, which will give it a different seed each time.
Declare and initialise rand outside the loop, with or without an explicit seed.
Use Math.random().
So in your code you set up a seed for your Random and you create new Random object every loop iteration so it just returns same number every time. If you use seed the documentation of Random class says :
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.
In your case you can get rid of seed value from your constructor or move Random class object creation outside of the loop :
public static void main(String[] args) {
int[] arr = new int[2];
Random rand = new Random();
for(int i = 0; i <= 1; i++) {
int zahlen = rand.nextInt(6) + 1;
arr[i] = zahlen;
}
System.out.println(Arrays.toString(arr));
}
Here I moved creation of Random instance outside of the loop so only one object is created and I am not passing seed to the constructor. I could pass the seed but in this case it is not needed as I don't need to create more instances of Random and I dont need them to generate same results.
*
int[] wuerfel = new int[2];
//It will loop once while assigning a random number to the array
Random rand = new Random();
for(int i = 0; i <= 1; i++) {
int zahlen = rand.nextInt(6) + 1;
wuerfel[i] = zahlen;
}
System.out.println(Arrays.toString(wuerfel));
* try this one create Random object with passing parameter

Generating unique random number is increasing complexity and might cause performance overhead?

Implementation:
private static List<Integer> getRandomDistribution(List<String> unsortedList, int max) {
Random random = new Random();
List<Integer> indexContainer = new ArrayList<>();
for (int i = 0; i < max; i++) {
int index = random.nextInt(max);
// Below is what I don't like,
if (indexContainer.contains(index)) {
i--;
} else {
indexContainer.add(index);
}
}
return indexContainer;
}
So basically its saying that, until I don't find the required unique random number. I will continue the loop, what could happen is it might keep looping for a long time thus increasing the overhead.
Problems:
int index = random.next(max) is what should decide the randomness, also I will have to maintain the ordering. That why I have used List
Secondly, i-- is where I am stuck, because frankly I don't like the implementation.
NOTE:
I will also have to maintain the order within the indexContainer.
Since you are generating a permutation of all the numbers from 0 to max-1, it would make more sense to populate the List with all the numbers from 0 to max-1 and then call Collections.shuffle(list).
Random random = new Random();
List<Integer> indexContainer = new ArrayList<>();
for (int i = 0; i < max; i++) {
indexContainer.add(i);
}
Collections.shuffle(indexContainer, random);

How do I make a large number of random arrays?

I need to make an array that has 8000 random integers between values 0 - 65535 for a hash table assignment, I understand the math.random function but how do I get random numbers for such a large range of numbers? Thanks!
If you're in Java 8, you can write
int[] array = new Random().ints(0, 65536).limit(8000).toArray();
otherwise you'd just write something like
int[] array = new int[8000];
Random rng = new Random();
for (int i = 0; i < 8000; i++) {
array[i] = rng.nextInt(65536);
}

Random Array Generator Java

I need to initialize an array of characters with 1000 random characters between [a,..z] and [A,..,Z].
I don’t want do this by first generating only characters between [a,..z] and then only characters in [A...Z] but treat all 52 characters equally.
I know one way to do this is to generate a random number between 0 and 51 and assign it one of the character values.
How would I approach this problem or assign values to the random numbers between 0 and 51?
You have got the interesting code idea.
Here might be the thought.
Take all the a-z and A-Z and store them in an array[].
Randomly generate a number between 1-52 (use API classes for that).
You will get a number in step 2, take it as an array index and pick this index from array[] of chars.
Place that picked char to your desired location/format............
Process it.
Best Regards.
Let me give you some general guidelines. The "one way to do this" you mentioned works. I recommend using a HashMap<E>. You can read more about hashmaps in the docs:
http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
Alternatively, you can use another array that contains a - z and A - Z and you can use the index number to refer to them. But in this case I think it makes more sense to use a HashMap<E>.
I think you know how to create a Random object. But if you don't, check out the docs:
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html
So you basically use the nextInt method of the Random class to generate a random number. And you can put that random number into your HashMap or array. And then you just put that character you get into an array that stores the result of the program.
This is the sample work, hope this will work for you
import java.util.ArrayList;
import java.util.Random;
public class RandomNumber {
public static void main(String args[]) {
char c;
ArrayList<Character> character = new ArrayList<Character>();
Random rn = new Random();
for (int i = 0; i < 500; ++i) {
character.add((char) (rn.nextInt(26) + 66));
character.add((char) (rn.nextInt(26) + 97));
}
System.out.println(character);
}
}
The simplest approach would be:
// constant declared in the class
static final int LETTERS_COUNT = 'z'-'a'+1;
char[] randomChars = new char[500];
Random r = new Random();
for(int i=0; i<randomChars.length; i++) {
randomChars[i] = (char)(r.nextInt(LETTERS_COUNT) + (r.nextBoolean() ? 'a' : 'A'));
}
If you don't like accessing random number generator two times, you can generate numbers from 0 to 51:
for(int i=0; i<randomChars.length; i++) {
int num = r.nextInt(LETTERS_COUNT*2);
randomChars[i] = (char)(num >= LETTERS_COUNT ? 'a'+(num-LETTERS_COUNT) : 'A'+num);
}
However I don't see any advantages of this approach. Internally r.nextInt may also change its internal state several times. The distribution should be similar in both cases.
You can this with a function using either arrays or arithemtic.
Note that you can calculate with characters like with numbers, because they are stored as numbers (http://www.asciitable.com/), you will also note that digits, small letters and big letters are stored in sequence so that accessing ranges is pretty easy with a simple for-loop.
private Random r = new Random();
public char randomLetter() {
int randomNumber = this.r.nextInt(52);
if(randomNumber >= 26) {
return (char)(('A'+randomNumber)-26);
} else {
return (char)('a'+randomNumber);
}
}
The version using an array will be faster, but can only be used if the set of possible outcomes is small enough to be stored.
private Random r = new Random();
private static char[] set = new char[52]; //static because we only need 1 overall
static { //this is a static "constructor"
for(int i = 0; i < 26; i++) {
set[i] = (char)('a'+i);
set[i+26] = (char)('A'+i);
}
}
public char fastRandomLetter() {
final int randomNumber = this.r.nextInt(52);
return set[randomNumber];
}
public class ShuffleArray {
public static void main(String[] args) {
int[] array = { 1, 2, 3, 4, 5, 6, 7 };
Random rand = new Random();
for (int i = 0; i < array.length; i++) {
int randomIndexToSwap = rand.nextInt(array.length);
int temp = array[randomIndexToSwap];
array[randomIndexToSwap] = array[i];
array[i] = temp;
}
System.out.println(Arrays.toString(array));
}
}

random.nextDouble creates the same sequence in a for block

I have the following code to create a random series of a numbers from 0 to a given amount.
ArrayList<Integer> places = new ArrayList<Integer>();
for (int cnt = 0; cnt < NUMBER; cnt++) {
int place = (int)(random.nextDouble()*places.size());
places.add(place , new Integer(cnt));
}
I use this code in a method and then I run this method for about 1000 times for statistics purposes.
My problem is that created series is the same for all of the 1000 time.
Every time that I run the sequence is different, but same for all of the for values.
What should I do? Is there a method like srand() in C++?
Your algorithm seems flawed if you are trying to generate an array with numbers 0 ... NUMBER-1 in random order. Consider:
Random rnd = new Random(System.currentTimeMillis());
...
ArrayList<Integer> places = new ArrayList<Integer>(NUMBER);
for (int i = 0; i < NUMBER; ++i) {
places.add(i);
}
Collections.shuffle(places, rnd);
Use you use Math.random(). It will return a double from 0.0 to 1.0 exclusively. So you can replace the 2 lines inside the for loop with this:
places.add((int)(Math.random() * places.size()),cnt);
//you don't have to do "new Integer(cnt)" because of Java's auto-boxing feature

Categories