PDA

Ver la versión completa : Ayuda con un Programa en Java



eduk15
28-01-2008, 01:54
Muy buenas noches señores, en esta oportunidad deseo su ayuda en un programa que realize en Java. Se trata de un pequeño programa que arroja numeros aleatorios en cierto intervalo (sea este intervalo [a;b]), los almacena en un vector, y debe arrojar como respuesta numeros aleatorios diferentes, es decir, no se deben de repetir ninguno de ellos. Para esto use el compilador JCreator Pro 4.00 y el jdk 1.5.0
El problema esque el programa arroja los numeros aleatorios pero se repiten, revise en reiteradas ocasiones mi logica, no se en donde puede estar el error, espero que me puedan ayudar a solucionarlo.
Aqui les dejo el codigo:
/**
* @(#)Aleatorios.java
*
*
* @author
* @version 1.00 2008/1/27
*/


public class Aleatorios {
private int n;
int v[]=new int[100];
public Aleatorios(int _n)
{n=_n;
for(int x=0;x<n;x++)
{v[x]=0;}
}

void Producir_Numeros(int n,int a, int b)
{
int i=0;
int p;
while (i<n)
{
p=(int)(Math.random()*b);
if(p>=a)
{
int k=0;
while((p!=v[k])&&(k<n))
{
v[i]=p;
k++;
}
i++;
}
}
System.out.println("\nNumeros aleatorios generados con exito!");
System.out.println("\nLos numeros generados son: ");
for (int j=0;j<n;j++)
{System.out.println(v[j]);}
}
}

/**
* @(#)Principal.java
*
*
* @author
* @version 1.00 2008/1/27
*/


public class Principal {

public static void main(String[] argv)
{
int num,a1,b1;
System.out.println("\nCuantos elementos aleatorios desea? ");
num=CTeclado.readInt();
System.out.println("\nIngrese parametros del intervalo de donde seran sacados los numeros.");
System.out.println("\nCota Superior: ");
a1=CTeclado.readInt();
System.out.println("\nCota Inferior: ");
b1=CTeclado.readInt();
Aleatorios al=new Aleatorios(num);
al.Producir_Numeros(num,a1,b1);
}
}

Nota: CTeclado es una clase con metodos para leer diferentes tipos de variables, solo tengo el .class mas no el codigo. num, a1 y b1 son variables del tipo entero, asique CTeclado.readInt() puede ser reemplazado por alguna sentencia para leer enteros, en mi caso, yo desconozco dicha sentencia.

Agradezco de antemano su ayuda.

hystd
28-01-2008, 13:30
Buenas! El problema es por cómo usas el método estático Math.random().

Este método devuelve un valor comprendido entre 0 y 1. Tu lo multiplicas por un valor "b", y luego haces el casting a un entero. Pues aquí está el problema... al hacer el casting a (int) te quedas con la parte entera del valor generado por random(), que es un double...

Por ejemplo:

Primera llamada a random() -> devuelve 0.8719149460279755
Segunda llamada a random() -> devuelve 0.8689836094846761

Si los multiplicas por un valor constante (para realizarle un offset o desplazamiento), por ejemplo "7", los resultados obtenidos son los siguientes:

0.8719149460279755 * 7 = 6,1034046221958285
0.8689836094846761 * 7 = 6,0828852663927327

Ahora le haces el casting a un entero (int), y ya viene el problema... truncas completamente los valores, quedándode con las partes enteras... en este caso devuelves "6".

Espero que hayas entendido el problema.

Como solución simple, se me ocurre que puedes multiplicar por 10^n, para desplazar la coma del valor devuelto por random(), que es un double, y luego haciendo por ejemplo una operación "mod" con la cota superior, pues obtendrás mejores resultados... aunque no aseguras la pseudoaleatoriedad óptima, pero si la mejora...

Por ejemplo en el caso anterior:

0.8719149460279755 * 7 = 6,1034046221958285
0.8689836094846761 * 7 = 6,0828852663927327

Ahora multiplicamos por ejemplo por 100000:

6,1034046221958285 * 100000 = 610340
6,0828852663927327 * 100000 = 608288

Hacemos la operación "resto" (operador mod), con el valor establecido por "cota superior"
Si por ejemplo nuestra cota superior es 20, entonces:

610340 mod 20 = 0
608288 mod 20 = 8

Como ves, el procedimiento que te propongo, aunque no es lo mejor, pero es muy fácil de implementar, ha solucionado el problema para dos números que con tu método se repetían. (Una secuencia 6, 6, ....., la ha convertido a una 0, 8, .....)

Espero haberte ayudado, o por lo menos que hayas entendido cuál es el problema de tu solución.

Un saludo

eduk15
30-01-2008, 17:28
Muchisimas gracias por tu respuesta, me ha servido de gran ayuda. Si entendi lo que me explicaste, en realidad no sabia como trabajaba el casting para ese caso, ahora voy a mejorar mi codigo. Muchas gracias.