Estoy tratando de obtener números aleatorios entre 0 y 100. Pero quiero que sean únicos, no repetidos en una secuencia. Por ejemplo, si tengo 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);
1..100
(existen algoritmos famosos para eso), pero deténgase después de haber determinado los primerosn
elementos.Respuestas:
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<Integer> list = new ArrayList<Integer>(); 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
Random
instancia.Eso es lo que hace que los números sean idénticos. Una
Random
instancia es sembrada por la hora actual en milisegundos. Para un valor semilla en particular , la instancia 'aleatoria' devolverá exactamente la misma secuencia de números pseudoaleatorios .El primer bucle for simplemente se puede cambiar a:
for (int i = 1; i < 11; i++) { list.add(i); }
fuente
Con Java 8+, puede usar el
ints
método deRandom
para obtener una cantidadIntStream
de valores aleatoriosdistinct
ylimit
reducir la secuencia a una cantidad de valores aleatorios únicos.ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);
Random
también tiene métodos que creanLongStream
syDoubleStream
s si los necesita en su lugar.Si desea todos (o una gran cantidad) de los números en un rango en un orden aleatorio, podría ser más eficiente agregar todos los números a una lista, mezclarla y tomar la primera n porque el ejemplo anterior está implementado actualmente generando números aleatorios en el rango solicitado y pasándolos a través de un conjunto (de manera similar a la respuesta de Rob Kielty ), lo que puede requerir generar muchos más que la cantidad pasada al límite porque la probabilidad de generar un nuevo número único disminuye con cada uno encontrado. Aquí hay un ejemplo de la otra forma:
List<Integer> range = IntStream.range(0, 100).boxed() .collect(Collectors.toCollection(ArrayList::new)); Collections.shuffle(range); range.subList(0, 99).forEach(System.out::println);
fuente
Arrays#setAll()
es un poco más rápido que una transmisión. Entonces: `Integer [] índices = new Integer [n]; Arrays.setAll (índices, i -> i); Colecciones.shuffle (Arrays.asList (índices)); return Arrays.stream (índices) .mapToInt (Integer :: intValue) .toArray (); `long
dónde cambia y enmascara para acceder a bits individuales).fuente
pick()
es un ejemplo.HashSet
, donde almacena los números que ya ha generado y usacontains
para probar si ya ha generado ese número. ElHashSet
probablemente será ligeramente más lento que una matriz booleana, pero ocupan menos memoria.Utilice
Collections.shuffle()
en los 100 números y seleccione los primeros cinco, como se muestra aquí .fuente
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, 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; }
fuente
Refactoricé la respuesta de Anand para hacer uso no solo de las propiedades únicas de un conjunto, sino que también utilicé el booleano falso devuelto por
set.add()
cuando falla una adición 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<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); } }
fuente
SET_SIZE_REQUIRED
es lo suficientemente grande (digamos, más queNUMBER_RANGE / 2
entonces, tiene un tiempo de ejecución esperado mucho mayor.He hecho esto así.
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); } }
fuente
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<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); } }
fuente
Una forma inteligente de hacer esto es usar exponentes de un elemento primitivo en módulo.
Por ejemplo, 2 es un mod de raíz primitivo 101, lo que significa que los poderes de 2 mod 101 te dan una secuencia no repetitiva que ve todos los números 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, escribirías:
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 "primroot" de Maple lo hará por usted.
fuente
Vine aquí de otra pregunta, que ha sido duplicada de esta pregunta ( Generando un número aleatorio único en Java )
Almacene de 1 a 100 números en una matriz.
Genere un número aleatorio entre 1 y 100 como posición y devuelva la matriz [posición-1] para obtener el valor
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 usa)
Si el valor en la matriz es -1, obtenga el número aleatorio nuevamente para buscar una nueva ubicación en la matriz.
fuente
Tengo una solución fácil para este problema. Con esto podemos generar fácilmente n números aleatorios únicos. Es lógico que cualquiera pueda usarlo en cualquier idioma.
for(int i=0;i<4;i++) { rn[i]= GenerateRandomNumber(); for (int j=0;j<i;j++) { if (rn[i] == rn[j]) { i--; } } }
fuente
break;
after thei—;
probar esto
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); } }
fuente
Esto no es significativamente diferente de otras respuestas, pero quería la matriz de enteros al final:
Integer[] indices = new Integer[n]; Arrays.setAll(indices, i -> i); Collections.shuffle(Arrays.asList(indices)); return Arrays.stream(indices).mapToInt(Integer::intValue).toArray();
fuente
puede usar una matriz booleana para completar el valor verdadero si se toma el valor; de lo contrario, configure navegue a través de la matriz booleana para obtener el valor como 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<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; } } }
fuente
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(m-i); 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 del 0 al m-1. Para elegir el primer número, simplemente usamos
rand.nextInt(m)
. Luego elimine el número de la lista. Ahora quedan números m-1, así que llamamosrand.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 se modificó al eliminar el primer número. Si la posición es mayor o igual que el primer número, el segundo número es la posición + 1. Haga una derivación adicional, puede obtener este algoritmo.Explicación
Este algoritmo tiene complejidad O (n ^ 2). Por lo tanto, es bueno para generar una pequeña cantidad de números únicos a partir de un conjunto grande. Mientras que el algoritmo basado en la reproducción aleatoria necesita al menos O (m) para realizar la reproducción aleatoria.
Además, el algoritmo basado en la reproducción aleatoria necesita memoria para almacenar todos los resultados posibles para realizar la reproducción aleatoria, este algoritmo no es necesario.
fuente
Puede utilizar la clase Colecciones.
Una clase de utilidad llamada Colecciones ofrece diferentes acciones que se pueden realizar en una colección como ArrayList (por ejemplo, buscar los elementos, encontrar el elemento máximo o mínimo, invertir el orden de los elementos, etc.). Una de las acciones que puede realizar es mezclar los elementos. La reproducción aleatoria moverá aleatoriamente cada elemento a una posición diferente en la lista. Lo hace utilizando un objeto aleatorio. Esto significa que es una aleatoriedad determinista, pero funcionará en la mayoría de las situaciones.
Para mezclar ArrayList, agregue la importación de Colecciones en la parte superior del programa y luego use el método estático Shuffle. Se necesita ArrayList para barajar como parámetro:
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); } }
fuente
Aunque es un hilo antiguo, es posible que agregar otra opción no sea perjudicial. (Las funciones lambda de JDK 1.8 parecen facilitar las cosas);
El problema se puede dividir en los siguientes pasos;
Aquí está la función con una descripción:
/** * 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; }
Entonces, para obtener 11 números aleatorios únicos para el objeto de lista 'allIntegers', llamaremos a la función como;
List<Integer> ids = getUniqueRandomInts(allIntegers,11);
La función declara un nuevo arrayList 'generateUniqueIds' y se llena con cada entero aleatorio único hasta el número requerido antes de regresar.
La clase PS ThreadLocalRandom evita el valor de inicialización común en el caso de subprocesos simultáneos.
fuente
Este es el método más simple para generar valores aleatorios únicos en un rango o de una matriz .
En este ejemplo, usaré una matriz predefinida, pero también puede adaptar este método para generar números aleatorios. Primero, crearemos una matriz de muestra para recuperar nuestros datos.
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);
A partir de ahora
sampleList
, produciremos cinco números aleatorios que son únicos.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 }
Esto es conceptualmente muy simple. Si el valor aleatorio generado ya existe, reiteraremos el paso. Esto continuará hasta que todos los valores generados sean únicos.
Si encuentra útil esta respuesta, puede votarla, ya que es mucho más simple en concepto en comparación con las otras respuestas .
fuente
Puede generar n números aleatorios únicos entre 0 y n-1 en 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)); }
}
fuente
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<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; } }
fuente
A continuación se muestra una forma que solía generar siempre un número único. La función aleatoria genera un número y lo almacena en un archivo de texto, luego la próxima vez que lo verifica en el archivo lo compara y genera un nuevo número único, por lo que de esta manera 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; }
fuente