FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
||||
|
||||
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
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 |
#2
|
||||
|
||||
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:
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. |
#3
|
||||
|
||||
Ok...
Muchas Gracias... Ya me funciona tanto con el Ramdon (agregando el randomize...y con el RandomRange... Salu2
__________________
BlueSteel |
#4
|
||||
|
||||
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 |
#5
|
||||
|
||||
__________________
...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 |
#6
|
||||
|
||||
Cita:
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 |
#7
|
||||
|
||||
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.
Saludos y espero que te ayude Última edición por Black_Ocean fecha: 17-06-2008 a las 01:37:47. |
#8
|
||||
|
||||
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.
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. |
#9
|
||||
|
||||
Cita:
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. |
#10
|
||||
|
||||
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. |
#11
|
||||
|
||||
Cita:
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. |
#12
|
||||
|
||||
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. |
#13
|
||||
|
||||
Hola Caro
Muchas gracias por tu respuesta... me da error aquí ??? estará bien esto o le falta algo ??? Cita:
Salu2
__________________
BlueSteel Última edición por BlueSteel fecha: 17-06-2008 a las 20:15:55. |
#14
|
|||
|
|||
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... |
#15
|
||||
|
||||
Bueno...
al final lo realice de otra forma... sin crear un StringList...
bueno, y el codigo anterior lo llamo así
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
Salu2
__________________
BlueSteel Última edición por BlueSteel fecha: 17-06-2008 a las 21:03:11. |
#16
|
|||
|
|||
Hola...
Con un TStringList podría quedar más o menos así:
Saludos... |
#17
|
||||
|
||||
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:
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.
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. |
#18
|
||||
|
||||
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. |
#19
|
||||
|
||||
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:
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:
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 |
#20
|
||||
|
||||
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 |
|
|
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 |
|