I can create random numbers from a range using
Random rand = new Random();
int num = rand.nextInt(10);
System.out.println("Generated Random Number between 0 to 10 is : " + num);
But if i need the next random number generated to be a part of the range minus the already generated one, will keeping the above statement in a loop will suffice?
Also I need to stop once i exhaust all the number from the range.
For eg,
The code gives me a random number between [0-10],
1st - 4 - range {[0-10]}
2nd - 9 - range {[0-10]-4}
3rd - 8 - range {[0-10]-4,9}
..
..
10th - 10 - range {[0-10]-[0-9]}
Will this function output from [Range]{this is my requirement} or (Range)? Or is there any better alternative solution?
The easiest way would probably be to:
put the numbers (0 to 10) in a list
call Collections.shuffle() on that list
loop over the list
Something like:
List<Integer> numbers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 10);
Collections.shuffle(numbers);
System.out.println(numbers);
You can even provide a random generator for the shuffling operation if the default doesn't suit you.
I do not think this is possible. Try to remember the numbers you already generatedin a list and use it to generate more random numbersuntil you find one that is not in your list.
Related
I am trying to make a program to construct a Maze (a classic exercise in Java) and I want to my method to generate the maze to recieve a seed for the aleatory number generator that is used to generate this. This is required because I want the program to generate the same maze everytime I enter the same seed.
But, with some seed values, more values looks like to have more probability than others.
I mean, suppose that I set a random object with a given seed and use it to generate integers between [0, 4) and this is used as criteria to build the maze. The sequence generated is so characteristic that the maze is just too easy. Is I just dont set any seed, a good maze is generated.
The integers part are just an example. I could use an uniform and divide it 4 regions: [0, 0,25), [0,25, 0.5), [0.5, 0.75), [0.75, 1)
Is there a way to modify that seed so that the behavior of the random number generator will be the same for the same seed and mantain the good "mixture" of the numbers? I mean, how can I generate the same numbers setting a seed such that they are evenly distributed in this intervals?
Thanks!
You can try this to make sure the numbers are 'random', but uniformly distributed over [0, 1), [1, 2), [2, 3) and [3, 4):
Random random = new Random(seed);
int count = 200; // or another number, just how many you need
List<Float> numbers = new ArrayList<Float>(count);
for (int i = 0; i < count; i++) {
numbers.add(random.nextFloat() + (i % 4));
}
Collections.shuffle(numbers);
This question already has an answer here:
Select a random value from an Array
(1 answer)
Closed 8 years ago.
I'm writing a program that generates co-primes of a number.
Now for example a number 'A' has 50 co-primes, my objective is to randomly select a co-prime from the list of all co-primes generated for the number A.
Again for example:
consider a number 15, it has co-primes - {1, 2, 4, 7, 8, 10, 11, 13, 14}. So now i have to select randomly from these values. Likewise, if i generate an array of any values, then how to randomly select from this array.
So in general my question is how to generate a random number from the array of numbers that i have. Now, those numbers in the array can be anything. Like not necessarily natural numbers, or prime numbers, etc.
So is there any java function to do so. I've burnt my brain searching the internet, but didn't find one. I usually go for finding result on google, rather than asking quetions on forums. But when one gets exhausted, it's better to ask experts out there who might have faced similar problems.
Thanks in advanced!!
Is that what you want ?
int[] arr = { 1,5,9,3,2,7 };
Random rd = new Random();
int dice = arr[rd.nextInt(arr.length)];
You can use the java.util.Random class for this:
public int chooseRandom(int[] coPrimes) {
//Creates the Random instance
Random randomizer = new Random();
//Generate a random integer between 0 and the length of the array (exclusive)
int value = randomizer.nextInt(coPrimes.length);
//Return the element at that generated index
return coPrimes[value];
}
This question already has answers here:
Random number,with nonuniform distributed [duplicate]
(5 answers)
Closed 8 years ago.
//Generates a random number but doesn't allow the same number be repeated
for (int i = 0; i < questions1.length; i++)
{
//random number
int r = (int)(Math.random() * i);
temp = index[r];
index[r] = index[i];
index[i] = temp;
}
How do I make it favour 1 number in particular?
If you want, for example, a random number between 1-6, but want 3 to be picked twice as likely as any other number, a very simple solution would be to create an array with 7 indexes. 1, 2, 4, 5, 6 all hold one index each. 3 holds two indices. Now pick a random number between 0 and 6 and return whatever number is in that index.
Using this approach you can provide whatever weights you want to any range of numbers.
There are almost certainly more elegant solutions, but this will get the job done.
You could build an List and fill it with the numbers you want in the proportion you want. Then use Collections.shuffle.
public void test() {
// Throw 1 twice as likely and 6 3 times as likely as the other numbers.
List dice = Arrays.asList(1,1,2,3,4,5,6,6,6);
Collections.shuffle(dice);
}
Let's say your target range is [0, 6] and you give 1 twice the likelihood. I'll give you two methods which won't eat your memory:
Select a random number out of [0, 7] and map 7 to 1
Select a random out of [0, 6] and if it's not 1 return a new random number out of [0, 6].
Suppose I wanted to generate random numbers taken from ArrayList:(1,2,3,4,5,6,7,8,9,10)
A Random Generator produces 5.
List gets updated- AL:(1,2,3,4,6,7,8,9,10)
Next Random Number cannot be 5.
I am writing a program that generates random numbers from a arraylist and once it generates the random number the list removes that number and the next random generated digit cannot be that number.
ArrayList<Integer> numsLeft = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,10));
Random randomGenerator = new Random();
int number = 0;
String cont;
do
{
number = randomGenerator.nextInt(numsLeft.size());
numsLeft.remove(number);
System.out.println (number + " continue (y/n)");
cont = (stdin.readLine());
}
while (cont.equalsIgnoreCase("y"));
But the only thing I can do here is lower the size...
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html
The easier approach is to simply shuffle your list then use the numbers in the shuffled order:
List<Integer> nums = new ArrayList<Integer>();
for (int i = 1; i < 11; i++)
nums.add(i);
Collections.shuffle(nums);
Now they are in random order, just use them one by one:
for (Integer i : nums) {
// use i
}
You could make an array of the available numbers. Then, the random number generator gives you the position in that array for the number that you want.
Probably a linked list or something would be more efficient, but the concept is the same.
So, with your example, you'd pull 5 the first time. The second time, you'd have this in your list:
1, 2, 3, 4, 6, 7, 8, 9
If your random number was 5 again, the fifth position is 6. Pop the six out, shift 7, 8, 9 over one, and decrement your random number generator to be 1-8 instead of 1-9. continue on.
of course, looking at your code, it looks like that is what you are trying to do already.
What seems to be the issue with your code? What results are you getting?
number = randomGenerator.nextInt(numsLeft.size());
numsLeft.remove(number);
You are now printing the random index that you are generating, not the number that was removed from the list. Is that what you wanted? I think you really meant this:
int index = randomGenerator.nextInt(numsLeft.size());
number = numsLeft.remove(index);
You could also do this using by randomly shuffling the list and then just going through it:
List<Integer> numsLeft = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,10));
// Shuffle the list randomly
Collections.shuffle(numsLeft);
do {
// Remove the first number each time
int number = numsLeft.remove(0);
System.out.println (number + " continue (y/n)");
cont = (stdin.readLine());
} while (cont.equalsIgnoreCase("y"));
Why don't you create a hash map to take care of this. So your hash map can contain something like
Map[(1,1), (2,2), (3,3), ...] or Map[(1,true), (2,true), (3,true), ...]
So if you generate a number, then you can do something like:
String value = map.get(key); or boolean present = map.get(key);
if(value != null) or if(value == present)
map.remove(key), or you can even update the data and instead of removing the key you can update it and add the word removed or a boolean as previously suggested. But this way you can keep track of all the entries and removals in your map for each of the key values which would be your list of numbers.
remove can be pretty expensive operation when list is long. Shuffle is too - especially if you only need a few numbers. Here is another algorithm (it is famous but I can't find the source right now).
put your N (ordered) numbers in a list
Choose a random number m between 0 and N-1
Pick the element at location m. This is your unique random number
SWAP element m with the LAST element in the array
Decrement N by 1
Go to step 2
You "set aside" the numbers you have used in step 4 - but
Unlike shuffle, your initialization is fast
Unlike remove, your remove operation only takes moving one element (instead of, on average, N/2)
Unlike the "pick one and reject if you saw it before", your efficiency of picking a "new" number doesn't decrease as the number of elements picked increases.
I used the following code to generate the random numbers:
long randNo = Math.round(Math.random() * 10000);
I have some situations where i found duplicates. Is it possible that it will generate same numbers?
Yes, it's possible. If you need to generate 10000 distinct random numbers from 0 to 9999. You can generate list of 10000 consecutive numbers and then call Collections.shuffle on it.
With random numbers, all numbers in the range are equally likely. This means if you get a number, the next value is just as likely to appear as it did the first time.
BTW: using round is not a great idea in you example as the numbers 1 to 9999 are equally likely but the numbers 0 and 10000 are half as likely as they only occur on a half rounded down or half rounded up.
A more efficient pattern is to use
Random rand = new Random();
// as needed
int num = rand.nextInt(10000); // will be [0, 10000)
If you need to generate unique numbers you can use Collections.shuffle
List<Integer> nums = new ArrayList<Integer>();
for(int i = 0; i < 10000; i++) nums.add(i);
Collections.shuffle(nums);
This will give you up to 10000 unique numbers in a random order.