Algoritmos para eliminar columnas por diferencias

Algoritmos, fórmulas, estadísticas...
Avatar de Usuario
Doctorpi
12
12
Mensajes: 2660
Registrado: Mié 15 Oct, 2003 6:14 pm
Contactar:

Respuestas

Mensaje por Doctorpi »

1.Para saber que byte es el que corresponde a la quiniela 1.384.538 solo hemos de dividir el numero por 8.
Asi el byte 173.067 es el que contiene nuestro bit.
Para saber que bit es, hay que obtener el modulo (o resto) de 1.384.538 entre 8, o sea el bit 2.
2.Si queremos alterar un bit sin cambiar los otros 7, depende de lo que queramos hacer.
Si queremos ponerlo a 0, hay que hacer un AND logico poniendo a 1 todos los bits menos el nuestro.
Ejemplo:
Nota. los bits se leen de der. a izq. y se numeran de 0 a 7
76543210
10111101 (supongamos que este es nuestro byte)
11111011 (mascara de bits para poner a 0 el bit 2)
----------- AND
10111001 Resultado
Un AND logico solo da 1 de resultado si los dos bits son 1.Si leeis un poco sobre como funciona el AND logico lo entendereis
p q AND
-------------
0 0 0
0 1 0
1 0 0
1 1 1

Si queremos ponerlo a 1 la operacion es el OR
76543210
00101010 (supongamos que este es nuestro byte)
00000100 (mascara de bits para poner a 0 el bit 2)
----------- OR
00101110
Un OR logico da 1 si alguno de los 2 bits es 1. Por lo tanto si nuestra mascara tiene todo 0's menos el bit que queremos poner a 1, solo nuestro bit cambiara de valor.

p q OR
-------------
0 0 0
0 1 1
1 0 1
1 1 1

3.Para saber si un bit esta a 0 o a 1. Deberemos hacer un AND de nuestro bit con una mascara a 1 de ese bit precisamente. Si da 0 era 0 si da diferente de 0 era 1.
01001001
00000100
----------- AND
00000000 Nuestro bit era 0

01001101
00000100
----------- AND
00000100 Nuestro bit era 1

Un saludo
Dr.Pi
Avatar de Usuario
JoanD
12
12
Mensajes: 2657
Registrado: Vie 19 Dic, 2003 6:35 pm
Ubicación: Barcelona
Contactar:

Mensaje por JoanD »

No hay nada mejor que formular unas cuantas preguntas y que alguien te las responda con tanta claridad y detalle como lo ha hecho el Dr. Pi. Moltes gràcies, ets un mestre !!!.

Lo he estado probando con VB.

'Por ejemplo declaro una variable de tipo byte:
Dim b As Byte

'le asigno el valor 129. En binario es 10000001
b = 129

'Ahora le quiero poner a 1 el byte nº 4 empezando por la derecha
' el 8 es el valor que lo representa ya que en binario es: 00001000

b = b Or 8

'la variable b toma el valor 137 que en binario es: 10001001
'ahora le pongo el cuarto bit a 0 haciendo un and con 11110111
' cuyo valor decimal es 255-8 = 247

b = b And 247

y efectivamente b vale ahora otra vez 129

Lección aprendida
[Nomada]

Mensaje por [Nomada] »

Jope lo que uno aprende de esto estaba hacindo los deberes sobre este tema y me encuentro, un poco desfasado en el tema.

Al final hemos llegado a poner 8 columnas en 1 bit, esto va a una velocidad, que ni los diseñadores de hardware se atreverian a pensar.

En fin sigo con mis deberes, un poco atascado en la conversion de decimal a bynario y viceversa. Solo veo unos y ceros, ¿ Es normal ?.

Me queda una cuestion, si el Dr.Pi pone los 14 triples, segun he podio leer, en meno de 548, la unica cosa que se me ocurre en un producto de 8*2=16, a lo mejor es una tonteria mas de las mias, pero eso me suena a hexadecimal.

Cuanta memoria ocuparia en total de un array con tres subindices (se dice asi ) en los que pondriamos 5triples en el primero o 4, lo mismo en el segundo, 3 o 4 en el ultimo. Siguendo la explicacion de pinfly al aplicar el divide y venceras. Eso siempre por un producto de 2.

Un saludo
Avatar de Usuario
JoanD
12
12
Mensajes: 2657
Registrado: Vie 19 Dic, 2003 6:35 pm
Ubicación: Barcelona
Contactar:

Mensaje por JoanD »

El siguiente ejemplo ilustrar el uso de un bit por columna. El ejemplo carga un fichero de apuestas poniendo a 1 el bit que le corresponde.

ReDim Flags(597871) As Byte
Rem 597871 * 8 = 4.782.968 = 3^14-1

Open Me.TxFileNameApuestas For Input As #1
While Not EOF(1)
      Input #1, Apuesta
      i = ConvBase3aBase10(Apuesta)
      If (Flags(i \ 8) And Pot(i Mod 8)) = 0 Then
                Bait = Indice \ 8
                Flags(Bait) = Flags(Bait) Or Pot(Indice Mod 8)
      End If
Wend
Close


Meter los 14 triples descompuestos en 3 bytes nos ocuparia 4782969*3 = 14.348.907 de bytes. Creo que la finalidad de descomponer las columnas en 3 bytes no es la de poder meter los 14 triples en memoria sino la de poder tener una tabla de 5 triples y otra de 4 con los valores referentes a la diferencia de signos precalculados en matrices de 243 * 243 y de 81 * 81.

Lo que no entiendo Nomada, es por que razón quieres multiplicar por 2, ¿acaso quieres tener 2 bits por apuesta para tener 2 datos sobre la misma?
Última edición por JoanD el Sab 19 Nov, 2005 1:18 pm, editado 1 vez en total.
[Nomada]

Mensaje por [Nomada] »

Joand yo aun estoy en los principios.

No es por nada en particular, solo que me llamo la curiosidad que tambien exite la notacion hexadecimal y la pregunta es por si esto se podia utilizar o es una tonteria mas de las mias.

Lo que tu haces es correcto me parece ya que pregunte por algo asi a conocidos y me digeron que era buena.

Al ritmo que vas en tus deberes, nos vas a sacar mucha ventaja, eso no vale.

Estoy un poco atascado en lo e averiguar la diferencia de las columnas ya que a mi me interesa mucho y mas cuando se como obtener la diferencia que puede tener la columna ganadara con el resto ( esto es una primicia adelantada), es la condicIon o filtro que utilizo para rebajar las columnas y conservar el 14 cada semana. Esta la aplico en mi sistema de 16.384 columnas y en el de transformacion a signos, con los resultados que tu ves. Salvo la semana que me lo puli por tener un bug en el programa.

Si supiera como averiguar o posellera el algoritmo para obtenerlo en menos tiempo, otro gallo cantaria, por que me permitiria hacer mas pruebas, actualmente tarda 7 horas todo el porceso, si lo consigo hacer y rebajo a 1 hora podria hacer mas pruebas y poder centrarme en otros filtros, que tengo en estudio y estos pueden ser mas novedosos y aportar algo mas al rebaje de columnas que posiblemente no saldran, los he porbado y funcionan, por ejemplo de las que recibo las puedo dejar al 50% con casi la totalidad de premios que tienen en origen. Lastima que aun este en ese punto.

Seguiremos con el averiguar la diferencia.

Un saludo
Avatar de Usuario
JoanD
12
12
Mensajes: 2657
Registrado: Vie 19 Dic, 2003 6:35 pm
Ubicación: Barcelona
Contactar:

Mensaje por JoanD »

Nómada, creo que puedo ayudarte a rebajar el tiempo de comparación pero deberias concretar el problema. ¿Se trata de comparar una columna con muchas ? o de ¿muchas con muchas (como el MQSelector)?. Si el numero de columnas a comparar es superior a 16016 usaria un método y si es inferior usaria otro. Si puedes o quieres explicarme en que consiste la condicon seguro que entre los dos rebajamos el tiempo. Mi desafio es dejarlo en menos de 1 hora. Y eso que no se todavia de que va. ¡¡¡ Animo !!!!
[Nomada]

Mensaje por [Nomada] »

Hola JuanD

El problema

Muchas (cerca del 1.5) contra una y una contra 10.000,. cada vez,

Pasos:
1-Conversion a sistema, por igualdad y no igual. dos variables

2-Comparacion de iguales. Comparacion por desigual. las dos anteriores.
Para obtener la diferencia de cada comparcion.

3.-Busqueda de valor de las diferencias en un rango de valores, no todas las veces son seguidos, en total 25.

4- Comparacion. Esto seis veces, obteniendo unos valores.

5- Comparacion de los valores obtenidos en el paso 4, para aceptar o rechazar.

La forma de obtener el rango de posibles valores, es otra cosa, creo que es lo que son las diferencias y nadie dice que rango de valores utilizar cada jornada ya que varian. He adelantado mucho ya que los rangos los obtengo previamente.

El problema es el tiempo que tarda mucho, a lo mejor estoy haciendo algo mal y es que me gusta ver lo que hace la maquina, lo que si hago y aqui me vas a decir quita el doevents, ese es mi posble fallo.

Tambien te comento que los pasos del uno al cinco los hago con signos (1X2).

Las comparaciones las realizo cada vez recorriendo los 14 signos.

Una cosa a tener en cuenta es que no puedo dividir los procesos. Uno para sistema y el otro para signos.

He conseguido aligerar memoria guardando indices(ose que columna admito= guardo en una matriz aparte de las que rechazo. Teniendo dos matrices que multiplicadas por dos son 4, donde solo guardo el numero de la columna en cada una de las matrices.

Un saludo
Luis
P.D. Esto es de forma escueta. Si esto es muy ecueto te lo amplio con mas detalle.
Avatar de Usuario
JoanD
12
12
Mensajes: 2657
Registrado: Vie 19 Dic, 2003 6:35 pm
Ubicación: Barcelona
Contactar:

Mensaje por JoanD »

Cuesta un poco entender el proceso pero no tienes porque desvelar tu sistema si no quieres.

Si programas en Visual Basic aparte de quitar el DoEvents te puedo hacer unas recomendaciones que haran que tu programa sea un poco mas rápido:

- No usar variables de tipo variant. Te recomiendo que uses la option explicit para que te obligue a declarar las variables. Procura no declarar ninguna de tipo variant. Usa al máximo los de tipo Integer o byte. Si no usas la Option expicit cuando usas una variable no declarada, Visual Basic lo asume a Variant y el programa es mas lento. Cuidado porque cuando haces DIM x, y, z as integer , la única variable declarada como integer es la z. las demas son de tipo Variant.

- Usa MID$, LEFT$ y RIGHT$ en lugar de MID, LEFT y RIGHT puesto que en estos últimos se utiliza el tipo variant.

- Para saber si una cadena es nula no uses If Cadena$="" then ..., sino que es mas rápido hacer If Len(Cadena$)=0 then ...

- Usa variables globales en lugar de las estáticas siempre que te sea posible.

- El uso de colecciones es preferible al uso de matrices cuando hay mas de 200 elementos y te interesa acceder de forma no secuencial (aunque yo no uso colecciones)

- Los parametros de las funciones o subrutinas que no se modifiquen dentro de ellas en mejor declararlas como Byval

- No uses las propiedades de los controles (text, caption, value, etc) como variables. Asigna estas propiedades a variables que no sean de tipo variant.

- Y por último evita hacer la comparación de cadenas caracter a caracter. En este foro se han explicado algunas ideas. La mejor es: tener precalculadas todas las diferencias posibles de 5 partidos. Este punto lo podemos desarrollar mas si quieres.
[Nomada]

Mensaje por [Nomada] »

Hola Juand.
Gracias en algo mas que se me esca lo de variant, me parece que a porrillo y de caption. pocos eso lo aprendi a base de pegarme tortas.

Voy a seguir los consejos que me has dado y a ver donde narices he metido la pata, en serio, soy un novatillo, en programacion.

Vrdaderamente no se programar.

Mi sistema no hay problema ya que estubo publicado y al alcance de todos. Con ficheros, forma de crearlo, resultados, etc, menos la automatización.

En cuanto a las diferencias seguire con mi pregunta en el foro de condicones.

Juan espero no haberte molestado.

Un saludo
Luis

P.D. Me recomendarias usar el CopyMemory y handle, es bueno o es algo mas enredoso. Dicen que se gana un monton.
Avatar de Usuario
JoanD
12
12
Mensajes: 2657
Registrado: Vie 19 Dic, 2003 6:35 pm
Ubicación: Barcelona
Contactar:

Mensaje por JoanD »

Hola Nómada,

No me has molestado en absoluto. No hay ningún motivo para ello.

Dime dónde está publicado el método. Si logro comprenderlo seguro que te podré ayudar mejor.

Lo del CopyMemory me parece que es una función del API de WINDOWS pero no sé dónde la podriamos usar.
[Nomada]

Mensaje por [Nomada] »

Gracias Juand

Siguiendo tus ocnsejos se ha acelerado mucho, 3 horas menos lastima que no sepa mucho de bytes o de byts.

El copymemori tengo que probarlo, accedes directamente a la posicion de memoria, pero ya estamos a utilizar punteros, una tabarra de aupa.

Te debo una.
Ya quedaremos para tomar algo.

Un saludo.
Avatar de Usuario
JoanD
12
12
Mensajes: 2657
Registrado: Vie 19 Dic, 2003 6:35 pm
Ubicación: Barcelona
Contactar:

Mensaje por JoanD »

Eso de los punteros me recuerda a la programación en C.
Si algo bueno tiene el VB es que no hay que pensar en punteros lo que le hace rápido de programar.
Si algo bueno tiene el C es que se consiguen procesos mas veloces seguramente por estar mas cerca de lo que entiende la máquina (direcciones de memoria, punteros, bits, etc...) pero costoso, en tiempo de programación, al menos para mí.
[Nomada]

Mensaje por [Nomada] »

Si Juand
Es lo mismo solo que en visual basic.

Si no fuera por la falta de tiempo, Creo que el proyecto lo terminaria.


Un saludo.
Avatar de Usuario
JoanD
12
12
Mensajes: 2657
Registrado: Vie 19 Dic, 2003 6:35 pm
Ubicación: Barcelona
Contactar:

Mensaje por JoanD »

Visual Basic es muy lento cuando trata con cadenas. Todavia puedes rebajar mas el tiempo de cálculo si substituyes las columnas alfanumericas por el valor numérico de tipo Long que las representa. Para hacer la conversión puedes consultar otros post de este foro.

Cuando necesites comparar el signo de un partido de una columna con otra puedes hacer lo siguiente:

if ((Num1 \ pot(Partido - 1)) Mod 3) = (Num2 \ pot(Partido - 1)) Mod 3)) then ...

Donde Num1 y Num2 son los numeros decimales que representan a ambas columnas, Partido es la posición que se está comparando y pot() es un array de 14 elementos que contiene las potencias de 3. Este array debe ser inicializado al entrar en el programa y debe ser publico.
[Nomada]

Mensaje por [Nomada] »

Gracias Juan eso ya lo hago lo de inicializar la posición.

y eso gana mucho tiempo. SI necesiot algo mas ya te consultare.

Espero que lo que recibisteis lo entendais. Espero que sea de vuestro agrado. Es todo lo que tengo :) y a donde he llegado :o

Un saludo Juand
Avatar de Usuario
JoanD
12
12
Mensajes: 2657
Registrado: Vie 19 Dic, 2003 6:35 pm
Ubicación: Barcelona
Contactar:

Mensaje por JoanD »

La verdad es que soy un poco duro de mollera y no he acabado de comprender tu sistema. Pero si que he deducido que necesitas trabajar con cada una de las posiciones de la columna con lo cual tu problema no está únicamente en comparar globalmente 2 columnas y obtener el numero de diferencias sino que ademas necesitas poder realizar las comparaciones signo a signo para elaborar tu pronostico. Es por ello que, en el anterior post, puse la manera de conseguir que, esa comparación, sea lo mas rápida posible: evitar la comparación entre cadenas de caracteres.
[Nomada]

Mensaje por [Nomada] »

Hola Joand
Viajando por ahi y sin querer me encontre con esta dierccion, tarta de algoritmos alo mejor la conoces, sino es asi espero que te sirva de ayuda a tus ideas.

http://www.cucei.com.mx/modules/UpDownl ... _Datos.doc

Es un documento de word, te lo puedes bajar. si quieres, tiene ejemplos, en pascal me parece.

Un saludo
Avatar de Usuario
JoanD
12
12
Mensajes: 2657
Registrado: Vie 19 Dic, 2003 6:35 pm
Ubicación: Barcelona
Contactar:

Mensaje por JoanD »

Grácias Nomada.

Le he dado una ojeada y he visto que hay bastante "chicha". Veo que el Pascal es muy parecido al lenguaje C. Se le entiende todo. Muy interesante lo de los arrays circulares y también los algoritmos de ordenación y búsqueda, aunque esto ultimo ya lo tenemos bastante "sobado" con Coarma. Él expuso un algoritmo mas rápido que el Quick Short en el tema "Ordenar apuestas" de este foro.

Estamos a final de curso y si no aprovamos tendremos que repetirlo, asi que vamos a estudiar un poquito.
muttley
11
11
Mensajes: 325
Registrado: Mié 12 Feb, 2014 11:58 pm

Re: Algoritmos para eliminar columnas por diferencias

Mensaje por muttley »

Alguien sabe si estos algoritmos tenían nuevas ideas?
kot98
10
10
Mensajes: 197
Registrado: Mar 12 Jun, 2012 8:11 am

Re: Algoritmos para eliminar columnas por diferencias

Mensaje por kot98 »

Esto creo que lo hace varios programas de quinielas. :)
Responder