Bennu Game Development

Foros en Español => Extensiones => Topic started by: DCelso on October 05, 2010, 11:30:06 AM

Title: mod_rands
Post by: DCelso on October 05, 2010, 11:30:06 AM
Hola a todos, os adjunto el código fuente de un módulo que genera números aleatorios usando el método Mersenne twister  MT19937 de Makoto Matsumoto.
Title: Re: mod_rands
Post by: DCelso on October 05, 2010, 12:04:49 PM
le he añadido el alleged RC4
Title: Re: mod_rands
Post by: panreyes on October 05, 2010, 12:06:27 PM
Si no es demasiado complicado, se podría integrar en Bennu y que a través de una opción se pudiera elegir entre utilizar un sistema u otro, no?
Title: Re: mod_rands
Post by: Danielo515 on October 05, 2010, 02:15:41 PM
Ya se que podría buscar, pero prefiero preguntar.

¿Cuales son las (seguramente grandes) ventajas de este método de generación de aleatorios?
Title: Re: mod_rands
Post by: Drumpi on October 05, 2010, 04:13:31 PM
Quote from: PiXeL on October 05, 2010, 12:06:27 PM
Si no es demasiado complicado, se podría integrar en Bennu y que a través de una opción se pudiera elegir entre utilizar un sistema u otro, no?

Para eso están los includes, para elegir qué librería usar en cada proyecto.

Lo cierto es que una pequeña documentación de las funciones disponibles, su uso y sus características básicas irían muy bien, es que no hay ni leeme ;)
Title: Re: mod_rands
Post by: DCelso on October 05, 2010, 04:28:06 PM
:D. para eso está el test.prg.
Todas las funciones tienen un prefijo indicando el algoritmo empleado.

Pero vamos es como cualquier rand de cualquier lenguaje de programacion :D.

* Las funciones que terminan en "_seed" son para establecer la semilla de origen del algoritmo rand, y puede haber de dos tipos una sin parámetros de entrada, que usa la hora de sistema para establecer la semilla y otra con un parámetro de entrada que usa ese parámetro de entrada para establecer la semilla.

* Las funciones que tienen la palabra "rand" son para obtener un número aleatorio usando el algoritmo. Puenden  tener un parámetro de entrada que sirve para indicar hasta qué numero quieres que te de la secuencia y van desde 0 hasta ese número, y luego pueden no tener parámetro y estas irán desde 0 hasta 1 (son para números reales aleatorios)
Title: Re: mod_rands
Post by: Drumpi on October 05, 2010, 04:48:08 PM
¿Te refieres a ESTE prg?

[code language="bennu"]import "mod_say";
import "mod_rands";
Process Main()
local
   float val;
Begin
  MT19937_SEED();
  Say (MT19937_RAND(100));
  Say (MT19937_RAND(100));
  Say (MT19937_RAND(100));

  say ("Alleged RC4");
  ALRC4_SEED();
  Say (ALRC4_RAND(100));
  Say (ALRC4_RAND(100));
  Say (ALRC4_RAND(100));
 
  Say (ALRC4_RANDF(100));
  Say (ALRC4_RANDF(100));
  Say (ALRC4_RANDF(100));
End[/code]

Sí, desde luego es muy explicativo :D
Eso mismo que has escrito debería ir en un TXT, o expresado de distinta forma pero con la misma información :)
Title: Re: mod_rands
Post by: Windgate on October 05, 2010, 07:50:43 PM
¿Y algún algoritmo para obtener números aleatorios dentro de un intervalo siguiendo una distribución Normal o Poisson?

Para que me entendáis: La altura del ser humano no es una distribución uniforme, tendemos a 1.75m casi todos, y puntualmente algunos se alejan de la normal y miden 1.50m o 2.00m.

DCelso te doy el karma que ayer olvidé darte, estaba seguro de que nos ibas a venir con esto xDDD
Title: Re: mod_rands
Post by: gukan on October 07, 2010, 05:20:33 PM
Quote from: Windgate on October 05, 2010, 07:50:43 PM
¿Y algún algoritmo para obtener números aleatorios dentro de un intervalo siguiendo una distribución Normal o Poisson?

Para que me entendáis: La altura del ser humano no es una distribución uniforme, tendemos a 1.75m casi todos, y puntualmente algunos se alejan de la normal y miden 1.50m o 2.00m.

DCelso te doy el karma que ayer olvidé darte, estaba seguro de que nos ibas a venir con esto xDDD
Me imagino que esto no va aqui ya que poco tiene que ver con las extensiones, pero como Wind lo ha preguntado aqui, respondo por aqui.

Teniendo el random para la uniforme 0,1 tienes cualquier distribucion.
Para la Poisson se ve que es tan sencillo como esto:
// Returns a number (of points in a unit length) which
// has a Poission distribution with intensity c.
public int poisson(double c) {
   int x = 0;
   double t = 0.0;
   for (;;) {
      t = t - Math.log(Math.random())/c;
      if (t > 1.0)
          break;
      x = x + 1;
   }
   return x;
}


Para la normal el metodo de Box–Muller parece lo mas sencillo de todo.
(http://upload.wikimedia.org/math/d/4/5/d45b69cbca8f444a9a3621b90bbebf31.png)
donde U y V son distribuciones uniformes (0,1)
La X y la Y son dos distribuciones normales independientes de media 0 y desviación 1. Despues solo tienes que transformalas a la media y desviación que quieras y ya lo tienes. (x*desviacion)+media y ya vas que andas!
Title: Re: mod_rands
Post by: Windgate on October 07, 2010, 08:11:28 PM
Sí, me imaginaba una solución así, pero la idea es no tener que operar cada vez sino tenerla a modo de dll y pasar como parámetros la media y la desviación despreocupándote de tener o no conocimientos de estadística :D

No obstante te doy un karma por si algún día es útil que nunca se sabe :P
Title: Re: mod_rands
Post by: gukan on October 07, 2010, 09:16:16 PM
Yo no tengo ni idea de hacer dlls, pero vamos para la poisson el codigo ya esta hecho (java, pero totalmente implementable en cualquier otro lenguaje), y el de la Normal tiene de ser muy sencillote de hacer (diria más, por casualidades de la vida yo estudie estadistica y me parece que en alguna practica que tuve, implemente ese mismo metodo que he puesto, eso si, en pascal seguramente).
Asi que a ver si alguno de los dll-guru del foro se anima y te empaqueta una bonita dll ;D
Title: Re: mod_rands
Post by: DCelso on October 07, 2010, 10:44:10 PM
Bueno, he encontrado una página en la que hay librerías C++  para generar numeros aleatorios uniformes y otra para numeros aleatorios no uniformes para las siguientes distribuciones: normal, truncated normal, bernoulli, poisson, binomial, hypergeometric, Wallenius' and Fisher's noncentral hypergeometric, multinomial, multivariate hypergeometric, and multivariate Fisher's and Wallenius' noncentral hypergeometric distributions

http://www.agner.org/random/

A ver si me armo de valor y rearmo este módulo con estas dos libs :D.
Title: Re: mod_rands
Post by: DCelso on October 07, 2010, 11:04:10 PM
ostras, esto es lo que hace el rand de c

void srand(unsigned int seed)
{
  holdrand = (long) seed;
}

int rand()
{
  return (((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
}

con menos líneas y más rápido, imposible. :D
En fin el algoritmo  sería algo como  el nuevo valor es igual al antiguo valor  multiplicado por un numeraco al que luego le sumo otro numeraco para luego dividirlo 16 veces entre dos y finalmente quedarme con los últimos 15 bits.
:D
Title: Re: mod_rands
Post by: Windgate on October 08, 2010, 12:39:50 AM
No se comieron mucho el coco no...
Title: Re: mod_rands
Post by: gukan on October 08, 2010, 06:53:56 AM
Pues aunque os parezca mentira es el metodo mas comun para generar los rand:
http://en.wikipedia.org/wiki/Linear_congruential_generator
Title: Re: mod_rands
Post by: DCelso on October 08, 2010, 03:53:56 PM
Bueno, pues la he programado en bennu y parece que va bien y todo :D.

import "mod_say"
import "mod_time"
global
seed;
end
function srand(value)
begin
seed = value;
end

function rand()
begin
seed = seed * 214013 + 2531011;
return ( (seed >> 16) & 07fffh);
end

function rand_between(vstart, vend)
begin
return (rand() % (vend-vstart+1) +vstart);
end


process main()
private
i;
valor;
float media;
numeros = 1000;
begin

srand(time());
for (i=0;i<numeros;i++)
valor = rand();
say(valor);
media= media +valor;
end
media = media /numeros;
say("media:"+media);

media = 0;
for (i=0;i<1000;i++)
valor = rand_between(10,20);
say(valor);
media= media +valor;
end
media = media /numeros;
say("media:"+media);

end
Title: Re: mod_rands
Post by: Drumpi on October 08, 2010, 07:42:01 PM
Yo he visto un generador de números aleatorios en hardware, que si está bien hecho es cíclico y se dan todos los números, a base de desplazamientos y puertas XOR, así que... ;D