Cómo elegir aleatoriamente un elemento de una matriz

95

Estoy buscando una solución para elegir un número al azar de una matriz de enteros.

Por ejemplo, tengo una matriz new int[]{1,2,3}, ¿cómo puedo elegir un número al azar?

BreakHead
fuente
Refiera esto
Mithun Sasidharan

Respuestas:

183
public static int getRandom(int[] array) {
    int rnd = new Random().nextInt(array.length);
    return array[rnd];
}
Chris Dennett
fuente
2
sí, pero tienes que decir que generatores una instancia dejava.util.Random
stivlo
26
No crearía Random()cada vez que ejecutas la función: se supone que el generador aleatorio tiene historial. Si no es así, es extremadamente predecible. No es un problema en absoluto en este caso, pero debe mencionarse que array[(int)(System.currentTimeMillis() % array.length)]es tan bueno como la solución propuesta.
alf
6
@alf, eso está lejos de ser tan bueno como la solución propuesta. new Random()intenta crear una instancia que tiene una semilla diferente a cualquier creada anteriormente Random. Su enfoque se rompería horriblemente con solo invocar la función dos veces en poco tiempo.
aioobe
1
@alf, algunos sistemas no tienen un reloj con una precisión de milisegundos, lo que puede excluir algunas opciones sigcd(array.length,clockAccuracy)!=1
fanático del trinquete
3
Acabo de notar una notificación de que voté en contra de esta respuesta; debí haber hecho clic en ella accidentalmente; desafortunadamente, la interfaz no me deja deshacerlo (dice que no puedo cambiar mi voto a menos que se edite la respuesta ...). Entonces, disculpas a Chris Dennett.
Peter Hanley
13

Puede usar el generador aleatorio para generar un índice aleatorio y devolver el elemento en ese índice:

//initialization
Random generator = new Random();
int randomIndex = generator.nextInt(myArray.length);
return myArray[randomIndex];
Luchian Grigore
fuente
9

Si va a obtener un elemento aleatorio varias veces, debe asegurarse de que su generador de números aleatorios se inicialice solo una vez.

import java.util.Random;

public class RandArray {
    private int[] items = new int[]{1,2,3};

    private Random rand = new Random();

    public int getRandArrayElement(){
        return items[rand.nextInt(items.length)];
    }
}

Si está eligiendo elementos de matriz aleatorios que deben ser impredecibles, debe usar java.security.SecureRandom en lugar de Random. Eso asegura que si alguien conoce las últimas selecciones, no tendrá ventaja para adivinar la siguiente.

Si está buscando elegir un número aleatorio de una matriz de objetos utilizando genéricos, puede definir un método para hacerlo (Fuente Avinash R en elemento aleatorio de la matriz de cadenas ):

import java.util.Random;

public class RandArray {
    private static Random rand = new Random();

    private static <T> T randomFrom(T... items) { 
         return items[rand.nextInt(items.length)]; 
    }
}
Stephen Ostermiller
fuente
3

use java.util.Randompara generar un número aleatorio entre 0 y la longitud de la matriz:, random_numbery luego use el número aleatorio para obtener el entero:array[random_number]

James.Xu
fuente
3

Utilice la clase Random :

int getRandomNumber(int[] arr)
{
  return arr[(new Random()).nextInt(arr.length)];
}
AlQafir
fuente
2

También puedes usar

public static int getRandom(int[] array) {
    int rnd = (int)(Math.random()*array.length);
    return array[rnd];
}

Math.random()devuelve doubleentre 0.0(inclusivo) a 1.0(exclusivo)

Multiplicar esto por array.lengthte da doubleentre 0.0(inclusivo) y array.length(exclusivo)

La transmisión a intse redondeará hacia abajo y le dará un número entero entre 0(inclusive) e array.length-1(inclusive)

monstruo del trinquete
fuente
Math.random () devuelve un doble y no un int. Si lo hubiera hecho, habría habido solo dos valores posibles, 0 y 1.
Akshay R.
1

Dado que tiene Java 8, otra solución es utilizar Stream API.

new Random().ints(1, 500).limit(500).forEach(p -> System.out.println(list[p]));

Donde 1es el int más bajo generado (incluido) y 500es el más alto (exclusivo). limitsignifica que su transmisión tendrá una longitud de 500.

 int[] list = new int[] {1,2,3,4,5,6};
 new Random().ints(0, list.length).limit(10).forEach(p -> System.out.println(list[p])); 

Aleatorio es del java.utilpaquete.

Johnny Willer
fuente
0

Java tiene una clase Random en el paquete java.util. Usándolo puede hacer lo siguiente:

Random rnd = new Random();
int randomNumberFromArray = array[rnd.nextInt(3)];

¡Espero que esto ayude!

decaer
fuente
0
package workouts;

import java.util.Random;

/**
 *
 * @author Muthu
 */
public class RandomGenerator {
    public static void main(String[] args) {
     for(int i=0;i<5;i++){
         rndFunc();
     } 
    }
     public static void rndFunc(){
           int[]a= new int[]{1,2,3};
           Random rnd= new Random();
           System.out.println(a[rnd.nextInt(a.length)]);
       }
}

fuente
0

También puede probar este enfoque.

public static <E> E[] pickRandom_(int n,E ...item) {
        List<E> copy = Arrays.asList(item);
        Collections.shuffle(copy);
        if (copy.size() > n) {
            return (E[]) copy.subList(0, n).toArray();
        } else {
            return (E[]) copy.toArray();
        }

    }
Ravi Sapariya
fuente
Así que baraja una lista con O(nlogn)complejidad de tiempo, hace la copia dos veces usando el total de 3 veces más memoria que la matriz inicial, aunque el problema que OP preguntó se puede resolver con O(1)complejidad de tiempo y O(1)memoria ...?
Jaroslaw Pawlak
sí, tienes razón, era mejor hacerlo con una constante complejidad temporal y espacial.
Ravi Sapariya
0
package io.github.baijifeilong.tmp;

import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Stream;

/**
 * Created by [email protected] at 2019/1/3 下午7:34
 */
public class Bar {
    public static void main(String[] args) {
        Stream.generate(() -> null).limit(10).forEach($ -> {
            System.out.println(new String[]{"hello", "world"}[ThreadLocalRandom.current().nextInt(2)]);
        });
    }
}
BaiJiFeiLong
fuente