Generación de números aleatorios únicos en Java

Estoy tratando de obtener números aleatorios entre 0 y 100. Pero quiero que sean únicos, no repetidos en una secuencia. Por ejemplo, si obtuve 5 números, deberían ser 82,12,53,64,32 y no 82,12,53,12,32 Usé esto, pero genera los mismos números en una secuencia.

Random rand = new Random(); selected = rand.nextInt(100); 

  • Agregue cada número en el rango secuencialmente en una estructura de lista .
  • Shuffle it.
  • Toma la primera ‘n’.

Aquí hay una implementación simple. Esto imprimirá 3 números aleatorios únicos del rango 1-10.

 import java.util.ArrayList; import java.util.Collections; public class UniqueRandomNumbers { public static void main(String[] args) { ArrayList list = new ArrayList(); for (int i=1; i<11; i++) { list.add(new Integer(i)); } Collections.shuffle(list); for (int i=0; i<3; i++) { System.out.println(list.get(i)); } } } 

La primera parte de la solución con el enfoque original, como señaló Mark Byers en una respuesta ahora eliminada, es usar solo una sola instancia Random .

Eso es lo que está causando que los números sean idénticos. Una instancia Random es sembrada por la hora actual en milisegundos. Para un valor inicial específico , la instancia 'aleatoria' devolverá la misma secuencia exacta de números pseudo aleatorios .

Con Java 8+ puede usar el método de IntStream de Random para obtener un IntStream de valores aleatorios y luego distinct y limit para reducir la secuencia a una serie de valores aleatorios únicos.

 ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println); 

Random también tiene métodos que crean LongStream y DoubleStream si los necesitas.

Si desea todos (o una gran cantidad) de los números en un rango en orden aleatorio, puede ser más eficiente agregar todos los números a una lista, mezclarlos y tomar los primeros n porque el ejemplo anterior se implementa actualmente generando números aleatorios en el rango solicitado y pasándolos a través de un conjunto (similar a la respuesta de Rob Kielty ), lo que puede requerir generar más que la cantidad aprobada para limitar porque la probabilidad de generar un nuevo número único disminuye con cada uno encontrado. Aquí hay un ejemplo de la otra manera:

 List range = IntStream.range(0, 100).boxed() .collect(Collectors.toCollection(ArrayList::new)); Collections.shuffle(range); range.subList(0, 99).forEach(System.out::println); 
  1. Cree una matriz de 100 números, luego aleatorice su orden.
  2. Diseñe un generador de números pseudoaleatorios que tenga un rango de 100.
  3. Crea una matriz booleana de 100 elementos, luego establece un elemento verdadero cuando elijas ese número. Cuando selecciona la siguiente verificación de número en la matriz e intenta nuevamente si el elemento de la matriz está configurado. (Puede crear una matriz booleana fácil de borrar con una matriz de long donde se desplaza y enmascarar para acceder a bits individuales).

Use Collections.shuffle() en los 100 números y seleccione los primeros cinco, como se muestra aquí .

Siento que vale la pena mencionar este método.

  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, ie k = 10,000 */ public Set pickRandom(int n, int k) { final Set picked = new HashSet<>(); while (picked.size() < n) { picked.add(RANDOM.nextInt(k + 1)); } return picked; } 

Volví a factorizar la respuesta de Anand para usar no solo las propiedades únicas de un conjunto, sino también usar el booleano falso devuelto por el set.add() cuando falla un complemento al conjunto.

 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(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); } } 

Esto funcionará para generar números aleatorios únicos …………….

 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 randomNumbers = new HashSet(); 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); } } 

He venido aquí de otra pregunta, que ha sido duplicada de esta pregunta ( generación de un número aleatorio único en java )

  1. Almacene 1 a 100 números en una matriz.

  2. Genere un número aleatorio entre 1 y 100 como posición y retorno matriz [posición-1] para obtener el valor

  3. Una vez que use un número en la matriz, marque el valor como -1 (No es necesario mantener otra matriz para verificar si este número ya se utilizó)

  4. Si value in array es -1, obtenga el número aleatorio de nuevo para obtener una nueva ubicación en la matriz.

He hecho esto así.

  Random random = new Random(); ArrayList arrayList = new ArrayList(); 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); } } 

Una forma inteligente de hacerlo es usar exponentes de un elemento primitivo en el módulo.

Por ejemplo, 2 es una raíz primitiva mod 101, lo que significa que los poderes de 2 mod 101 le dan una secuencia no repetitiva que ve cada número del 1 al 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 

En código Java, deberías escribir:

 void randInts() { int num=1; for (int ii=0; ii<101; ii++) { System.out.println(num); num= (num*2) % 101; } } 

Encontrar una raíz primitiva para un módulo específico puede ser complicado, pero la función "primo" de Maple hará esto por usted.

probar esto

 public class RandomValueGenerator { /** * */ private volatile List previousGenValues = new ArrayList(); 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); } } 

Esto no es significativamente diferente de otras respuestas, pero al final quería la matriz de enteros:

  Integer[] indices = new Integer[n]; Arrays.setAll(indices, i -> i); Collections.shuffle(Arrays.asList(indices)); return Arrays.stream(indices).mapToInt(Integer::intValue).toArray(); 

A continuación se muestra una forma en que solía generar un número único siempre. La función aleatoria genera número y lo almacena en archivo de texto, la próxima vez que lo comprueba en un archivo lo compara y genera un número único nuevo, por lo tanto, siempre hay un nuevo número único.

 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; } 

puede usar una matriz booleana para completar el verdadero valor si se toma else establecer navegar a través de la matriz booleana para obtener el valor según se indica a continuación

 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 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 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; } } } 

Elija n números aleatorios únicos de 0 a 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(mi); result[i] = r[i]; for(int j = i-1; j >= 0; j--){ if(result[i] >= r[j]) result[i]++; } } return result; } 

Imagine una lista que contiene números de 0 a m-1. Para elegir el primer número, simplemente usamos rand.nextInt(m) . Luego elimine el número de la lista. Ahora quedan los números m-1, entonces llamamos a rand.nextInt(m-1) . El número que obtenemos representa la posición en la lista. Si es menor que el primer número, entonces es el segundo número, ya que la parte de la lista anterior al primer número no cambió al eliminar el primer número. Si la posición es mayor o igual que el primer número, el segundo número es posición + 1. Haga alguna derivación adicional, puede obtener este algoritmo.

Mira esto

 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