En una entrada anterior de este blog vimos lo que era una gramática, y cómo se podían utilizar
las gramáticas para crear automáticamente sistemas de trading. En
esta entrada vamos a ver cómo se puede implementar todo esto con R.
Aunque el código es lo suficientemente genérico para poder utilizar
cualquier gramática, vamos a seguir con nuestro ejemplo de gramática
para la generación de números enteros, para no complicar demasiado
la cosa.
Lo primero que tenemos es que definir
nuestra gramática. Para ello utilizamos una lista de R con las
reglas de producción. Cada elemento de la lista es una regla, y
dentro de cada regla, las distintas opciones van como elementos en un
vector. Seguimos el convenio de encerrar los símbolos no terminales
entre '<' y '>', y dentro de una misma regla de producción
separamos los diferentes tokens mediante espacios (si no lo
hiciésemos así, tendríamos que recurrir a un analizador léxico, y
eso lo complicaría todo). A continuación declaramos el símbolo
inicial, y finalmente dentro de un bucle while() aplicamos las reglas
de producción iterativamente a los símbolos no terminales hasta que
todos los símbolos que queden en la cadena sean terminales.
En este caso hemos utilizado la función
sample() para seleccionar aleatoriamente qué regla de producción
tenemos que aplicar. En un entorno de producción real deberíamos
reemplazar esta regla por algún método de búsqueda inteligente,
tipo algoritmo genético o enjambre de partículas. Pero este es tema
para una futura entrada del blog.
# Definición de la gramática
nt <- list(
entero = c("<entero>
<digito>", "<digito>"),
digito = c("1", "2",
"3", "4", "5", "6", "7",
"8", "9", "0")
)
# Símbolo inicial
programa <- c("<entero>")
fin <- FALSE
while (!fin) {
fin <- TRUE
nprograma <- c()
for(i in 1:length(programa)) {
token <- programa[i]
if( grepl("<.+>",
token) ) {
# Se trata de un símbolo
no terminal, hay que parsearlo
# Quitamos los marcadores <
y >
token <- substr(token,
2, nchar(token)-1)
# Seleccionamos la regla
adecuada
regla <-
nt[names(nt)==token][[1]]
# Seleccionamos
aleatoriamente una producción
prod <- sample(regla, 1)
# Parseamos la producción
a aplicar y la añadimos
nprograma <-
c(nprograma, unlist(strsplit(prod, " ")))
# Tenemos que hacer otra iteración
fin <- FALSE
} else {
# Se trata de un símbolo
terminal, lo añadimos tal cual
nprograma <-
c(nprograma, token)
}
}
programa <- nprograma
}
# Programa final
sistema <- paste(programa,
collapse="")
print(sistema)
No hay comentarios:
Publicar un comentario