Este capítulo primero explica varias formas de generar números aleatorios Java y luego los demuestra a través de ejemplos.
Descripción general:
¿Dirás aquí, ¿cuál es la dificultad de generar números aleatorios? ¿No es solo usar Java encapsulado aleatorio? Por supuesto, está bien en general, y los algoritmos se explicarán en este artículo también se basan en esta función de biblioteca aleatoria.
Este artículo se centra principalmente en el comportamiento del muestreo, y el muestreo en sí tiene una regla implícita que no tiene datos duplicados. Ok, con estas instrucciones. Primero puede intentar usar algunas de sus propias ideas para generar números aleatorios sin una generación repetida.
Intentos de algoritmo:
Aparecen algunos buenos algoritmos, a menudo acompañados de algunos algoritmos no tan buenos. Sin embargo, para los algoritmos que no son muy efectivos, generalmente tienen una característica común, que es fácil de entender e implementar. La siguiente es una breve explicación a través de un enfoque paso a paso.
Primer intento: algoritmo ingenuo aleatorio
Este algoritmo es fácil de entender, ¡es aleatorio! Cada vez que se genera un número aleatorio y se agrega al conjunto.
Void privado SimpleRandom (int inicio, int end, int count) {System.out.println ("Algoritmo aleatorio natural:"); StringBuffer Buffer = new StringBuffer (); for (int i = 0; i <count; i ++) {int random = numinUtils.randomInTeger (inicio, final); buffer.append (i == 0? ("[" + aleatorio): ("," + aleatorio)); } buffer.append ("]"); System.out.println (buffer); } El segundo intento: verificar el algoritmo aleatorio existencial
Sabemos que hay un problema con el método anterior, es decir, puede haber datos duplicados. Entonces, pensamos en verificar si el número ya existe al generar un número aleatorio, y si existe, se regenerará.
Private void Checkrandom (int inicio, int end, int count) {System.out.println ("Verifique el algoritmo aleatorio existencial:"); StringBuffer Buffer = new StringBuffer (); List <integer> save = new ArrayList <> (); for (int i = 0; i <count; i ++) {int random = numinUtils.randomInTeger (inicio, final); if (exits (save, aleation)) {i--; continuar; } save.add (aleatorio); buffer.append (i == 0? ("[" + aleatorio): ("," + aleatorio)); } buffer.append ("]"); System.out.println (buffer); } El tercer intento: algoritmo aleatorio de eliminación de elementos
El algoritmo anterior ha resuelto el problema de la duplicación de datos. Sin embargo, un problema muy malo es que puede llevarnos mucho tiempo generar números aleatorios de muestra (esto depende de la cara ...).
Sin embargo, aquí tenemos nuevas ideas. Eso es usar aleatoriamente un número en un conjunto y eliminarlo cuando esto se seleccione. Entonces, ¿no volverás a alcanzar al azar este número cuando sea aleatorio? Esto resuelve muy bien el problema de la repetición de números aleatorios. El código es el siguiente:
privado void removerandom (int inicio, int end, int count) {System.out.println ("Elemento eliminación del algoritmo aleatorio:"); StringBuffer Buffer = new StringBuffer (); List <integer> números = initList (inicio, final); for (int i = 0; i <count; i ++) {int random = numberUtils.randomInTEGER (count - i); buffer.append (i == 0? ("[" + números.get (aleatorio)): ("," + números.get (random))); números.remove (aleatorio); } buffer.append ("]"); System.out.println (buffer); } Cuarto intento: algoritmo aleatorio de transferencia de estado
En muchos de mis blogs anteriores, algunos son procesos de transferencia de estado en algoritmos. State Transfer también es uno de mis algoritmos favoritos. La Figura 1 a continuación marca el rango de valor de los números aleatorios, y el número de naranja en la secuencia es la secuencia aleatoria en el resultado. Hay algunas flechas punteadas en la secuencia inferior, que representan la transición del estado.
Figura 1 Algoritmo de generación de números aleatorios de muestreo basado en la transición de estado
Código de implementación:
statusrandom privado void (int inicio, int end, int count) {System.out.println ("Algoritmo aleatorio de transferencia de estado:"); StringBuffer Buffer = new StringBuffer (); int [] status = new int [end + 1]; for (int i = 0; i <count; i ++) {int random = numinUtils.randomInTeger (inicio, final); System.err.println (aleatorio); if (status [random] == 0) {buffer.append (i == 0? ("[" + aleatorio): ("," + aleatorio)); Estado [Random] = Random == end? inicio: (aleatorio + 1); // es imposible tener un número antes de inicio} else {// status transfer int index = random; do {index = status [index]; } while (status [index]! = 0); buffer.append (i == 0? ("[" + índice): ("," + index)); estado [index] = index == end? Inicio: (índice + 1); // es imposible tener un número antes de inicio}} buffer.append ("]"); System.out.println (buffer); } El quinto intento: algoritmo aleatorio recursivo de Floyd
El algoritmo Floyd es, en última instancia, un proceso de transferencia de estado. El algoritmo requerirá una lista o una matriz para almacenar el número aleatorio determinado. Como su nombre indica, usaré soluciones recursivas aquí. En el proceso de recursión, transferimos el estado del número aleatorio I-th al número aleatorio I-1. El código es el siguiente:
Lista privada <Integer> SimpleFloyd (List <Integer> List, int Count, int inicio, int end) {if (count == 0) {return List; } list = simplefloyd (list, count - 1, inicio, finalización - 1); int random = numberUtils.randomInTeger (inicio, final); if (list.contains (random)) {list.add (end); } else {list.add (aleatorio); } Lista de retorno; } Sexto intento: iterar sobre el algoritmo aleatorio de Floyd
La idea es similar al algoritmo aleatorio de Floyd recursivo anterior, pero aquí agregamos una variable para optimizar. Ya no hay necesidad de recurrir. El código es el siguiente:
Lista privada <Integer> iterationFloyd (int inicio, int end, int count) {System.out.println ("Algoritmo aleatorio iterativo de Floyd:"); List <integer> list = new ArrayList <> (); for (int i = end - count+1; i <end; i ++) {int random = numinUtilss.randomInTeger (inicio, i); if (list.contains (random)) {list.add (i); } else {list.add (aleatorio); }} lista de retorno; } Resultados de la prueba:
Figura 2 Resultados de la prueba de algoritmo de generación de números aleatorios
En los resultados de las pruebas anteriores, podemos ver claramente que el algoritmo aleatorio ingenuo no solo tiene datos duplicados, sino que también es el más lento. Por lo tanto, evite usar este algoritmo al generar números aleatorios muestreados. Entre los últimos algoritmos, el algoritmo aleatorio de transferencia de estado es el mejor, y el algoritmo aleatorio iterativo de Floyd es el segundo. Esto se puede hacer de acuerdo con las preferencias personales.