Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Coloboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-06-2008
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 27
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
  #2  
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: 26
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
  #3  
Antiguo 18-06-2008
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 26
maeyanes Va por buen camino
Hola...

[broma]
Programas en la aplicación una combinación de teclas la cual al activarla permita capturar (sin un edit ni nada) el número que tienes asignado... ya que se obtuvo ese número, lo agregas a la lista de ganadores y listo...
[/broma]


Saludos...
Responder Con Cita
  #4  
Antiguo 18-06-2008
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 27
Delphius Va camino a la fama
Cita:
Empezado por BlueSteel Ver Mensaje
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
Amigo Blue, pues.... debo decirte que algo así.
Lo que ha sido estar fuera por 4 días... ha sido dificil soportar esos días sin tocar una PC. El penúltimo dia toqué la noteboock de mi prima, pero donde me encontraba la conexión inalambrica no llega. Supuestamente desde que el gobierno provincial puso internet wifi gratis para toda la provincia no hay un solo punto sin conectar.

Pero que se le va ha hacer... si quería velocidad debía irme a la ruta a la estación de servicio y el acceso al pueblo (justo donde estaba el corte) puesto que en pueblo nadie tiene esa conexión (yo me pregunto... cuantas familias son las que tendrán una PC con una salida a internet). Y el único ciber (en el pueblo) que posee máquinas con acceso a internet lo hace a través de un servicio contratado... Y de por si ese servicio es malo.

Y bueno... me tuve que guardar las ganas.

Revisa esa documentación, a modo de complemento a lo que estuviste haciendo.

Por ahora la opción del TStringGrid es la más recomendable.

Con respecto a la bromita, puedes probar con comprar el número 0 y emplear el generador de Lehmer. Ese generador tiene a cero con algunos valores de m y semillas. Una vez que se estanca en 0, continúa sacando 0 y no sale de allí. Probabilistamente hablando tienes la probabilidad de jugar por 150 de los premios.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #5  
Antiguo 18-06-2008
Avatar de Caro
*Caro* Caro is offline
Moderadora
 
Registrado: jul 2004
Ubicación: Cochabamba, Bolivia
Posts: 2.544
Poder: 24
Caro Va por buen camino
Cita:
Empezado por Delphius Ver Mensaje
..............
Por ahora la opción del TStringGrid es la más recomendable.
..............
Creo que si te ha afectado Marcelo, no hemos mencionado sobre el StringGrid, no te preocupes ya te repondrás .

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
  #6  
Antiguo 18-06-2008
[maeyanes] maeyanes is offline
Capo de los Capos
 
Registrado: may 2003
Ubicación: Campeche, México
Posts: 2.732
Poder: 26
maeyanes Va por buen camino
Eso le pasa por alejarse tanto tiempo del Club...
Responder Con Cita
  #7  
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: 26
BlueSteel Va por buen camino
Cool

Cita:
Empezado por maeyanes Ver Mensaje
Eso le pasa por alejarse tanto tiempo del Club...

si se puso así por 4 días, se imaginan a Delphius como con 1 mes o 1 año sin un PC ni siquiera un Celular....

Salu2

PS: No desvirtuen los hilos
__________________
BlueSteel
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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 09:50:56.


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