PDA

Ver la Versión Completa : Generación de Números Aleatorios


DarkDrakon
04-10-2006, 17:02:02
Buenas con todos los amigos foristas .... Bueno aqui va mi pregunta, quisiera generar o crear numeros aleatorios, pero quisiera hacerlo sin tener la necesidad de usar la funcion Random(), ni Randomize().

Bueno no se si se pueda hacer esto, bueno creo que si, pero no se como es que deberia empezar. No les pido que me digan todo, solo alguna idea de como empezar :p . Les agradezco de antemano.

Ñuño Martínez
04-10-2006, 17:17:52
Una forma de generar números pseudo-aleatorios puede ser la siguiente:

VAR
RandomSeed: LONG;

FUNCTION Random: LONG;
BEGIN
RandomSeed := (RandomSeed * 27584621) + 1;
Random := RandomSeed RSH 16;
END;


Lo he traducido de un código fuente en C, así que no sé si funciona del todo bien. Posiblemente debas usar algún que otro molde.

Por cierto, el rango de los números aleatorios es de 0 a 2^16.

seoane
06-10-2006, 19:50:55
Otro algoritmo diferente:


var
Semilla: Cardinal;

function Random2(Rango: Cardinal): Integer;
var
i: Integer;
begin
for i:= 1 to 32 do
begin
Semilla:= Semilla shl 1;
Semilla:= Semilla or $01;
Semilla:= Semilla xor ((Semilla shr 2) and $01);
Semilla:= Semilla xor ((Semilla shr 3) and $01);
Semilla:= Semilla xor ((Semilla shr 5) and $01);
Semilla:= Semilla xor ((Semilla shr 7) and $01);
Semilla:= Semilla xor ((Semilla shr 11) and $01);
Semilla:= Semilla xor ((Semilla shr 13) and $01);
Semilla:= Semilla xor ((Semilla shr 17) and $01);
Semilla:= Semilla xor ((Semilla shr 19) and $01);
Semilla:= Semilla xor ((Semilla shr 23) and $01);
Semilla:= Semilla xor ((Semilla shr 29) and $01);
Semilla:= Semilla xor ((Semilla shr 31) and $01);
end;
Result:= Semilla mod Rango;
end;


Se utiliza igual que el Random de toda la vida, y en este caso también hay que acordarse de darle un valor inicial a la semilla. Aquí un ejemplo de como usarlo, y una prueba de que tal funciona:


var
i,j,k: integer;
Str: string;
X: array[0..255] of Integer;
begin
FillChar(X, Sizeof(X), 0);
// Le damos un valor a la semilla
Semilla:= GetTickCount;
// Generamos cien mil numeros aletorios
for i:= 1 to 100000 do
inc(X[Random2(256)]);
j:= MAXINT;
k:= 0;
// Mostramos de veces que aperece cada numero
for i:= 0 to 255 do
begin
if j > X[i] then j:= X[i];
if k < X[i] then k:= X[i];
if i mod 10 = 0then
Str:= Str + #13;
Str:= Str + IntToStr(X[i]) + ',';
end;
Str:= Str + #13#13 +
'El valor mas bajo es: ' + IntToStr(j) + #13 +
'El valor mas alto es: ' + IntToStr(k);
// Si funciona bien deben mostrarse valores
// cercanos para todos los numeros.
ShowMessage(Str);
end;


Otra forma de generar números "aleatorios" es utilizar un algoritmo de encriptación, donde cada numero es el anterior encriptado. Utilizando un buen algoritmo, AES, MD5, Serpent, etc ... la secuencia sera tan difícil de descifrar, como lo sera romper el algoritmo.

DarkDrakon
09-10-2006, 23:35:44
:rolleyes: Muchas gracias a los 2 por responder :o ... ahora lo pondre en practica y despues ya vere lo que pasa :p .

Delphius
10-10-2006, 14:14:35
Quisiera aportar un poco de información al asunto.

He visto el código que muestra Seoane y me he preguntado: ¿No es demasiado procesamiento hacer operaciones de corrimiento de bits?

Yo hago empleo de geenradores multiplicativos congrenciales mixtos y multiplicativos... que son los más usados y mejores.

Haz una búsqueda en los foros.... he posteado en más de una ocasión sobre esto.. no se si te sirva.. pero con aportar un poco no se pierde nada.:D

Saludos,

seoane
10-10-2006, 14:35:47
He visto el código que muestra Seoane y me he preguntado: ¿No es demasiado procesamiento hacer operaciones de corrimiento de bits?

Yo hago empleo de geenradores multiplicativos congrenciales mixtos y multiplicativos... que son los más usados y mejores.


Lo de que sean mejores los algoritmos que tu usas no te lo discuto, al fin y al cabo el que aquí expongo, lo cree en 5 minutos y sin ningún tipo de análisis estadístico. Pero por qué afirmas que hacer desplazamiento de bits es "demasiado", ¿a que te refieres con eso?.

Me gustaría ver tus algoritmos para generar números aleatorios, seguramente con mucha mas base matemática que los mios. Y aunque tengo un poco oxidada esa materia desde que salí de la universidad nunca esta de mas aprender algo.

Delphius
10-10-2006, 15:31:57
Lo de que sean mejores los algoritmos que tu usas no te lo discuto, al fin y al cabo el que aquí expongo, lo cree en 5 minutos y sin ningún tipo de análisis estadístico. Pero por qué afirmas que hacer desplazamiento de bits es "demasiado", ¿a que te refieres con eso?.

A lo que me refiero es que tengo entendido que hacer operaciones de corrimiento de bits, (shr, shl), hacen que se requiera de más numero de operaciones.. y que estos tipos de operaciones son "lentas". Y si se están en un ciclo.... más todavía.

Me gustaría ver tus algoritmos para generar números aleatorios, seguramente con mucha mas base matemática que los mios. Y aunque tengo un poco oxidada esa materia desde que salí de la universidad nunca esta de mas aprender algo.

Tu generador es multiplicativo... va a funcionar bien, todo dependerá de que valor ingrese en Rango.... la serie que puede generar dependerá de ello.

Que tienen mayos base matemática... no creo. No hubo mucho avance en lo que hace a generación de numeros aletorios. La "técnica" es emplear no uno, sino varios en "cadena" para producir series aún más grandes. Tal es el caso del generador del ARENA, que tiene series del orden de los 10^149 si mas no me equivoco... pasarían 49 años antes de que se repita la secuencia.

Si los quieres, están por aqui.... en los foros... ahorita estoy en l trabajo... si logro enontrarme un tiempo te los paso en otra oportunidad.

Saludos,

seoane
10-10-2006, 15:56:21
:) Era eso, pues no te preocupes, las operaciones desplazamiento de bit shl y shr se corresponden a una sola instrucción de ensamblador. De echo se utilizan mucho para dividir y multiplicar por potencias de dos de forma rápida. No se como de "lentas" serán pero en ningún caso mas que una operación de multiplicación o división.

nemesio
10-10-2006, 16:33:06
Podrías tener tambien numeros aleatorios de la hora al descomponerla y tomar un milisegundo.

Saludos