Autor Tema: errata en Clase Random. Ejemplos y Ejercicios resueltos rango numérico CU00906C  (Leído 6423 veces)

calajucha

  • Sin experiencia
  • *
  • Mensajes: 1
    • Ver Perfil
Hola, creo que tienen una errata en el curso de java nivel avanzado I en Clase Random. Ejemplos y Ejercicios resueltos. (CU00906C)

donde dice:

En el caso de necesitar números aleatorios enteros en un rango determinado, podemos trasladarnos a un intervalo distinto, simplemente multiplicando, aplicando la siguiente fórmula general:

(int) (rnd.nextDouble() * cantidad_números_rango + término_inicial_rango)


Esto no es correcto del todo porque desde que el "termino_inicial_rango<0" se saldría del rango. Debería de ser de esta forma:

(int)(rnd.nextDouble() * (b-a) + a)

a = término_inicial_rango
b = cantidad_números_rango
« Última modificación: 03 de Noviembre 2020, 20:33 por César Krall »

Alex Rodríguez

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2050
    • Ver Perfil
Re:errata en Clase Random. Ejemplos y Ejercicios resueltos. (CU00906C)
« Respuesta #1 en: 05 de Septiembre 2013, 14:22 »
Hola calajucha, es posible que se trate de una errata, en alguna ocasión se escapan; aunque si has seguido cursos y otros materiales de la web creo que se puede decir que se escapan pocas y gracias a avisos como este las vamos corrigiendo. Voy a revisarlo y cuando lo haya visto te respondo. Saludos.

Alex Rodríguez

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2050
    • Ver Perfil
Re:errata en Clase Random. Ejemplos y Ejercicios resueltos. (CU00906C)
« Respuesta #2 en: 05 de Septiembre 2013, 20:05 »
He estado revisando lo que indicabas y surgen varias cuestiones.

En primer lugar ¿a qué llamamos cantidad_números_rango? Yo llamaría cantidad_números_rango al valor número superior del rango - número inferior del rango + 1 . Por ejemplo, si se quieren generar enteros entre 1 y 10 cantidad_números_rango sería 10-1+1 = 10. Si se quieren generar enteros entre 2 y 6 tendríamos 6-2+1 = 5

Hay algunas cosas curiosas. Por ejemplo el uso de int(numeroDecimal) devuelve siempre el redondeo a la parte entera de un número. En el caso de números positivos nos devuelve el entero inferior pero en caso de ser números negativos nos devuelve el entero superior

Así int(6.88) devuelve 6 que es el entero inferior pero int(-6.88) devuelve -6 que es el entero superior. En realidad no deberíamos hablar de redondeo, sino simplemente de "parte entera de un número".

Si queremos generar enteros entre 1  y -6 tenemos un problema con una expresión de este tipo:

(int)(rnd2.nextDouble() * 8 + (-6));

¿Cuál es el problema? Que si pretendemos obtener una distribución más o menos uniforme de los números -6, -5, -4, -3, -2, -1, 0, 1 esta fórmula no nos va a ir bien.

Esta fórmula nos devuelve aleatorios entre -6 y 5 con un 12,5 % de probabilidad, entre -5 y -4 con un 12,5 % de probabilidad, entre -4 y -3 con  otro 12,5 %, entre -3 y -2 con otro 12,5 %, entre -2 y -1 con otro 12,5%, entre -1 y 0 con otro 12,5 %, entre 0 y 1 con otro 12,5% y entre 1 y 2 (excluido) con otro 12,5%.

Problema primero: para obtener un -6 necesitaríamos un aleatorio exactamente cero. Si generamos decimales con 16 posiciones decimales significa que la probabilidad de obtener un cero es casi nula, con lo cual obtener un -6 será casi imposible.

Problema segundo: como entre -1 y 0 se toma la parte entera que es cero y entre 0 y 1 se toma la parte entera que es cero, la probabilidad de obtener un cero no es del 12,5 %, sino el doble, el 25%.

En resumen, con esta fórmula hay problemas para intervalos donde intervienen números negativos.

En cambio diría en principio que funciona a la perfección (con distribución uniforme) cuando se trata de un intervalo entre números positivos.

No sé si esto te aclara algo, o al contrario. Yo diría que ni la fórmula planteada en el curso ni la que planteas tú es adecuada en el caso de intervalos con números negativos, en ese caso habría que buscar otras alternativas. Revísalo a ver si estás de acuerdo. Saludos.

Aquí un pequeño programa de pruebas:

Código: [Seleccionar]
/*Numeros aleatorios www.aprenderaprogramar.com*/
import java.util.Random;

public class test {
    public static void main(String[] Args) {
        int num1 =0 ;
        int num2 = 0;
        System.out.println ("Test con aleatorios enteros entre 1 y 6, cantidad_numeros_rango = 6-1+1 = 6");
        Random rnd1 = new Random();
        for (int i =0; i<30; i++) {
            num1 = (int)(rnd1.nextDouble() * 6 + 1);
            System.out.println ("Aleatorio generado: " + num1);
        }
        System.out.println ("Test con aleatorios enteros entre 1 y -6, cantidad_numeros_rango = 1-(-6)+1 = 8");
        Random rnd2 = new Random();
        for (int i =0; i<30; i++) {
            num2 = (int)(rnd2.nextDouble() * 8 + (-6));
            System.out.println ("Aleatorio generado: " + num2);
        }
    }
}

kansadostoy

  • Sin experiencia
  • *
  • Mensajes: 26
    • Ver Perfil
Re:errata en Clase Random. Ejemplos y Ejercicios resueltos. (CU00906C)
« Respuesta #3 en: 10 de Septiembre 2013, 11:18 »
Hola Alex, no me queda claro si es una errata y si es una errata si la van a corregir o no

Alex Rodríguez

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2050
    • Ver Perfil
Re:errata en Clase Random. Ejemplos y Ejercicios resueltos. (CU00906C)
« Respuesta #4 en: 12 de Septiembre 2013, 17:26 »
Sí, puede considerarse como una errata o incorrección.

El cambio sería el siguiente:

Donde dice "En el caso de necesitar números aleatorios enteros en un rango determinado, podemos trasladarnos a un intervalo..."

Debe decir "En el caso de necesitar números aleatorios enteros positivos en un rango determinado, podemos trasladarnos a un intervalo..."

Creo que con este cambio quedaría corregido.

kansadostoy

  • Sin experiencia
  • *
  • Mensajes: 26
    • Ver Perfil
Re:errata en Clase Random. Ejemplos y Ejercicios resueltos. (CU00906C)
« Respuesta #5 en: 14 de Septiembre 2013, 11:40 »
ok alex, gracias por aclararlo

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".