Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 16-06-2008
Avatar de BlueSteel
[BlueSteel] BlueSteel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Concepción - Chile
Posts: 2.310
Poder: 23
BlueSteel Va por buen camino
Talking Función Random ???

Hola...

tengo algunas dudas con respecto al uso de la función Ramdon. La estoy implementando para que me escoga el ganador de un concurso, en donde tiene que elegir un numero al azar de un universo de 1503.

La estoy utilizando de esta forma

Código Delphi [-]
 
sGanador.Text := IntToStr(Random(1503));

Si bien, el proceso lo realiza y me muestra valores aleatoreos que no sean mayores de 1503, el problema es el siguiente:

1.- cada vez que inicio el sistema, el primer valor que selecciona es 0, despues 47, despues 1294, despues 304... por lo cual, no me estaria sirviendo dicha función, ya que siempre que ingrese al sistema estarían eligiendo los mismos numeros y en el orden que los deje. Puede que sea un parametro que obvie, pero igual me causa extraseña

2.- necesito que la aplicación me seleccione los valores al azar, pero que no me salga favorecido un valor que ya ha sido seleccionado, es decir, si en el sorteo 1 salio de 15, que no se repita dicho numero en ninguno de los siguientes sorteos...

Bueno, el concurso consiste en regalar 300 camisetas del Club de Fútbol, 20 Televisores Plasta de 32" y un Auto 0 KM, por lo cual, y como es ante Notario, no pueden repetirse los numeros...

que me sugieren que realice...???

Salu2
__________________
BlueSteel
Responder Con Cita
  #2  
Antiguo 16-06-2008
Avatar de Black_Ocean
Black_Ocean Black_Ocean is offline
Miembro
 
Registrado: nov 2006
Posts: 128
Poder: 18
Black_Ocean Va por buen camino
Hola,

Antes de usar la función Random debes inicializarlo con el procedimiento Randomize para que no se repitan los números en forma seguida.

Ej:

Código Delphi [-]
Randomize;
Random(1503);

Por otra parte, te recomiendo que uses la función RandomRange de la librería Math en reemplazo de Random, ya que puedes definir el rango desde y hasta qué número deseas, y tambien por si no quieres considerar el 0, ya que Random considera de acuerdo a esta condición: 0 <= X < Rango

Saludos y buena suerte colega.

Última edición por Black_Ocean fecha: 16-06-2008 a las 23:26:25.
Responder Con Cita
  #3  
Antiguo 16-06-2008
Avatar de BlueSteel
[BlueSteel] BlueSteel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Concepción - Chile
Posts: 2.310
Poder: 23
BlueSteel Va por buen camino
Cool

Ok...

Muchas Gracias...

Ya me funciona tanto con el Ramdon (agregando el randomize...y con el RandomRange...

Salu2
__________________
BlueSteel
Responder Con Cita
  #4  
Antiguo 17-06-2008
Avatar de BlueSteel
[BlueSteel] BlueSteel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Concepción - Chile
Posts: 2.310
Poder: 23
BlueSteel Va por buen camino
Cool

Bueno, para no hacer otro hilo, solo me falta ver la opción de que no seleccione un numero que ya se ha seleccionado...

Alguien sabes como se puede realizar esto ???

Salu2
__________________
BlueSteel
Responder Con Cita
  #5  
Antiguo 17-06-2008
Avatar de eduarcol
[eduarcol] eduarcol is offline
Miembro Premium
 
Registrado: ago 2003
Ubicación: En los estados Zulia y Merida de Venezuela
Posts: 4.151
Poder: 25
eduarcol Va por buen camino
pues para eso deberias tener una lista, y hacer algo asi:

Código Delphi [-]
while x in Lista do
__________________
...Yo naci en esta ribera del arauca vibr@d0r
Soy hermano de la espuma,
de la garza, de la rosa y del sol...
Viva Venezuela
Responder Con Cita
  #6  
Antiguo 17-06-2008
Avatar de BlueSteel
[BlueSteel] BlueSteel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Concepción - Chile
Posts: 2.310
Poder: 23
BlueSteel Va por buen camino
Cool

Cita:
Empezado por eduarcol Ver Mensaje
pues para eso deberias tener una lista, y hacer algo asi:


Código Delphi [-]while x in Lista do

si estaba pensando algo parecido.... bueno, los favorecidos los voy metiendo en una tabla temporal.... donde tambien almaceno el numero sorteado.....

así que tendré que ir comparando si el numero esta dentro de los ya favorecidos.... lo que me da lata es que puede demorarse mucho en recorrer la tabla, ya que los registros de la tabla temporal se van insertando según posición de llegada, por lo que tendre que verificar toda la tabla cada vez que salga un numero nuevo.... y debo generar un listado de 300 ganadores....??

bueno, ahora es muy tarde....así que me voy a jugar unas mesitas de billar para relajarme.. y mañana veré como lo realizo...

Salu2
__________________
BlueSteel
Responder Con Cita
  #7  
Antiguo 17-06-2008
Avatar de Black_Ocean
Black_Ocean Black_Ocean is offline
Miembro
 
Registrado: nov 2006
Posts: 128
Poder: 18
Black_Ocean Va por buen camino
Hola,

Para almacenar datos temporales para este caso como el tuyo, lo más cómodo es trabajar con conjuntos. Delphi implementa esto de una manera muy simple, ya que es el mismo concepto que los conjuntos cuando te los enseñan en básica =).

Aquí te pongo un ejemplo de cómo trabajar con conjuntos en Delphi.

Código Delphi [-]
type
  TSelecciones = set of 1..255; // esto se refiere a que el conjunto puede contener números desde el 1 hasta el 255

var
  Seleccionados: TSelecciones;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Seleccionados := [1, 2, 3]; //inicializamos el conjunto con estos 3 numeros cualquieras que los contendrá

  if not (4 in Seleccionados) then //chequeamos si el 4 está contenido en el conjunto, como no está, devuelve falso
    ShowMessage('No está el número en el conjunto :-(');
  
  Seleccionados := Seleccionados + [4]; //Agregamos al conjunto el número 4 (ahora contendrá el 1, 2, 3 y el 4)

  if 4 in Seleccionados then // Ahora como el conjunto aparte de los 3 números iniciales contiene tambien el 4 devolverá verdadero =)
    ShowMessage('Ahora está el número en el conjunto =)');
end;

Saludos y espero que te ayude

Última edición por Black_Ocean fecha: 17-06-2008 a las 01:37:47.
Responder Con Cita
  #8  
Antiguo 17-06-2008
Avatar de Caro
*Caro* Caro is offline
Moderadora
 
Registrado: jul 2004
Ubicación: Cochabamba, Bolivia
Posts: 2.544
Poder: 22
Caro Va por buen camino
Hola BlueSteel, también podrías utilizar un StringList y su función IndexOf para buscar si algun número ya esta en la lista, mas o menos sería así el codigo.

Código Delphi [-]
 Lista : TStringList;
....
....
var
 Numero, Limite : Integer;
begin
 Randomize;
 Limite := 1300;
 Numero := Random(Limite);
 if Lista.IndexOf(IntToStr(Numero))=-1 then
  Lista.Add(IntToStr(Numero))
 else
  begin
   While (Lista.IndexOf(IntToStr(Numero))<>-1) and (Lista.Countdo
    Numero := Random(Limite);

   if Lista.IndexOf(IntToStr(Numero))=-1 then
    Lista.Add(IntToStr(Numero));
  end;

donde Lista es un StringList, ademas que debes crearlo talvez en el OnCreate de tu formulario.

Saluditos
__________________
Disfruten cada minuto de su vida a lado de sus seres queridos como si fuese el ultimo, uno nunca sabe lo que puede pasar.

Última edición por Caro fecha: 03-05-2010 a las 18:26:16.
Responder Con Cita
  #9  
Antiguo 17-06-2008
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.281
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por BlueSteel Ver Mensaje
...lo que me da lata es que puede demorarse mucho en recorrer la tabla, ya que los registros de la tabla temporal se van insertando según posición de llegada, por lo que tendre que verificar toda la tabla cada vez que salga un numero nuevo.... y debo generar un listado de 300 ganadores....??
Utiliza un TStringList en memoria ordenado. Las búsquedas son dicotómicas y casi inmediatas.
A medida que vayan saliendo buscas y añades los nuevos.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #10  
Antiguo 17-06-2008
Avatar de Caro
*Caro* Caro is offline
Moderadora
 
Registrado: jul 2004
Ubicación: Cochabamba, Bolivia
Posts: 2.544
Poder: 22
Caro Va por buen camino
Cita:
Empezado por Neftali Ver Mensaje
...un TStringList en memoria ordenado.....
Una pregunta Neftalí, esto significa que a parte de usar un TStringList y la función IndexOf, debemos también ordenarlo con Lista.Sorted := True, supongo que cada vez que se haya introducido un número a nuestra lista.

Saluditos
__________________
Disfruten cada minuto de su vida a lado de sus seres queridos como si fuese el ultimo, uno nunca sabe lo que puede pasar.
Responder Con Cita
  #11  
Antiguo 17-06-2008
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.281
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por Caro Ver Mensaje
Una pregunta Neftalí, esto significa que a parte de usar un TStringList y la función IndexOf, debemos también ordenarlo con Lista.Sorted := True, supongo que cada vez que se haya introducido un número a nuestra lista.
Al crear el stringList lo creas con la propiedad Sorted a True.

Código Delphi [-]
  TS := TStringList.Create();
  TS.Sorted := True;
  TS.Duplicates := dupError;

En tu caso yo aseguraría que no hay duplicados, ya sea con dupError o dupIgnore (mejor el primero).

A partir de ahí puedes utilizar IndexOf o Find para encontrar el elemento que necesites. No necesitas reordenar maualmente cada vez.
Al estar ordenada e insertar elementos ya te los añadirá ordenados. Es un poco más lento al insertar/borrar, pero infinitamente más rápido al buscar.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #12  
Antiguo 17-06-2008
Avatar de Caro
*Caro* Caro is offline
Moderadora
 
Registrado: jul 2004
Ubicación: Cochabamba, Bolivia
Posts: 2.544
Poder: 22
Caro Va por buen camino
Me ha quedado claro Neftali, muchas gracias por responderme.

Saluditos
__________________
Disfruten cada minuto de su vida a lado de sus seres queridos como si fuese el ultimo, uno nunca sabe lo que puede pasar.
Responder Con Cita
  #13  
Antiguo 17-06-2008
Avatar de BlueSteel
[BlueSteel] BlueSteel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Concepción - Chile
Posts: 2.310
Poder: 23
BlueSteel Va por buen camino
Cool

Hola Caro

Muchas gracias por tu respuesta...

me da error aquí ??? estará bien esto o le falta algo ???

Cita:
While (Lista.IndexOf(IntToStr(Numero))<>-1) and (Lista.Count
Lo otro es que nunca he usado un StringList, así que desde donde saco el componente (pestaña del delphi 7.. bueno si es que es un componente)... o solo se declara por código...

Salu2
__________________
BlueSteel

Última edición por BlueSteel fecha: 17-06-2008 a las 20:15:55.
Responder Con Cita
  #14  
Antiguo 17-06-2008
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
Hola...

Un TStringList no es un componente, es una clase, la cual está declarada en la unidad Classes...

Y recuerda, tienes que decir que error es el que te da, para que te podamos ayudar...

Hasta pareces nuevo...


Saludos...
Responder Con Cita
  #15  
Antiguo 17-06-2008
Avatar de BlueSteel
[BlueSteel] BlueSteel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Concepción - Chile
Posts: 2.310
Poder: 23
BlueSteel Va por buen camino
Cool

Bueno...

al final lo realice de otra forma... sin crear un StringList...

Código Delphi [-]
Procedure TForm1.Sortear;
Var
   Num_Registros : Integer;
   sFin : Boolean;
begin
    sFin := False;
    Num_Registros := ADQ_Select.RecordCount;
    Randomize;

    While sFin = False Do //Ciclo para verificar si el numero ya habia sido seleccionado
    Begin
        sGanador.AsInteger := RandomRange(1,Num_Registros);
    With Premiados Do
    Begin
         If Not Locate('Nro',sGanador.Text,[]) Then  // Aqui verifico que no este dentro de la tabla temporal.. si no esta lo agrego..
            Begin
                 ADQ_Select.Locate('Nro',sGanador.Text,[]);
                 Premiados.Append;
                 Premiados.FieldByName('Nro').AsString       := IntToStr(ADQ_Select['Nro']);
                 Premiados.FieldByName('Rut').AsString       := ADQ_Select['Rut'];
                 Premiados.FieldByName('Nombre').AsString    := Concat(ADQ_Select['Nombres'],' ',ADQ_Select['Apellidos']);
                 Premiados.FieldByName('Contrato').AsInteger := ADQ_Select['Contrato'];
                 Premiados.FieldByName('Abono').AsInteger    := ADQ_Select['Abono'];
                 Premiados.FieldByName('Ubicacion').AsString := ADQ_Select['Ubicacion'];
                 Premiados.Post;
                 sFin := True;
            End;
    End;
    End;
end;

bueno, y el codigo anterior lo llamo así

Código Delphi [-]
procedure TForm1.BitBtn4Click(Sender: TObject);
Var
   i : Integer;
begin
     For i:=1 to 300 Do
     Begin
          Sortear;
     End;
end;


Bueno, el proceso en si se demora alrededor de 2 segundos en seleccionar los 300 numeros de un universo de 1505... así que quede más que satisfecho con el código...

maeyanes
tines toda la razón.. no di el código ni mensaje de error... creo que yo mismo me enviaré a leer la guia de estilo.. y como penitencia realizaré 1000000 de.. debo entregar codigo de error

Código Delphi [-]
For i:=1 to 1000000 Do
  ShowMessage('Debo engregar el error completo, con código y mensaje de error... no volverá a pasar de nuevo');


Salu2
__________________
BlueSteel

Última edición por BlueSteel fecha: 17-06-2008 a las 21:03:11.
Responder Con Cita
  #16  
Antiguo 17-06-2008
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 24
maeyanes Va por buen camino
Hola...

Con un TStringList podría quedar más o menos así:

Código Delphi [-]
function Sortear: TStringList;
const
  NoGanadores = 300;
  NoParticipantes: 1505;

var
  I: Integer;
  Ganador: Integer;

begin
  Randomize;
  Result := TStringList.Create;
  Result.Sort := True;
  for I := 1 to NoGanadores do
  begin
    Ganador := RandomRange(1, NoParticipantes);
    if Result.Count = 0 then
      Result.Add(IntToStr(Ganador))
    else
    begin
      while Result.IndexOf(IntToStr(Ganador)) <> -1 do
        Ganador := RandomRange(1, NoParticipantes);
      Result.Add(IntToStr(Ganador))
    end
  end
end;

// Para usar la función:

var
  ListaGanadores: TStringList;

begin
  ListaGanadores := Sorteo;
  // Usas la lista
  ListaGanadores.Free
end;


Saludos...
Responder Con Cita
  #17  
Antiguo 18-06-2008
Avatar de Caro
*Caro* Caro is offline
Moderadora
 
Registrado: jul 2004
Ubicación: Cochabamba, Bolivia
Posts: 2.544
Poder: 22
Caro Va por buen camino
Hola BlueSteel, yo sigo pensando que deberías hacerlo con StringList, no es dificil manejarlo.

Un StringList es una clase que hereda de TString, llegando a ser una lista de cadenas que la tienes en memoria. como dice Neftali las búsquedas son casi inmediatas, de verdad te ayudara mucho en otras cosas que quieras hacer, incluyendo esta.

Sobre el error en la linea que marcas le faltaba un parentesis al final, se me ha ido.

Primero debes definir una variable de tipo TStringList y despues crearla como cualquier instancia de clase con:

Código Delphi [-]
 StringList : TStringList
......
 StringList := TStringList.Create;

Despues puedes utilizar todas las funciones y procedimientos de la clase TString como Add, Delete, IndexOf, Exchage..... Si te fijas en el componente ListBox, existe una propiedad Items, que es un TString, y seguro que sabes manejar dicha propidad adicionando items, borrando, etc, un TStringList lo manejas de la misma manera ya que también hereda de TString, la diferencia es que no es un componente sino solo una clase.

Ahora sobre mi ejemplo quedaría así, seleccionando los 300 ganadores.

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
 Numero, i, j, Limite : Integer;
 Lista : TStringList;
begin
 Lista := TStringList.Create;
 Lista.Sorted := True;

 Randomize;
 Limite := 1500;
 for j:=0 to 300 do
  begin
   Numero := RandomRange(0, Limite);
   if Lista.IndexOf(IntToStr(Numero))=-1 then
    Lista.Add(IntToStr(Numero))
   else
    begin
     While (Lista.IndexOf(IntToStr(Numero))<>-1) and (Lista.Countdo
      Numero := RandomRange(0, Limite);

     if Lista.IndexOf(IntToStr(Numero))=-1 then
      Lista.Add(IntToStr(Numero));
    end;
  end;

 showmessage('Se ha terminado de encontrar a los ganadores');

 for i :=0 to Lista.Count-1 do //Recorremos la lista
  showmessage(Lista[i]);
end;

Saluditos
__________________
Disfruten cada minuto de su vida a lado de sus seres queridos como si fuese el ultimo, uno nunca sabe lo que puede pasar.

Última edición por Caro fecha: 18-06-2008 a las 03:10:29.
Responder Con Cita
  #18  
Antiguo 18-06-2008
Avatar de Caro
*Caro* Caro is offline
Moderadora
 
Registrado: jul 2004
Ubicación: Cochabamba, Bolivia
Posts: 2.544
Poder: 22
Caro Va por buen camino
Hola de nuevo, el error que te marcaba no es por un parentesis al final, nose porque me corta esa linea y no se muestra completo esto es lo que puse en esa condición "While (Lista.IndexOf(IntToStr(Numero))<>-1) and (Lista.Count<Limite) do"

Saluditos
__________________
Disfruten cada minuto de su vida a lado de sus seres queridos como si fuese el ultimo, uno nunca sabe lo que puede pasar.
Responder Con Cita
  #19  
Antiguo 18-06-2008
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Yo también considero de que el uso de TStrinList es una opción recomendable. Cuenta con los métodos adecuados para resolverte el problema de buscar entre los repetidos. Ni que decir de que con emplear el TStringList te evitas tener que estar buscando contra la base de datos y luego guardando.

Por otro lado, si es demasiado preocupante el tema de los repetidos y te resulta un tanto "molesto" el emplear un TStringList, te recomendaría que emplearas algún generador de números pseudoaletorios que te grantize de que no habrá ningún repetido en una serie de m elementos (ese m es número bastante enorme por cierto).

Existen. Si que existen. Los generadores que cumplen con estas condiciones son los generadores congrenciales mixtos.

Para que exista esta característica en dichos generadores se debe cumplir estos requisitos:
1. b es primo con m
2. a-1 es múltiplo de p para todo primo p que divida a m
3. a-1 es múltiplo de 4 siempre que m sea múltiplo de 4

Para comprender mejor el tema te hago llegar este documento.
Mis apuntes de Modelos y Simulacones están el armario, perdona que no pueda explayarme demasiado.

Internamente, la función Random es un generador congruencial (o multiplicativo) mixto. Y no me extraña que sus valores a,b y m sean los adecuados según dicho axiomas.
Aunque no está demás hacer algunas comprobaciones. Y no es de extrañar que ante un período m corto como es el de 1503 existan colisiones.

Si buscas sobre el tema en los foros llegarás a hilos en donde he expuesto el tema. De hecho, ha quedado disponible aqui en los foros mis códigos que pueden ser estudiados y adaptados según tus necesidades.

Si necesitas un riguroso control sobre los repetidos puede que debas consideras que la inversión del esfuerzo sobre el de emplear un generador propio (tal vez) te es más viable que emplear un TStringList y el simple Random.

En fin, es una alternativa más que te ofrezco.

Por otro lado, me parece que es más efectivo emplear un repeat-until que un while para iterar hasta encontrar un número que no esté repetido.

El algoritmo debe venir así:

Si empleamos el StrinList
1. Desde 1 hasta CANTIDAD_DE_SORTEOS hacer:
1.1. repetir
1.1.1 Numero = Random(....)
1.1* hasta Numero no esté en lista (si empleamos el uso de un TStringList)
1.2. Añadir a lista
2. Guardar el contenido de lista en DB

Si se opta por emplear el uso de un generador que nos garantize que en el período no exista un repetido entonces lo hacemos más simple así:
1. Desde 1 hasta CANTIDAD_DE_SORTEOS hacer:
1.1. Numero = Random(....)
1.2. Guardar en DB

En fin. Cada cosa que te ofrece sus ventajas y desventajas.

Ahora pienso que, se puede emplear Random() y no random(1503) por ejemplo. Creo (no aseguro) que el uso de Random (sin indicar rango) fuerza al generador a trabajar con el valor máximo de m. Si es así, y si se cumplen estos axiomas mencionados podría bastar con obtener la parte decimal de dicho número y obtener el resto de la divsión respecto a 1503 (tal vez 1504).

Es decir que si obtenemos 0,48971 realizamos estos pasos:
1. Nro = 48971
2. Nro = Nro mod 1503 = 875

¿Porque el mod? Porque de este modo garantizamos que el máximo valor a obtenemos sea menor a 1503.

Ummm.... ¿Y no es eso volver a amplicar un generador sobre otro? Pues de hecho si... volvemos a lo mismo. Ya que de por sí, el generador realizar el mod de un número astronómicamente grande respecto a un valor m (también astronómicamente grande).

En definitiva.... es volvemos a lo mismo. Acotar un rango amplio a uno más bajo. De cualquier manera la distribución de probabilidad que siguen es, un principio, uniforme: 1/m.

Analicemos el tema numéricamente,

Si m es 1503, obtendremos = 0.000665335

Un valor bajo, al menos en un principio. Analizarlo al extremo en el contexto de los 300 Pues.... 300/1503 = 0.1996007984

¿Porqué hice ese 300/1503? Pues para demostrar la probabilidad de que un número se repita 300 veces dentro de los 1503.

Si nos basamos en que el rango de 1503 es corto... yo diría que las probabilidades no son alentadoras. Trabajar con dicho rango es posiblemente, inviable.

Apliqué este algoritmo:

Código Delphi [-]
resourcestring
  msgSorteado = 'Nro ganador: %d, sorteo nº: %d';

procedure TForm1.RealizarSorteo(Sorteos: TStrings);
const
  CANTIDAD_SORTEOS = 300;
var
    i, Nro: integer;
begin
  Sorteos.Clear;

  for i := 1 to CANTIDAD_SORTEOS do
    begin
      Nro := Random(1503) + 1;
      Sorteos.Add(Format(msgSorteado,[Nro,i]))
    end;
end;


En un TListBox con la propiedad Sorted en true.

He hecho una prueba con D6 y obtenido repetidos, en distintas iteraciones. De hecho varios números se repiten dos veces.

La prueba no tiene sentido si uno aplica un Randomize obviamente.

La misma prueba, aplicando este algoritmo:

Código Delphi [-]
procedure TForm1.RealizarSorteo(Sorteos: TStrings);
const
  CANTIDAD_SORTEOS = 300;
var
    i, Nro: integer;
begin
  Sorteos.Clear;
  for i := 1 to CANTIDAD_SORTEOS do
    begin
      Nro := Trunc(Random * 100000000000) mod 1503;
      Sorteos.Add(Format(msgSorteado,[Nro,i]))
    end;
end;

Si bien no obtengo toda la parte decimal convertida en entero, para un experimento puede servir.

Y vuelvo a obtener repetidos...
¿Que pasa aquí?
Pues simplemente que estamos acotando el rango grande a uno pequeño.

Realizando la prueba con un Random solo, y un format a 0.8f. No he conseguido ningún repetido.

He aquí la eterna pregunta ¿Nos conformamos con el uso de una "lista" para buscar repetidos e iteramos mientras haya repetidos o nos esforzamos a buscar aquellas propiedades a,b que garantizen junto a m que en la serie no nos vamos a topar con repetidos y empleamos nuestro propio generador?

Puedes probar bibliotecas científicas para ver si alguna ofrece una mejor alternativa.

Y antes yo sacaba valores respecto a 1503.... en realidad amigo, deberíamos hacerlo en 300. Que son en realidad esos 300 números que saldrán. De hecho, si sabemos que en realidad sorteamos 300 numéros, tenemos 1/300 de salir ¿No es cierto? 1/300 no da un valor de 0,003333..

Aun así, necesitamos generar números en el rango buscado y por tanto nuestro "m" son y serán esos 1503. Si tomamos todos, o sólo los primeros 300 ya es otra cosa.

Yo me pregunto, si al acotar el rango a 1503 obtenemos muchos repetidos... que podría esperararse si lo hacemos en 300. (No es necesario responderla, no viene al caso... es sólo una reflexión mia).

Yo hice esos cálculos para mentalizar el porque y cuando el uso de un Random es útil.

Se que no aporto mucho, pero al menos creo que con esto doy un panorama del uso de random.

Recuerden que las implementaciones de Random pueden variar de una versión a otra del compilador.

Saludos
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #20  
Antiguo 18-06-2008
Avatar de BlueSteel
[BlueSteel] BlueSteel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Concepción - Chile
Posts: 2.310
Poder: 23
BlueSteel Va por buen camino
Wink

Changos [Delphius]... que te fumastes ???

Parece que estos 4 días que no estubistes conectado te tenian atragantado...

Bueno, revisaré la documentación que dejas.

[Caro], también revisaré lo que me dejastes, no tube tiempo por que salí a realizar compras de partes y piezas, así que creo que en la tarde lo implementaré con TStringList para ver como funciona eso...

Bueno, gracias a todos...

[broma]Una última consulta, como puedo forzar a que el Random saque mis 2 numeros para ganarme ya sea una camiseta, un plasma o el auto [/broma]

Salu2
__________________
BlueSteel
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Uso de Random arespremium OOP 5 12-08-2007 21:48:39
Random() altp .NET 3 27-11-2006 11:59:45
random chechu Varios 6 24-11-2005 20:09:45
random edulp Varios 1 24-10-2005 02:17:39
Random!! Alejandro Horns Varios 1 13-12-2004 16:37:39


La franja horaria es GMT +2. Ahora son las 18:44:43.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi