• Miércoles 6 de Noviembre de 2024, 06:35

Autor Tema:  Función Random  (Leído 10368 veces)

bria

  • Nuevo Miembro
  • *
  • Mensajes: 5
    • Ver Perfil
Función Random
« en: Miércoles 14 de Enero de 2004, 21:01 »
0
Hola....

podrían ayudarme a generar floats entre 2 variables ( + - randmax)?
Ahora estoy ejecutando lo siguiente:
for (i=0; i<n_inp+1; i++) {
for (h=0; h<n_hid; h++) {
w1[h] = rnd(-randmax,randmax);
}
}

y cual ha sido mi sorpresa cuando he visto que siempre se inicializa con los mismos valores (aunque respeta los limites de + - randmax). rnd no es una función propia de Builder, aunque la acepta (no sale en la ayuda). randmax es una varibale que decide el usuario y que suele estar entre 0,0001 y 0,5.

Mirando la ayuda, habla solo de generar valores entre 0 y 1, que no me sirve, y algo más que no he llegado a entender (si, lo siento.....)

Si alguien fuera tan amable de echarme una mano....


PD: ya he probado a añadir un randomize antes de llamar a la función y el resultado ha sido el mismo.

chuidiang

  • Miembro MUY activo
  • ***
  • Mensajes: 123
  • Nacionalidad: es
    • Ver Perfil
    • http://www.chuidiang.com
Re: Función Random
« Respuesta #1 en: Jueves 15 de Enero de 2004, 09:29 »
0
Las funciones de generar numeros aleatorios suelen generarlos entre dos limites fijos. Para flotantes, suele ser entre 0.0 y 1.0 (excluido en 1.0)
Luego tu puedes convertirlo a tu rango echando una cuenta. Si lo quieres entre -randmax y +randmax, la cuenta es algo como esto

Código: Text
  1.  
  2. aux = valor * (2 * randmax);   // Esto convierte el valor aleatorio entre 0.0 y 2*randmax
  3.  
  4. aux2 = aux - randmax;  // Esto lo convierte al rango que tu quieres.
  5.  
  6.  


Las funciones aleatorias no son aleatorias realmente. Hacen unas cuentas y obtienen un valor pseudo-aleatorio. En cada ejecución del programa, las cuentas son las mismas y obtienes los mismos numeros aleatorios.

Hay una funcion srand() en la que se da un numero inicial para empezar esas cuentas. Es necesario llamar a esta funcion pasandole un entero distinto en cada ejecucion del programa. Lo habitual es pasar el tiempo actual. Solo hay que llamar a esa función una única vez. En C para solaris el código es el siguiente

Código: Text
  1.  
  2. main ()
  3. {
  4.    srand48 (time(NULL));  // se pasa a srand la fecha-hora actual
  5.    ...
  6.  
  7.    while (...)
  8.    {
  9.        double valor = drand48();  // Numeros aleatorios
  10.        ...
  11.    }
  12. }
  13.  
  14.  

No se las funciones de fecha hora en borland, pero no te costará encontrarla.

En unix hay rand() que da un entero aleatorio y se inicializa con srand()
y hay drand48() que da un double aleatorio y se inicializa con srand48(). Mira si en borland hay varias srand() y asegurate de usar la que corresponda al rand() que estés usando.

Se buena.

QliX=D!

  • Miembro MUY activo
  • ***
  • Mensajes: 214
    • Ver Perfil
Re: Función Random
« Respuesta #2 en: Jueves 15 de Enero de 2004, 15:28 »
0
Citar
Las funciones aleatorias no son aleatorias realmente. Hacen unas cuentas y obtienen un valor pseudo-aleatorio. En cada ejecución del programa, las cuentas son las mismas y obtienes los mismos numeros aleatorios.

Esto en realidad no es verdad...
Dps de muchas ejecuciones los valores se empiezan a repetir.
Estos valores aleatorios no son adecuados para cosas sobre seguridad, pero si para aleatorizar metodos o datos en juegos, etc.
El C usa un Generador congruencial linear como algoritmo.
QliX=D! - From the top of Tsunami

Ruben3d

  • Miembro HIPER activo
  • ****
  • Mensajes: 710
  • Nacionalidad: es
    • Ver Perfil
    • Web personal
Re: Función Random
« Respuesta #3 en: Jueves 15 de Enero de 2004, 18:16 »
0
Cita de: "QliX=D!"
Citar
Las funciones aleatorias no son aleatorias realmente. Hacen unas cuentas y obtienen un valor pseudo-aleatorio. En cada ejecución del programa, las cuentas son las mismas y obtienes los mismos numeros aleatorios.

Esto en realidad no es verdad...

Hola a todos.

Quería decir que chuidiang sí tiene razón (aunque es algo incompleto). Efectivamente, como bien dice QliX=D!, la función de generación de números aleatorios en C (y en muchos otros lenguajes) implementa un generador congruente lineal.

A grandes rasgos, un generador de estas características toma un número, llamado semilla, y le aplica una transformación (no la voy a explicitar aqui). Este nuevo número así generado pasa a ser la nueva semilla, sustituyendo al anterior. A continuación, este número es dividido entre cierto número (llamemoslo m) (de ninguna manera elegido al azar), con lo que se obtiene un nuevo número en el rango [0.0,1.0), que será el retorno de la función.

Es cierto que, como señaló QliX=D!, la serie de números generada comenzará a repetirse tras cierta cantidad de pasos. Si el valor de m está bien elegido (además de otros usados en la transformación) conseguiremos un generador de período completo (de tamaño m-1). Para garantizar esto, m ha de ser un primo. Ahora bien, para maximizar el tamaño del periodo, hemos de elegir un m grande, que en máquinas de 32 bits puede ser 2^31-1.

Así pues, siempre que se inicie el programa y se empiecen a generar números aleatorios se generará la misma secuencia (como dijo chuidiang) ya que la generación es llevada a cabo por la aplicación consecutiva de una serie de operaciones constantes (con constantes quiero decir que siempre son las mismas y no dependen de ningún factor externo). Sin embargo, si nos fijamos bien en el proceso que he descrito más arriba, la generación se basa en ir aplicando transformaciones a un valor llamado semilla. Dando un valor inicial diferente en cada ejecución (usando la hora, por ejemplo) a la semilla conseguiremos series de números diferentes cada vez que ejecutemos el programa.

Cita de: "QliX=D!"
Estos valores aleatorios no son adecuados para cosas sobre seguridad, pero si para aleatorizar metodos o datos en juegos, etc.

Francamente, opino que los valores así generados sí son aptos para aplicaciones seguras. No hay más que fijarse en el tamaño del periodo: m-1 = (2^32-1)-1 = 2147483646. Lo que más puede poner en compromiso la fiabilidad de un sistema basado en un generador de este tipo es la correcta elección de ciertas constantes que se utilizan (una de ellas es m). Una elección al azar o no estudiada detenidamente puede dar lugar a generadores que altenernen entre números pares o impares, que tiendan a generar más veces ciertos números o que se reduzca su periodo drásticamente, propiedades difícilmente deseables.

Bueno, espero haber dejado claro con esta explicación cómo se generan los números aleatorios en los ordenadores. Espero que le sea de ayuda a alguien.

Un saludo.

Ruben3d

QliX=D!

  • Miembro MUY activo
  • ***
  • Mensajes: 214
    • Ver Perfil
Re: Función Random
« Respuesta #4 en: Jueves 15 de Enero de 2004, 19:20 »
0
Cita de: "Ruben3d"
Cita de: "QliX=D!"
Estos valores aleatorios no son adecuados para cosas sobre seguridad, pero si para aleatorizar metodos o datos en juegos, etc.

Francamente, opino que los valores así generados sí son aptos para aplicaciones seguras. No hay más que fijarse en el tamaño del periodo: m-1 = (2^32-1)-1 = 2147483646. Lo que más puede poner en compromiso la fiabilidad de un sistema basado en un generador de este tipo es la correcta elección de ciertas constantes que se utilizan (una de ellas es m). Una elección al azar o no estudiada detenidamente puede dar lugar a generadores que altenernen entre números pares o impares, que tiendan a generar más veces ciertos números o que se reduzca su periodo drásticamente, propiedades difícilmente deseables.
 
NO! NO! Y NO!.
realmente no es apto para aplicaciones seguras por que los generadores congruenciales son muy sencilllos de "adivinar"
El periodo de 2147483646 es demasiado pequeño para cualquier tipo de implementacion segura.
En cierta manera con un generador congruencial haciendo una analisis de varios valores se peude llegar a adivinar un "rango" de numeros donde puede caer nuestro proximo numero.

Si pasean por varios sitios de la red dice explicitamente que para requerimientos de seguridad no son suficientemente bueno los generadore congruenciales, por ejemplo: Quoteado de: http://webs.ono.com/usr005/jsuarez/aleat3.htm

Citar
El generador lineal congruencial.

Ponemos como ejemplo este generador porque es uno de los más difundidos siendo a la vez uno de los más débiles y no apto para uso criptográfico. Se utiliza en la mayoría de las funciones rand() y similares.

La forma general de es: Xi+1=(a.Xi + b ) mod m donde X0 sería la semilla del generador. La salida suele ser el número Xi/m, un número en coma flotante en el intervalo [0,1).

Algunas propiedades de estos generadores:

   1. El módulo m es una cota superior del número de valores diferentes que puede tomar la semilla.
   2. Si Xi vuelve a tomar el valor de la semilla inicial la secuencia se repetirá cíclicamente.
   3. Todas las secuencias producidas por este tipo de generador si se prolongan lo suficiente (periodo) acaban en un ciclo que se repite indefinidamente.

Un buen generador lineal tendrá un periodo tan largo como sea posible (es decir m). Este máximo se alcanza si y sólo si se cumplen las tres siguientes condiciones [Knuth]

a) b es primo con m
B) a-1 es múltiplo de p para todo primo p que divida a m
c) a-1 es múltiplo de 4 siempre que m sea múltiplo de 4

Habitualmente se toma como m una potencia de 2 más de 1 de modo que se puede coger por ejemplo b=1 y a un número impar.

No sólo este tipo de generador sino todos los de tipo polinómico congruencial, es decir:

x= (anxn + ... + a1x + a0) mod m

son predecibles y por tanto inútiles para cualquier cifrado serio.

Tambien de:
http://www.dwheeler.com/secure-programs/Se...om-numbers.html

en una parte dice:
Citar
Most non-cryptographic library PRNGs are some variation of ``linear congruential generators'', where the ``next'' random value is computed as "(aX+B) mod m" (where X is the previous value). Good linear congruential generators are fast and have useful statistical properties, making them appropriate for their intended uses. The problem with such PRNGs is that future values can be easily deduced by an attacker (though they may appear random)


Bueno y no muchos mas.... pero hay mas para poner.
En si, el problema es que es ADIVINABLE el proximo numero.


HAy formas de "engañar" al atacante y hacer que no se de cuenta de que uso un congruencial lineal... pero bueno, no way... usen otro tipo... no usen este estilo de PRNG y listo :D
QliX=D! - From the top of Tsunami

Ruben3d

  • Miembro HIPER activo
  • ****
  • Mensajes: 710
  • Nacionalidad: es
    • Ver Perfil
    • Web personal
Re: Función Random
« Respuesta #5 en: Jueves 15 de Enero de 2004, 22:06 »
0
No hacía falta que me abrumaras con citas de diversos autores. Con exponerme un argumento bastaba.  :P

Respecto a la primera cita, la variación que propone es peligrosa por dos motivos: si no se es cuidadoso con la elección de m (siendo b impar) tendremos un generador que alternará entre números pares e impares. Es más, dependiendo de la elección de b podemos dar lugar a que ciertas semillas generen secuencias de números de periodo 1  :o. Un ejemplo de esto sería:
  • Xi+1 = [16807·Xi + 1] mod (2^31-1)</li>
  • [16807·1319592028 + 1] mod (2^31-1) = 1319592028</li>
Así, la calidad de un generador congruente lineal está directamente ligada a la elección de las constantes utilizadas, además de la variación elegida.

De todas formas, no te puedo quitar la razón cuando dices que los valores pueden predecirse. Es fácil ver que, sabiendo las constantes que se emplean para generar una nueva semilla a partir de la anterior, se puede averiguar qué número será el próximo en generarse a partir del ya dado, como con todo sistema basado en la aplicación de reglas.

Es más, si se toma el ejemplo de generador congruente lineal que he dado (basado en la congruencia Xi+1 = aXi mod m) y se multiplica un número generado por éste por m obtendremos la semilla utilizada, por lo que ya sólo restaría inicializar el generador con esta semilla para poder obtener la misma serie de números aleatorios.

Ahora bien, cuando menciono "sistema seguro" no me refiero exactamente a la criptografía, sino más bien al grupo más general de sistemas englobados por este término. Por ejemplo, sistemas críticos con algoritmos probabilísticos pueden, perfectamente, utilizar un buen generador congruente lineal (quiero hacer destacar el calificador buen). Para los sistemas criptográficos sería una brecha de seguridad el permitir que se pudieran predecir los números utilizados en la codificación. Es por ello que se utiliza el sistema critográfico RSA (cuya explicación creo que ya sería demasiado off-topic, teniendo en cuenta el tema original del post).

Llegado a este punto creo que puedo decir que estoy de acuerdo con QliX=D! en que un generador congruente lineal no sirve para la criptografía, aunque no debe despreciarse su uso para el resto de aplicaciones.

Un saludo.

Ruben3d

dreadlock

  • Miembro activo
  • **
  • Mensajes: 66
    • Ver Perfil
Re: Función Random
« Respuesta #6 en: Lunes 19 de Enero de 2004, 16:27 »
0
WAo todo lo que e aprendido hoy!!!,  :kicking:
UN intento de explicar lo inezplicable:D

bria

  • Nuevo Miembro
  • *
  • Mensajes: 5
    • Ver Perfil
Re: Función Random
« Respuesta #7 en: Martes 20 de Enero de 2004, 13:16 »
0
Gracias por toda la información.

Utilizaré rand entre 0 y 100 y divideré entre el numero que sea encesario.
Para positivo negativo, rand entre 0 y 1, y elevare -1 a lo que salga.

Es algo a amno pero creo quye servirá.

Saludos.

SI alguien tiene alguna función / librería para ello,  se agradecerá.