I do have the following code for taking random int numbers
for (int i=1;i<=5;i++) {
int rand= new Random().nextInt(10);
Log.d("Ramdom number", String.valueOf(rand));
}
The problem is that I dont want random numbers to be repeated, mean when I run this code it gives to me 5 numbers but two of them at least repeats. Any advice?
For a small range of numbers to choose from, this should do the trick:
ArrayList<Integer> numbers = new ArrayList<Integer>();
for (int i = 0; i < 20; ++i) {
numbers.add(i);
}
Collections.shuffle(numbers);
for (int i = 0; i < 5; ++i) {
Log.d("Random number", numbers.get(i).toString());
}
The problem is that you are creating a Random object within the loop. If the loop is a 'tight', as in this case, the Random object will be seeded with the same value. Moving the Random object initialization outside the loop should do the trick.
Random r = new Random();
for (int i=1;i<=5;i++) {
int rand= r.nextInt(10)
Log.d("Ramdom number", String.valueOf(rand));
}
EDIT:
This should work (at least it did for me)
public static Integer[] getRangedInt(int maxRange, int numCount)
{
if (maxRange < numCount)
{
throw new Exception("maxRange cannot be smaller than numCount");
}
Set<Integer set = new HashSet<Integer>();
Random r = new Random();
while (Set.size() < numCount)
{
int random = r.nextInt(maxRange);
while (!set.add(random))
{
random = r.nextInt(maxRange);
}
}
return set.toArray(new Integer[set.size()]);
}
final int maxnumbers = 5;
final int maxvalue = 10;
final Random generator = new Random();
Set<Integer> numbers = new HashSet<Integer>();
while(numbers.size() < maxnumbers){
numbers.add(random.nextInt(maxvalue));
}
After this loop you should have maxnumber non-repeating random numbers between 0 and maxvalue in the set numbers. You have to watch out so you don't get too many iterations when using this method, i.e. generating 9999 non-repeating numbers out of 10000 would probably take a long time.
Another more scalable version would be to have a list of numbers:
List<Integer> numbers = new ArrayList<Integer>();
for(int i = 0; i<maxvalue; i++){ numbers.add(i); }
Collections.shuffle(numbers);
List<Integer> randomnums = numbers.subList(0, maxnumbers);
I think you need a SET of random numbers. This hint should suffice.
If not, then please comment.
You can maintain one list of generated numbers
boolean flag=false;
Vector<int> vec = new Vector<int>();
for (int i=1;i<=5;i++) {
flag=false;
int rand= r.nextInt(10);
for(int j=0;j<vec.size();j++)
{
if(vec.get(j)==rand)
{
flag=true;
break;
}
}
if(flag)
{
continue;
}
else
{
Log.d("Ramdom number", String.valueOf(rand));
vec.add(rand);
}
}
You can maintain a vector of generated numbers and check
Is that number already generated then generate new one
else display this number
So what you're looking for isn't a list of random numbers, it's a list of 30 numbers randomly ordered.
One way is to generate a list of all possible values, then order them randomly, then peel them from the front of the list as needed. Here's some pseudocode:
for(int i=1; i<=30; i++) {
double r = rand();
while (null != aTreeSet.get(r)) r = rand();
aTreeSet.put(r, i);
}
where rand() returns some random value (not the 1-30 you seek, that's i) perhaps between 0 and 1 and aTreeSet is what you think.
The loop prevents sadness in the unlikely event of a dup being returned by rand().
To use this, pull values from aTreeSet in sorted order.
edit - Gross solution
Another way is to generate the 1-30 value, and if it isn't already in a "I have seen this" Set, add it and return the value. if it is there, generate a new random number. Repeat until an unused number is discovered. This performs poorly, relatively speaking, for the last few values. For 30 values on modern processors, it will get done in milliseconds, of course. If your max value was 1,000 instead of 30, I'd start getting concerned.
What you want is a random combination, use a Hash table to avoid repetitions
From the top of my head the code should be something like:
Ramdom r = new Random();
Hashtable<Integer, Integer> h = new Hashtable<Integer, Integer>();
while( h.keys().size() < 5 ) {
int i = r.nextInt(10);
h.put(i,i);
}
Integer[] k = (Integer[]) h.keySet().toArray();
The line
h.put(i,i);
just overrides the value if it is repeated, so only different drawn numbers will have entries in the hash table.
You can save your generated numbers in a Set and use the random number only if it is not in the set
Random r = new Random();
Set<Integer> generatedNumbers = new HashSet<Integer>();
for(int i = 1;i<=5;i++) {
int rand = r.nextInt(10)
if (!generatedNumbers.contains(rand)) {
Log.d("Ramdom number", String.valueOf(rand));
generatedNumbers.add(rand);
}
}
Related
This question already has answers here:
Generating Unique Random Numbers in Java
(21 answers)
Closed 11 months ago.
With the below code if we try to generate random numbers from 1 to 10, I some times get duplicate values.
Below code should generate 5 unique values for random numbers between 1 to 10.
When I print the array it happens uniqueness is not guaranteed. Output was 2,1,9,10,2.
2 was repeated in this case.
Random random = new Random(System.currentTimeMillis());
random.setSeed(System.currentTimeMillis());
int[] myUniqueValues = new int[5];
for (int i = 0; i < 5; i++) {
myUniqueValues[i] = random.nextInt(10) + 1;
}
return myUniqueValues;
One way of doing this would be to create a list and pick randoms from it:
Random r = new Random();
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=0: i<10; i++){
list.add(i);
}
private int getUniqueRandom(){
int index = r.nextInt(list.size());
int number = list.get(index);
list.remove(index); // Check that it removes the Index not the value from list
return number;
}
Another way if you have a lot of numbers and dont want to store them in memory
Random r = new Random();
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=0; i<5; i++){
do{
int number = r.nextInt(10);
}while(!list.contains(number))
list.add(number);
}
The way with Set as suggested by steven7mwesigwa
This works because Sets can only contain unique values
Random r = new Random();
HashSet<Integer> list = new HashSet<Integer>();
while (list.size() < 5) {
list.add(r.nextInt(10));
}
A one liner from https://stackoverflow.com/a/31656679/11355399
int[] array = ThreadLocalRandom.current().ints(0, 10).distinct().limit(5).toArray();
We can use Set Collection here to remove duplicates inside loop itself. Set has method called contains which will check weather output of random function is already present in our result set or not. if it is present we can skip that iteration. if not we can random to our result set. please check below snippet.
Random random = new Random(System.currentTimeMillis());
random.setSeed(System.currentTimeMillis());
Set<Integer> myUniqueValues2 = new HashSet<>();
int k=0;
while(k<5) {
int test = random.nextInt(10) + 1;
if(!myUniqueValues2.contains(test)) {
myUniqueValues2.add(test);
k++;
}
}
for(int i: myUniqueValues2)
System.out.println(i+" ");
I'm trying to get random numbers between 0 and 100. But I want them to be unique, not repeated in a sequence. For example if I got 5 numbers, they should be 82,12,53,64,32 and not 82,12,53,12,32
I used this, but it generates same numbers in a sequence.
Random rand = new Random();
selected = rand.nextInt(100);
Add each number in the range sequentially in a list structure.
Shuffle it.
Take the first 'n'.
Here is a simple implementation. This will print 3 unique random numbers from the range 1-10.
import java.util.ArrayList;
import java.util.Collections;
public class UniqueRandomNumbers {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i=1; i<11; i++) list.add(i);
Collections.shuffle(list);
for (int i=0; i<3; i++) System.out.println(list.get(i));
}
}
The first part of the fix with the original approach, as Mark Byers pointed out in an answer now deleted, is to use only a single Random instance.
That is what is causing the numbers to be identical. A Random instance is seeded by the current time in milliseconds. For a particular seed value, the 'random' instance will return the exact same sequence of pseudo random numbers.
With Java 8+ you can use the ints method of Random to get an IntStream of random values then distinct and limit to reduce the stream to a number of unique random values.
ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);
Random also has methods which create LongStreams and DoubleStreams if you need those instead.
If you want all (or a large amount) of the numbers in a range in a random order it might be more efficient to add all of the numbers to a list, shuffle it, and take the first n because the above example is currently implemented by generating random numbers in the range requested and passing them through a set (similarly to Rob Kielty's answer), which may require generating many more than the amount passed to limit because the probability of a generating a new unique number decreases with each one found. Here's an example of the other way:
List<Integer> range = IntStream.range(0, 100).boxed()
.collect(Collectors.toCollection(ArrayList::new));
Collections.shuffle(range);
range.subList(0, 99).forEach(System.out::println);
Create an array of 100 numbers, then randomize their order.
Devise a pseudo-random number generator that has a range of 100.
Create a boolean array of 100 elements, then set an element true when you pick that number. When you pick the next number check against the array and try again if the array element is set. (You can make an easy-to-clear boolean array with an array of long where you shift and mask to access individual bits.)
Use Collections.shuffle() on all 100 numbers and select the first five, as shown here and below.
Console:
59 9 68 24 82
Code:
private static final Random rnd = new Random();
private static final int N = 100;
private static final int K = 5;
private static final List<Integer> S = new ArrayList<>(N);
public static void main(String[] args) {
for (int i = 0; i < N; i++) {
S.add(i + 1);
}
Collections.shuffle(S, rnd);
for (int i = 0; i < K; i++) {
System.out.print(S.get(i) + " ");
}
System.out.println();
}
I feel like this method is worth mentioning.
private static final Random RANDOM = new Random();
/**
* Pick n numbers between 0 (inclusive) and k (inclusive)
* While there are very deterministic ways to do this,
* for large k and small n, this could be easier than creating
* an large array and sorting, i.e. k = 10,000
*/
public Set<Integer> pickRandom(int n, int k) {
final Set<Integer> picked = new HashSet<>();
while (picked.size() < n) {
picked.add(RANDOM.nextInt(k + 1));
}
return picked;
}
I re-factored Anand's answer to make use not only of the unique properties of a Set but also use the boolean false returned by the set.add() when an add to the set fails.
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class randomUniqueNumberGenerator {
public static final int SET_SIZE_REQUIRED = 10;
public static final int NUMBER_RANGE = 100;
public static void main(String[] args) {
Random random = new Random();
Set set = new HashSet<Integer>(SET_SIZE_REQUIRED);
while(set.size()< SET_SIZE_REQUIRED) {
while (set.add(random.nextInt(NUMBER_RANGE)) != true)
;
}
assert set.size() == SET_SIZE_REQUIRED;
System.out.println(set);
}
}
I have made this like that.
Random random = new Random();
ArrayList<Integer> arrayList = new ArrayList<Integer>();
while (arrayList.size() < 6) { // how many numbers u need - it will 6
int a = random.nextInt(49)+1; // this will give numbers between 1 and 50.
if (!arrayList.contains(a)) {
arrayList.add(a);
}
}
This will work to generate unique random numbers................
import java.util.HashSet;
import java.util.Random;
public class RandomExample {
public static void main(String[] args) {
Random rand = new Random();
int e;
int i;
int g = 10;
HashSet<Integer> randomNumbers = new HashSet<Integer>();
for (i = 0; i < g; i++) {
e = rand.nextInt(20);
randomNumbers.add(e);
if (randomNumbers.size() <= 10) {
if (randomNumbers.size() == 10) {
g = 10;
}
g++;
randomNumbers.add(e);
}
}
System.out.println("Ten Unique random numbers from 1 to 20 are : " + randomNumbers);
}
}
One clever way to do this is to use exponents of a primitive element in modulus.
For example, 2 is a primitive root mod 101, meaning that the powers of 2 mod 101 give you a non-repeating sequence that sees every number from 1 to 100 inclusive:
2^0 mod 101 = 1
2^1 mod 101 = 2
2^2 mod 101 = 4
...
2^50 mod 101 = 100
2^51 mod 101 = 99
2^52 mod 101 = 97
...
2^100 mod 101 = 1
In Java code, you would write:
void randInts() {
int num=1;
for (int ii=0; ii<101; ii++) {
System.out.println(num);
num= (num*2) % 101;
}
}
Finding a primitive root for a specific modulus can be tricky, but Maple's "primroot" function will do this for you.
I have come here from another question, which has been duplicate of this question (Generating unique random number in java)
Store 1 to 100 numbers in an Array.
Generate random number between 1 to 100 as position and return array[position-1] to get the value
Once you use a number in array, mark the value as -1 ( No need to maintain another array to check if this number is already used)
If value in array is -1, get the random number again to fetch new location in array.
I have easy solution for this problem,
With this we can easily generate n number of unique random numbers,
Its just logic anyone can use it in any language.
for(int i=0;i<4;i++)
{
rn[i]= GenerateRandomNumber();
for (int j=0;j<i;j++)
{
if (rn[i] == rn[j])
{
i--;
}
}
}
Choose n unique random numbers from 0 to m-1.
int[] uniqueRand(int n, int m){
Random rand = new Random();
int[] r = new int[n];
int[] result = new int[n];
for(int i = 0; i < n; i++){
r[i] = rand.nextInt(m-i);
result[i] = r[i];
for(int j = i-1; j >= 0; j--){
if(result[i] >= r[j])
result[i]++;
}
}
return result;
}
Imagine a list containing numbers from 0 to m-1. To choose the first number, we simply use rand.nextInt(m). Then remove the number from the list. Now there remains m-1 numbers, so we call rand.nextInt(m-1). The number we get represents the position in the list. If it is less than the first number, then it is the second number, since the part of list prior to the first number wasn't changed by the removal of the first number. If the position is greater than or equal to the first number, the second number is position+1. Do some further derivation, you can get this algorithm.
Explanation
This algorithm has O(n^2) complexity. So it is good for generating small amount of unique numbers from a large set. While the shuffle based algorithm need at least O(m) to do the shuffle.
Also shuffle based algorithm need memory to store every possible outcome to do the shuffle, this algorithm doesn’t need.
Though it's an old thread, but adding another option might not harm. (JDK 1.8 lambda functions seem to make it easy);
The problem could be broken down into the following steps;
Get a minimum value for the provided list of integers (for which to generate unique random numbers)
Get a maximum value for the provided list of integers
Use ThreadLocalRandom class (from JDK 1.8) to generate random integer values against the previously found min and max integer values and then filter to ensure that the values are indeed contained by the originally provided list. Finally apply distinct to the intstream to ensure that generated numbers are unique.
Here is the function with some description:
/**
* Provided an unsequenced / sequenced list of integers, the function returns unique random IDs as defined by the parameter
* #param numberToGenerate
* #param idList
* #return List of unique random integer values from the provided list
*/
private List<Integer> getUniqueRandomInts(List<Integer> idList, Integer numberToGenerate) {
List<Integer> generatedUniqueIds = new ArrayList<>();
Integer minId = idList.stream().mapToInt (v->v).min().orElseThrow(NoSuchElementException::new);
Integer maxId = idList.stream().mapToInt (v->v).max().orElseThrow(NoSuchElementException::new);
ThreadLocalRandom.current().ints(minId,maxId)
.filter(e->idList.contains(e))
.distinct()
.limit(numberToGenerate)
.forEach(generatedUniqueIds:: add);
return generatedUniqueIds;
}
So that, to get 11 unique random numbers for 'allIntegers' list object, we'll call the function like;
List<Integer> ids = getUniqueRandomInts(allIntegers,11);
The function declares new arrayList 'generatedUniqueIds' and populates with each unique random integer up to the required number before returning.
P.S. ThreadLocalRandom class avoids common seed value in case of concurrent threads.
try this out
public class RandomValueGenerator {
/**
*
*/
private volatile List<Double> previousGenValues = new ArrayList<Double>();
public void init() {
previousGenValues.add(Double.valueOf(0));
}
public String getNextValue() {
Random random = new Random();
double nextValue=0;
while(previousGenValues.contains(Double.valueOf(nextValue))) {
nextValue = random.nextDouble();
}
previousGenValues.add(Double.valueOf(nextValue));
return String.valueOf(nextValue);
}
}
This isn't significantly different from other answers, but I wanted the array of integers in the end:
Integer[] indices = new Integer[n];
Arrays.setAll(indices, i -> i);
Collections.shuffle(Arrays.asList(indices));
return Arrays.stream(indices).mapToInt(Integer::intValue).toArray();
you can use boolean array to fill the true if value taken else set navigate through boolean array to get value as per given below
package study;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
Created By Sachin Rane on Jul 18, 2018
*/
public class UniqueRandomNumber {
static Boolean[] boolArray;
public static void main(String s[]){
List<Integer> integers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
integers.add(i);
}
//get unique random numbers
boolArray = new Boolean[integers.size()+1];
Arrays.fill(boolArray, false);
for (int i = 0; i < 10; i++) {
System.out.print(getUniqueRandomNumber(integers) + " ");
}
}
private static int getUniqueRandomNumber(List<Integer> integers) {
int randNum =(int) (Math.random()*integers.size());
if(boolArray[randNum]){
while(boolArray[randNum]){
randNum++;
if(randNum>boolArray.length){
randNum=0;
}
}
boolArray[randNum]=true;
return randNum;
}else {
boolArray[randNum]=true;
return randNum;
}
}
}
This is the most simple method to generate unique random values in a range or from an array.
In this example, I will be using a predefined array but you can adapt this method to generate random numbers as well. First, we will create a sample array to retrieve our data from.
Generate a random number and add it to the new array.
Generate another random number and check if it is already stored in the new array.
If not then add it and continue
else reiterate the step.
ArrayList<Integer> sampleList = new ArrayList<>();
sampleList.add(1);
sampleList.add(2);
sampleList.add(3);
sampleList.add(4);
sampleList.add(5);
sampleList.add(6);
sampleList.add(7);
sampleList.add(8);
Now from the sampleList we will produce five random numbers that are unique.
int n;
randomList = new ArrayList<>();
for(int i=0;i<5;i++){
Random random = new Random();
n=random.nextInt(8); //Generate a random index between 0-7
if(!randomList.contains(sampleList.get(n)))
randomList.add(sampleList.get(n));
else
i--; //reiterating the step
}
This is conceptually very simple. If the random value generated already exists then we will reiterate the step. This will continue until all the values generated are unique.
If you found this answer useful then you can vote it up as it is much simple in concept as compared to the other answers.
Check this
public class RandomNumbers {
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 5;
int A[] = uniqueRandomArray(n);
for(int i = 0; i<n; i++){
System.out.println(A[i]);
}
}
public static int[] uniqueRandomArray(int n){
int [] A = new int[n];
for(int i = 0; i< A.length; ){
if(i == A.length){
break;
}
int b = (int)(Math.random() *n) + 1;
if(f(A,b) == false){
A[i++] = b;
}
}
return A;
}
public static boolean f(int[] A, int n){
for(int i=0; i<A.length; i++){
if(A[i] == n){
return true;
}
}
return false;
}
}
Below is a way I used to generate unique number always. Random function generates number and stores it in textfile then next time it checks it in file compares it and generate new unique number hence in this way there is always a new unique number.
public int GenerateRandomNo()
{
int _min = 0000;
int _max = 9999;
Random _rdm = new Random();
return _rdm.Next(_min, _max);
}
public int rand_num()
{
randnum = GenerateRandomNo();
string createText = randnum.ToString() + Environment.NewLine;
string file_path = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + #"\Invoices\numbers.txt";
File.AppendAllText(file_path, createText);
int number = File.ReadLines(file_path).Count(); //count number of lines in file
System.IO.StreamReader file = new System.IO.StreamReader(file_path);
do
{
randnum = GenerateRandomNo();
}
while ((file.ReadLine()) == randnum.ToString());
file.Close();
return randnum;
}
You can use the Collections class.
A utility class called Collections offers different actions that can be performed on a collection like an ArrayList (e.g., search the elements, find the maximum or minimum element, reverse the order of elements, and so on). One of the actions it can perform is to shuffle the elements. The shuffle will randomly move each element to a different position in the list. It does this by using a Random object. This means it's deterministic randomness, but it will do in most situations.
To shuffle the ArrayList, add the Collections import to the top of the program and then use the Shuffle static method. It takes the ArrayList to be shuffled as a parameter:
import java.util.Collections;
import java.util.ArrayList;
public class Lottery {
public static void main(String[] args) {
//define ArrayList to hold Integer objects
ArrayList numbers = new ArrayList();
for(int i = 0; i < 100; i++)
{
numbers.add(i+1);
}
Collections.shuffle(numbers);
System.out.println(numbers);
}
}
You can generate n unique random number between 0 to n-1 in java
public static void RandomGenerate(int n)
{
Set<Integer> st=new HashSet<Integer>();
Random r=new Random();
while(st.size()<n)
{
st.add(r.nextInt(n));
}
}
I'm trying to get random numbers between 0 and 100. But I want them to be unique, not repeated in a sequence. For example if I got 5 numbers, they should be 82,12,53,64,32 and not 82,12,53,12,32
I used this, but it generates same numbers in a sequence.
Random rand = new Random();
selected = rand.nextInt(100);
Add each number in the range sequentially in a list structure.
Shuffle it.
Take the first 'n'.
Here is a simple implementation. This will print 3 unique random numbers from the range 1-10.
import java.util.ArrayList;
import java.util.Collections;
public class UniqueRandomNumbers {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i=1; i<11; i++) list.add(i);
Collections.shuffle(list);
for (int i=0; i<3; i++) System.out.println(list.get(i));
}
}
The first part of the fix with the original approach, as Mark Byers pointed out in an answer now deleted, is to use only a single Random instance.
That is what is causing the numbers to be identical. A Random instance is seeded by the current time in milliseconds. For a particular seed value, the 'random' instance will return the exact same sequence of pseudo random numbers.
With Java 8+ you can use the ints method of Random to get an IntStream of random values then distinct and limit to reduce the stream to a number of unique random values.
ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);
Random also has methods which create LongStreams and DoubleStreams if you need those instead.
If you want all (or a large amount) of the numbers in a range in a random order it might be more efficient to add all of the numbers to a list, shuffle it, and take the first n because the above example is currently implemented by generating random numbers in the range requested and passing them through a set (similarly to Rob Kielty's answer), which may require generating many more than the amount passed to limit because the probability of a generating a new unique number decreases with each one found. Here's an example of the other way:
List<Integer> range = IntStream.range(0, 100).boxed()
.collect(Collectors.toCollection(ArrayList::new));
Collections.shuffle(range);
range.subList(0, 99).forEach(System.out::println);
Create an array of 100 numbers, then randomize their order.
Devise a pseudo-random number generator that has a range of 100.
Create a boolean array of 100 elements, then set an element true when you pick that number. When you pick the next number check against the array and try again if the array element is set. (You can make an easy-to-clear boolean array with an array of long where you shift and mask to access individual bits.)
Use Collections.shuffle() on all 100 numbers and select the first five, as shown here and below.
Console:
59 9 68 24 82
Code:
private static final Random rnd = new Random();
private static final int N = 100;
private static final int K = 5;
private static final List<Integer> S = new ArrayList<>(N);
public static void main(String[] args) {
for (int i = 0; i < N; i++) {
S.add(i + 1);
}
Collections.shuffle(S, rnd);
for (int i = 0; i < K; i++) {
System.out.print(S.get(i) + " ");
}
System.out.println();
}
I feel like this method is worth mentioning.
private static final Random RANDOM = new Random();
/**
* Pick n numbers between 0 (inclusive) and k (inclusive)
* While there are very deterministic ways to do this,
* for large k and small n, this could be easier than creating
* an large array and sorting, i.e. k = 10,000
*/
public Set<Integer> pickRandom(int n, int k) {
final Set<Integer> picked = new HashSet<>();
while (picked.size() < n) {
picked.add(RANDOM.nextInt(k + 1));
}
return picked;
}
I re-factored Anand's answer to make use not only of the unique properties of a Set but also use the boolean false returned by the set.add() when an add to the set fails.
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class randomUniqueNumberGenerator {
public static final int SET_SIZE_REQUIRED = 10;
public static final int NUMBER_RANGE = 100;
public static void main(String[] args) {
Random random = new Random();
Set set = new HashSet<Integer>(SET_SIZE_REQUIRED);
while(set.size()< SET_SIZE_REQUIRED) {
while (set.add(random.nextInt(NUMBER_RANGE)) != true)
;
}
assert set.size() == SET_SIZE_REQUIRED;
System.out.println(set);
}
}
I have made this like that.
Random random = new Random();
ArrayList<Integer> arrayList = new ArrayList<Integer>();
while (arrayList.size() < 6) { // how many numbers u need - it will 6
int a = random.nextInt(49)+1; // this will give numbers between 1 and 50.
if (!arrayList.contains(a)) {
arrayList.add(a);
}
}
This will work to generate unique random numbers................
import java.util.HashSet;
import java.util.Random;
public class RandomExample {
public static void main(String[] args) {
Random rand = new Random();
int e;
int i;
int g = 10;
HashSet<Integer> randomNumbers = new HashSet<Integer>();
for (i = 0; i < g; i++) {
e = rand.nextInt(20);
randomNumbers.add(e);
if (randomNumbers.size() <= 10) {
if (randomNumbers.size() == 10) {
g = 10;
}
g++;
randomNumbers.add(e);
}
}
System.out.println("Ten Unique random numbers from 1 to 20 are : " + randomNumbers);
}
}
One clever way to do this is to use exponents of a primitive element in modulus.
For example, 2 is a primitive root mod 101, meaning that the powers of 2 mod 101 give you a non-repeating sequence that sees every number from 1 to 100 inclusive:
2^0 mod 101 = 1
2^1 mod 101 = 2
2^2 mod 101 = 4
...
2^50 mod 101 = 100
2^51 mod 101 = 99
2^52 mod 101 = 97
...
2^100 mod 101 = 1
In Java code, you would write:
void randInts() {
int num=1;
for (int ii=0; ii<101; ii++) {
System.out.println(num);
num= (num*2) % 101;
}
}
Finding a primitive root for a specific modulus can be tricky, but Maple's "primroot" function will do this for you.
I have come here from another question, which has been duplicate of this question (Generating unique random number in java)
Store 1 to 100 numbers in an Array.
Generate random number between 1 to 100 as position and return array[position-1] to get the value
Once you use a number in array, mark the value as -1 ( No need to maintain another array to check if this number is already used)
If value in array is -1, get the random number again to fetch new location in array.
I have easy solution for this problem,
With this we can easily generate n number of unique random numbers,
Its just logic anyone can use it in any language.
for(int i=0;i<4;i++)
{
rn[i]= GenerateRandomNumber();
for (int j=0;j<i;j++)
{
if (rn[i] == rn[j])
{
i--;
}
}
}
Choose n unique random numbers from 0 to m-1.
int[] uniqueRand(int n, int m){
Random rand = new Random();
int[] r = new int[n];
int[] result = new int[n];
for(int i = 0; i < n; i++){
r[i] = rand.nextInt(m-i);
result[i] = r[i];
for(int j = i-1; j >= 0; j--){
if(result[i] >= r[j])
result[i]++;
}
}
return result;
}
Imagine a list containing numbers from 0 to m-1. To choose the first number, we simply use rand.nextInt(m). Then remove the number from the list. Now there remains m-1 numbers, so we call rand.nextInt(m-1). The number we get represents the position in the list. If it is less than the first number, then it is the second number, since the part of list prior to the first number wasn't changed by the removal of the first number. If the position is greater than or equal to the first number, the second number is position+1. Do some further derivation, you can get this algorithm.
Explanation
This algorithm has O(n^2) complexity. So it is good for generating small amount of unique numbers from a large set. While the shuffle based algorithm need at least O(m) to do the shuffle.
Also shuffle based algorithm need memory to store every possible outcome to do the shuffle, this algorithm doesn’t need.
Though it's an old thread, but adding another option might not harm. (JDK 1.8 lambda functions seem to make it easy);
The problem could be broken down into the following steps;
Get a minimum value for the provided list of integers (for which to generate unique random numbers)
Get a maximum value for the provided list of integers
Use ThreadLocalRandom class (from JDK 1.8) to generate random integer values against the previously found min and max integer values and then filter to ensure that the values are indeed contained by the originally provided list. Finally apply distinct to the intstream to ensure that generated numbers are unique.
Here is the function with some description:
/**
* Provided an unsequenced / sequenced list of integers, the function returns unique random IDs as defined by the parameter
* #param numberToGenerate
* #param idList
* #return List of unique random integer values from the provided list
*/
private List<Integer> getUniqueRandomInts(List<Integer> idList, Integer numberToGenerate) {
List<Integer> generatedUniqueIds = new ArrayList<>();
Integer minId = idList.stream().mapToInt (v->v).min().orElseThrow(NoSuchElementException::new);
Integer maxId = idList.stream().mapToInt (v->v).max().orElseThrow(NoSuchElementException::new);
ThreadLocalRandom.current().ints(minId,maxId)
.filter(e->idList.contains(e))
.distinct()
.limit(numberToGenerate)
.forEach(generatedUniqueIds:: add);
return generatedUniqueIds;
}
So that, to get 11 unique random numbers for 'allIntegers' list object, we'll call the function like;
List<Integer> ids = getUniqueRandomInts(allIntegers,11);
The function declares new arrayList 'generatedUniqueIds' and populates with each unique random integer up to the required number before returning.
P.S. ThreadLocalRandom class avoids common seed value in case of concurrent threads.
try this out
public class RandomValueGenerator {
/**
*
*/
private volatile List<Double> previousGenValues = new ArrayList<Double>();
public void init() {
previousGenValues.add(Double.valueOf(0));
}
public String getNextValue() {
Random random = new Random();
double nextValue=0;
while(previousGenValues.contains(Double.valueOf(nextValue))) {
nextValue = random.nextDouble();
}
previousGenValues.add(Double.valueOf(nextValue));
return String.valueOf(nextValue);
}
}
This isn't significantly different from other answers, but I wanted the array of integers in the end:
Integer[] indices = new Integer[n];
Arrays.setAll(indices, i -> i);
Collections.shuffle(Arrays.asList(indices));
return Arrays.stream(indices).mapToInt(Integer::intValue).toArray();
you can use boolean array to fill the true if value taken else set navigate through boolean array to get value as per given below
package study;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/*
Created By Sachin Rane on Jul 18, 2018
*/
public class UniqueRandomNumber {
static Boolean[] boolArray;
public static void main(String s[]){
List<Integer> integers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
integers.add(i);
}
//get unique random numbers
boolArray = new Boolean[integers.size()+1];
Arrays.fill(boolArray, false);
for (int i = 0; i < 10; i++) {
System.out.print(getUniqueRandomNumber(integers) + " ");
}
}
private static int getUniqueRandomNumber(List<Integer> integers) {
int randNum =(int) (Math.random()*integers.size());
if(boolArray[randNum]){
while(boolArray[randNum]){
randNum++;
if(randNum>boolArray.length){
randNum=0;
}
}
boolArray[randNum]=true;
return randNum;
}else {
boolArray[randNum]=true;
return randNum;
}
}
}
This is the most simple method to generate unique random values in a range or from an array.
In this example, I will be using a predefined array but you can adapt this method to generate random numbers as well. First, we will create a sample array to retrieve our data from.
Generate a random number and add it to the new array.
Generate another random number and check if it is already stored in the new array.
If not then add it and continue
else reiterate the step.
ArrayList<Integer> sampleList = new ArrayList<>();
sampleList.add(1);
sampleList.add(2);
sampleList.add(3);
sampleList.add(4);
sampleList.add(5);
sampleList.add(6);
sampleList.add(7);
sampleList.add(8);
Now from the sampleList we will produce five random numbers that are unique.
int n;
randomList = new ArrayList<>();
for(int i=0;i<5;i++){
Random random = new Random();
n=random.nextInt(8); //Generate a random index between 0-7
if(!randomList.contains(sampleList.get(n)))
randomList.add(sampleList.get(n));
else
i--; //reiterating the step
}
This is conceptually very simple. If the random value generated already exists then we will reiterate the step. This will continue until all the values generated are unique.
If you found this answer useful then you can vote it up as it is much simple in concept as compared to the other answers.
Check this
public class RandomNumbers {
public static void main(String[] args) {
// TODO Auto-generated method stub
int n = 5;
int A[] = uniqueRandomArray(n);
for(int i = 0; i<n; i++){
System.out.println(A[i]);
}
}
public static int[] uniqueRandomArray(int n){
int [] A = new int[n];
for(int i = 0; i< A.length; ){
if(i == A.length){
break;
}
int b = (int)(Math.random() *n) + 1;
if(f(A,b) == false){
A[i++] = b;
}
}
return A;
}
public static boolean f(int[] A, int n){
for(int i=0; i<A.length; i++){
if(A[i] == n){
return true;
}
}
return false;
}
}
Below is a way I used to generate unique number always. Random function generates number and stores it in textfile then next time it checks it in file compares it and generate new unique number hence in this way there is always a new unique number.
public int GenerateRandomNo()
{
int _min = 0000;
int _max = 9999;
Random _rdm = new Random();
return _rdm.Next(_min, _max);
}
public int rand_num()
{
randnum = GenerateRandomNo();
string createText = randnum.ToString() + Environment.NewLine;
string file_path = System.IO.Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath) + #"\Invoices\numbers.txt";
File.AppendAllText(file_path, createText);
int number = File.ReadLines(file_path).Count(); //count number of lines in file
System.IO.StreamReader file = new System.IO.StreamReader(file_path);
do
{
randnum = GenerateRandomNo();
}
while ((file.ReadLine()) == randnum.ToString());
file.Close();
return randnum;
}
You can use the Collections class.
A utility class called Collections offers different actions that can be performed on a collection like an ArrayList (e.g., search the elements, find the maximum or minimum element, reverse the order of elements, and so on). One of the actions it can perform is to shuffle the elements. The shuffle will randomly move each element to a different position in the list. It does this by using a Random object. This means it's deterministic randomness, but it will do in most situations.
To shuffle the ArrayList, add the Collections import to the top of the program and then use the Shuffle static method. It takes the ArrayList to be shuffled as a parameter:
import java.util.Collections;
import java.util.ArrayList;
public class Lottery {
public static void main(String[] args) {
//define ArrayList to hold Integer objects
ArrayList numbers = new ArrayList();
for(int i = 0; i < 100; i++)
{
numbers.add(i+1);
}
Collections.shuffle(numbers);
System.out.println(numbers);
}
}
You can generate n unique random number between 0 to n-1 in java
public static void RandomGenerate(int n)
{
Set<Integer> st=new HashSet<Integer>();
Random r=new Random();
while(st.size()<n)
{
st.add(r.nextInt(n));
}
}
int[] drawNumbers = new int[10];//Array With 10 Random Numbers USED for DRAWN NUMBERS
String x = "Drawn Numbers: ";
List<Ticket> ticketWon ;
do{
//GENERATING 10 Random Numbers
for (int i = 0; i <= drawNumbers.length -1 ; i++) {
Random r = new Random();
drawNumbers[i] = r.nextInt(99) + 1;
x += drawNumbers[i] + " ";
}
}
I'm trying to generate 10 random numbers that must be random generated and Unique. My problem is that with Random r = new Random() there are times that replicated numbers are shown. How can i generate 10 random numbers from range 1 to 99 without replications?
Problem is for a Lottery System
I would like to use Collection.Shuffle but I'm not that sure how it should be implemented.
Here is an alternative way to achieve your desired result. We populate a list with values 1 to 99. Then we shuffle the list and grab the first 10 values:
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i=1; i<100; i++) {
list.add(new Integer(i));
}
Collections.shuffle(list);
for (int i=0; i<10; i++) {
System.out.println(list.get(i));
}
}
You won't have to import/directly deal with Random, which is a plus. However, as pointed out by #Voicu (in the comments), shuffle does indeed utilize random:
public static void shuffle(List<?> list) {
if (r == null) {
r = new Random();
}
shuffle(list, r);
}
private static Random r;
You can broadly think of this problem as having a deck of cards numbered from 1 to 99, and you want to pick 10 of those cards. The solution would be to, programmatically, create that deck and then randomly select from that deck and remove from the deck.
We can model the deck as a List of Integers and populate that List with entries from 1 to 99 with something like this:
List<Integer> deck = new ArrayList<Integer>();
for( int i=1; i<=99; i++ ){
deck.add( i );
}
We then need to pick a random card between the 0th card (lists are numbered starting at 0) and the number of elements in the list:
int draw = r.nextRandom( deck.size() );
Integer card = deck.remove( draw );
And repeat that 10 times, doing something with the "card" (say, putting it into an array, or another list, or whatever:
int drawNumbers = new int[10];
for( int co=0; co<10; co++ ){
int draw = r.nextRandom( deck.size() );
Integer card = deck.remove( draw );
drawNumbers[co] = card;
}
Use Set<Integer>.
Set<Integer> set = new HashSet<Integer>();
int[] drawNumbers = new int[10];
Random r = new Random();
for(int i=0; i<10; i++)
{
drawNumbers[i] = r.nextInt(99) + 1;
while(set.contains(drawNumbers[i]))
drawNumbers[i] = r.nextInt(99) + 1;
set.add(drawNumbers[i]);
}
I'd generate random numbers and save them to a Set until I get 10 numbers. Then create a list from it, shuffle it, and then take numbers from it.
final int NUMBERS_TO_DRAW = 10;
Random r = new Random();
// Generate NUMBERS_TO_DRAW random numbers
Set<Integer> randoms = new HashSet<>();
while (randoms.size() < NUMBERS_TO_DRAW) {
randoms.add(r.nextInt(99) + 1);
}
// Now shuffle them:
List<Integer> shuffledRandom = new ArrayList<>(randoms);
Collections.shuffle(shuffledRandom);
EDIT:
As #MarkPeters noted in the comments, using a LinkedHashSet would eliminate the need to shuffle:
final int NUMBERS_TO_DRAW = 10;
Random r = new Random();
// Generate NUMBERS_TO_DRAW random numbers
LinkedHashSet<Integer> randoms = new LinkedHashSet<>();
while (randoms.size() < NUMBERS_TO_DRAW) {
randoms.add(r.nextInt(99) + 1);
}
It would be easier to use a list so you could check if it already contains the number and re-generate if it does.
List<Integer> drawNumbers = new ArrayList<Integer>();
Random r = new Random();
int newNumber = -1;
do
{
newNumber = r.nextInt(99) + 1;
} while(drawNumbers.contains(newNumber); //Make sure the number is not already in the list.
Then put this in a loop to repeat 10 times.
I need to make a typical integer filled array with 10 random non repeating numbers from 0 to 20. Also, I need to be able to modify this so I can exclude some random numbers from 0 to 20.
How can I do this?
You can do this in three easy steps:
Build a list with all the candidate numbers you want
Use Collections.shuffle to shuffle that list
Use the n first elements of that shuffled list.
First build a list of size 20 with values 0,...,19
Then shuffle() it
And last - take the sublist containing first 10 elements.
This Method will work for you. It generate 10 unique random numbers from 0 to 20.
public static int[] getRandomArray(){
int randomCount =10;
int maxRandomNumber = 21;
if(randomCount >maxRandomNumber ){
/* if randomCount is greater than maxRandomNumber
* it will not be possible to generate randomCount
* unique numbers
**/
return null;
}
HashMap<Integer, Integer> duplicateChecker = new HashMap<Integer, Integer>();
int[] arr = new int[randomCount ];
int i = 0;
while(i<randomCount ){
// Generate random between 0-20, higher limit 21 is excluded
int random = new Random().nextInt(maxRandomNumber );
if(duplicateChecker.containsKey(random)==false){
duplicateChecker.put(random, random);
arr[i]=random;
i++;
}
}
return arr;
}
* Edited: To make the method deterministic. And Avoid the chance of infinite loop
public static int[] getRandomArray(){
int randomCount =10;
int maxRandomNumber = 21;
if(randomCount >maxRandomNumber ){
/* if randomCount is greater than maxRandomNumber
* it will not be possible to generate randomCount
* unique numbers
**/
return null;
}
ArrayList<Integer> arrayList = new ArrayList<Integer>();
// Generate an arrayList of all Integers
for(int i=0;i<maxRandomNumber;i++){
arrayList.add(i);
}
int[] arr = new int[randomCount ];
for(int i=0;i<randomCount;i++){
// Generate random between 0-20, higher limit 21 is excluded
int random = new Random().nextInt(arrayList.size());
// Remove integer from location 'random' and assign it to arr[i]
arr[i]=arrayList.remove(random);
}
return arr;
}
What about making an arraylist of numbers upto 20, and after each random number call you remove the number from the list and into the array.
example
Random r = new Random();
int[] myArray = new int[10];
ArrayList<Integer> numsToChoose = new ArrayList<Integer>();
int counter = 0;
for(int i = 0; i < 21; i++)
{
numsToChoose.add(i);
}
while(numsToChoose.size() > 11)
{
myArray[counter] = numsToChoose.remove(r.nextInt(numsToChoose.size()));
counter++;
}
That way it should only loop 10 times, I may be wrong though.
Hope it helps
EDIT: And in order to modify this to exclude certain numbers, you would just need a method that takes an array that contains said numbers as a parameter, and loop through it removing each number from the arraylist before you generate your random numbers.
Most of the other responses offer the Collections.shuffle method as a solution. Another way, which is theoretically faster is the following:
First lets build the list:
public class RandomWithoutReplacement {
private int [] allowableNumbers;
private int totalRemaining;
/**
* #param upperbound the numbers will be in the range from 0 to upperbound (exclusive).
*/
public RandomWithoutReplacement ( int upperbound ) {
allowableNumbers = new int[ upperbound ];
for (int i = 0; i < upperbound; i++) {
allowableNumbers[i] = i;
}
totalRemaining = upperbound;
}
}
Next lets consider what we need to do when we need to get the next number.
1) When we request another number, it must be chosen from any one of the available, uniformly.
2) Once it is chosen, it must not repeat again.
Here is what we can do:
First, choose a number at random from the allowableNumbers array.
Then, remove it from the array.
Then remove the number at the end of the array, and place it in the position of the number we are to return.
This ensures all of the 2 conditions we have placed.
public int nextRandom () {
//Get a random index
int nextIndex = (int) ( Math.random() * totalRemaining );
//Get the value at that index
int toReturn = allowableNumbers [ nextIndex ];
//Find the last value
int lastValue = allowableNumbers [ totalRemaining - 1 ];
//Replace the one at the random index with the last one
allowableNumbers[ nextIndex ] = lastValue;
//Forget about the last one
totalRemaining -- ;
return toReturn;
}
With that, your function is almost complete.
I would add a couple more things just in case:
public boolean hasNext () {
return totalRemaining > 0;
}
And at the beginning of the actual function:
public int nextRandom () {
if (! hasNext() )
throw new IllegalArgumentException();
// same as before...
}
That should be it!
Well, I could't help it not to post my solution which is storing a sequance of numbers into twice as many random locations first. Then compacts it into the resultting array.
int[] myRandomSet = generateNumbers(20, 10);
...
public int[] generateNumbers(int range, int arrayLenght){
int tempArray[];
int resultArray[];
int doubleLocations;
Random generator = new Random();
doubleLocations = range * 2;
tempArray = new int[doubleLocations];
resultArray = new int[arrayLenght];
for (int i=1; i<=range; i++){
if (i != 5 && i != 13){ //exclude some numbers
do{
r = generator.nextInt(doubleLocations);
}while(tempArray[r]!=0);
tempArray[r] = i; //enter the next number from the range into a random position
}
}
int k = 0;
for (int i=0; i<(doubleLocations); i++){
if(tempArray[i] != 0){
resultArray[k] = tempArray[i]; //compact temp array
k++;
if (k == arrayLenght) break;
}
}
return resultArray;
}