Hoy vamos a hablar de otra forma, más avanzada, que está disponible en NetLogo
y en muchos lenguajes de MBA, nos referimos a la posibilidad de crear
funciones dinámicas, cuando decimos funciones dinámicas, nos referimos a
funciones que están precodificadas para el momento en que el modelo está corriendo
en vez de manipular o vislumbrar los resultados de la ejecución del modelo
y una forma de hacer esto es con los comandos RUN o RUN-RESULT; ambos hacen las
mismas cosas, salvo que RUN-RESULT crea un reporte cuando se corre el código
toma cadenas de comandos, "código" y luego los corre de alguna manera
esto nos permite, esencialmente, crear código en forma dinámica durante la
corrida del modelo, por ejemplo uno puede literalmente decir algo como RUN [BK 1 LT
90 RT 90] o uno puede decir SET HEADING RUNRESULT [90 + 45 * 2]
en ambos casos escribimos el texto, pero lo que uno puede hacer es que en vez de
generar el texto en formas arbitrarias
les voy a mostrar un ejemplo de por qué querríamos hacer algo así, vamos al
ejemplo del código de NetLogo
uno puede imaginar, por ejemplo que se tiene una lista de cosas que uno puede
poner aquí y hacerlo correr en forma dinámica
TASK está relacionado de una forma que son piezas de código que uno puede
almacenar para ser usadas en una variable que se va a usar más tarde, por ejemplo
puedo tener dos procedimientos de SETUP SETUP1 y SETUP2 y SETUP1 podría ser TASK[
RANDOM 4] que sólo ejecute esa tarea, la número 1, este es un ejemplo muy sencillo
y podemos ASK PATCHES [SET PCOLOR RUN- RESULT SETUP1 o RUN-RESULT SETUP2]
y entonces se ejecutarán estas dos piezas de código
de este modo podemos tener estas dos cosas operando de diferentes formas
déjenme mostrarles cómo se hace esto y por qué puede ser tan poderoso
vamos a construir un ejemplo de cómo usar RUN y RUN-RESULT
imaginemos un ejemplo donde podemos tener tortugas que ejecutan su propia estrategia
por diferentes razones
turtles-own [strategy] y vamos a crear variables globales, que son los comandos
que van a ejecutar dentro de su estrategia
luego podemos asignar a esos comandos un valor preestablecido con el que le vamos a
dar una habilidad potencial
y estos son unos comandos de movimiento muy lindos, pero podrían ser lo que
quisiéramos que sean, ok? podrían ser comandos definidos por el usuario, podrían
ser cualquier cosa
luego podemos, pedirle que baje el lápiz (pen-down), asignar la dirección a 0,
asignar la estrategia para n valores 5 set strategy n-values [one-of commands]
qué es lo que esto va a hacer?
n-values básicamente corre un reporte 5 veces o corre un reporte las veces que uno
quiera, dependiendo del valor que pongamos aquí, esto dice corra el reporte y uno de
los comandos y que escoja en forma arbitraria de esta lista y luego los pone
en orden; la salida de esto
va a ser
una lista de 5 comandos; lo que luego queremos hacer, podemos básicamente decir
a las tortugas para cada estrategia, para cada elemento que tenemos en nuestra lista
de estrategias que corra ese elemento
podemos correr la rutina "setup" y luego "go"
y podemos ver como se ejecutan los comandos y son todos levemente diferentes
van a diferentes lugares, pero aún podemos ver que están repitiendo el mismo comando
una y otra vez; ahora vamos a incorporar RUN-RESULT
podemos agregar otro componente, que serán los operadores y las entradas
y podemos asignar los operadores a cosas como
signo más, signo menos, no quiero usar el divisor porque la división tiene sus
cosas, por ejemplo cuando dividimos por cero, que podemos llegar a hacerlo en
forma accidental y voy a asignar
las entradas, para que sean direccionamiento "heading"
"xcor"
"ycor"
1, 2, 10
y luego
puedo básicamente decir que
esta va a ser la estrategia y puedo crear una nueva, puedo darle
un giro a la estrategia "turn-strategy", así se convierte en algo más aleatorio
luego de que se ejecute la estrategia principal, asignemos el giro de la
estrategia
esto puede ser un poco confuso
voy a usar este comando "word"
para hacer lo que sea
un poco confuso, así que voy a repetir
5 veces el comando siguiente, vamos a asignar el giro de la estrategia (turn-
strategy)
para que sea
palabra (word)
giro de la estrategia (turn-strategy), con una de las entradas
y con uno de los operadores, está bien? esto sólo seleccionará
una de las entradas y uno de los operadores y al repetirlo 5 veces tenemos
xcor más ycor menos 1 * 5 veces en una sola movida; por supuesto necesitamos
poner una nueva entrada al final de todo esto porque podemos tener estos dos
operadores para que vayan al final y luego lo último que haremos es el giro de la
estrategia (turn-strategy)
que sea palabra (word) giro de la estrategia (turn-strategy), una de las
entradas; dicho sea de paso hay otro comando que toma dos cadenas y las empuja
y las junta, básicamente las suma y así podemos construir las cadenas a lo largo
del tiempo; voy a chequear para asegurarme de que esté todo bien, entonces ahora
podemos, al final de cada corrida de la estrategia principal, asignar la dirección
a RUN-RESULT y al giro de la estrategia (turn-strategy)
y esto correrá esos resultados; si volvemos acá, podemos arrancar, podemos
hacer click en "go", ups "formato ilegal de número", veamos que pasa
nos queda una pequeña cosita, tenemos que asignar el giro de la estrategia (turn-
strategy) a una cadena; tenemos que armar una estrategia ya que la estrategia será
reemplazada del todo y el giro de la estrategia será dependiente, entonces
queremos estar seguros de que sea anda el valor por defecto de NetLogo es un
conjunto de 0 valores, lo cual puede traer algunos problemas, porque dependeremos de
0; otra vez corremos "setup" y luego "go" y otra vez "go" y lo que podemos ver es
que está cambiando, debido a que el giro de la estrategia implica que luego de
correr un comando normal debemos volver a cambiarlo; en cualquier caso toda esta
porción de código nos permite crear estos bonitos patrones, podemos ver como en
forma algorítmica creamos un tipo de diseño al que podemos llamar "arte
algorítmico" y es un ejemplo de como usar RUN y RUNRESULT; en el manual, dicho sea
de paso, si quieren ver algunas cosas bien interesantes, hay una forma en la que se
puede tomar el código, tal como lo hice aquí y usar eso para resolver un problema
imaginen que quieren darle a una de estas tortugas la posibilidad de moverse en un
laberinto o algo así, o moverse a un lugar en particular; uno puede correr esto
combinado con algunos algoritmos evolucionarios para que hagan eso; en
algún sentido esto fue inspirado por Melanie Mitchel cuando trabajó sobre un
problema llamado "Robby el Robot", que creo ella introdujo en sus clases del SFI
en cualquier caso, esto nos da unos ejemplos rápidos de por que RUN y
RUNRESULT permiten crear patrones interesantes de conducta
dicho sea de paso, sólo les quiero mostrar esto rapidito, cómo se ven estas
estrategias? uno puede escribir [strategy] of one-of turtles (estrategia de una de
las tortugas) y las podemos ver, FD and BK y puedo hacer que el giro de la estrategia
de una de las tortugas; y vemos esta cadena de 2 - 10 - heading * 10 - 1 + xcor
este es un ejemplo de lo que estuvimos hablando; espero que haya sido útil
hemos visto RUN y RUN-RESULT, ahora vamos a explorar como crear un modelo usando
TASK; TASK es la habilidad de crear, de salvar funciones, esencialmente variables
para poder pasarlas a otras funciones por ejemplo un lugar donde pueden ser muy
útiles es cuando creamos una rutina de "setup"; podemos hacer una rutina "setup"
que tome como valores de entrada una tarea inicial
luego podemos escribir nuestro típico limpia todo (ca), reset-ticks, todo lo de
siempre
en esta rutina vamos a usar la tarea para hacer una especificación para que podamos
ver como queda el parche; en un caso queremos que se vea desigual y en otro
caso queremos que sea uniforme, entonces podemos decir ask patches [set pcolor
runresult initial-task]
y podemos usar esto para colorear lo que obtendremos y podemos hacerlo en dos
formas diferentes ya que tenemos una tarea que es setup-uniform que toma los valores
initial-value y básicamente lo que hace es setup task [initial-value] así en este
caso el procedimiento simplemente llamará al comando setup task y luego, perdón
llamará a setup y pasará la tarea con el valor que tenga o podemos hacer un setup-
random
y este podría ser setup task [random 4] y esto creará un setup aleatorio para el
inicio, entonces si vamos a la interfaz, podemos decir setup-uniform 4 y ahora
vemos un fondo gris o podemos escribir setup-random y vemos ese patrón diferente
podríamos escribir setup-uniform red y aún en este caso el rojo es simplemente un
fondo, podemos crear botones para esto, podemos tener uno para setup-uniform red
y será el setup rojo
y podemos tener otro botón que puede ser setup-random y que llamará al setup
aleatorio
podemos tener el setup rojo o el setup aleatorio, podemos ir y venir con los dos
las tareas (task) son muy poderosas, nos permiten pasar valores a funciones y esta
es una función muy simple, se pueden crear algunas más complejas como variables y eso
pude ser útil para pasar código y hacer que los modelos sean más dinámicos