Generar números aleatorios excepto ciertos valores.

Quiero generar números aleatorios, pero no quiero que sean de una excludematriz. Aquí está mi código.

public int generateRandom(int start, int end, ArrayList<Integer> exclude) {
    Random rand = new Random();
    int range = end - start +1 - exclude.size();
    int random = rand.nextInt(range) + 1;

    for(int i = 0; i < exclude.size(); i++) {
        if(exclude.get(i) > random) {
            return random;
        }
      random++;
    }

    return random;
}

Uso esta función en un ciclo while, y durante cada iteración agrego un nuevo valor exclude. A veces devuelve números que pertenecen exclude. ¿Cuál es el problema?

Respuesta 1

Creo que hay algunos errores.

1) El rango debe ser end - start + 1, porque este es el rango deseado.
2) Si realmente desea números aleatorios (tan "aleatorios" como sea posible en las computadoras), entonces no debería obtener el siguiente número disponible. Porque en este caso, su número aleatorio tendrá las características de densidad / frecuencia de números excluidos.

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) {
    Random rand = new Random();
    int range = end - start + 1;
    int random;

    boolean success = false;
    while(!success) {
        random = rand.nextInt(range) + 1;
        for(Integer i: excludeRows) {
            if(i == random) {
                break;
            } else if (i > random) {
                success = true;
                break;
            }
        }
    }
    return random;
}

ACTUALIZAR

Con la respuesta de Achintya Jha, mi código podría mejorarse (pero tenga en cuenta que también hay algunos comentarios):

public int generateRandom(int start, int end, ArrayList<Integer> excludeRows) {
    Random rand = new Random();
    int range = end - start + 1;

    int random = rand.nextInt(range) + 1;
    while(excludeRows.contains(random)) {
        random = rand.nextInt(range) + 1;
    }

    return random;
}
Respuesta: 2

Compruebas:

for(int i = 0; i < exclude.size(); i++) {
    if(exclude.get(i) > random) {
        return random;
    }

y si solo el primero es más grande, devolverá el valor. ¿Estás seguro de que excludeestá ordenado?

Puede usar if(exclude.contains(random ))el siguiente algoritmo:

Si (end-start) es un número razonable, y necesita casi todos los valores, puede crear una lista de todos los números aceptables y usar aleatorio en este tamaño de lista y elegir el valor aleatorio como índice. luego elimine el número no deseado de la lista y obtenga otro índice aleatorio.

Respuesta: 3

esto funcionó para mí:

    public int randomInt(int start, int end, int... exception) {
        int result = -1;
        Random rand = new Random();
        int range = end - start + 1;
        boolean equals = true;

        while(equals) {
            result = rand.nextInt(range);
            boolean differentOfAll = true;
            for(int i : exception) {
                if(result==i) {
                    differentOfAll = false;
                    break;
                }
            }
            if(differentOfAll) {
                equals = false;
            }
        }

        return result;
    }
Respuesta: 4

Tengo la siguiente situación: taglib.jar: un taglib JSP personalizado empaquetado como un archivo JAR. El archivo TLD es /META-INF/taglib.tld. webapp.war: una aplicación web con archivos JSP que usan las etiquetas proporcionadas ...

Tengo algunas clases de nombres largos que almaceno en la base de datos usando Hibernate. He notado que hibernate crea la columna dtype (para soporte de herencia) como un carácter variable (31). Desde la clase ...

Para una tarea que estoy haciendo, necesito asegurarme de que tengo un algoritmo ejecutándose en tiempo O (n), y estoy usando la función Math.abs () dentro de algunos bucles, así que me pregunto si Math.abs () se ejecuta en O (1) tiempo? ...

Estoy tratando de generar artefactos para el análisis XML log4j usando JAXB. Estoy usando el dtd http://logging.apache.org/log4j/1.2/apidocs/org/ap.../log4j/xml/doc-files/log4j.dtd y log.xml en línea. YO ...