Implementación de un primer modelo basado en 4 agentes 4.1 Introducción y objetivos En este capítulo continuamos con sus lecciones sobre NetLogo, pero a partir de ahora el enfoque estará en la programación y el uso de ABM reales que abordan cuestiones científicas reales. (El modelo Mushroom Hunt de Capitulo 2 no estaba muy basado en agentes ni científico, en las formas que discutimos en este capítulo). Y aunque este capítulo todavía trata sobre la programación de NetLogo, comienza a abordar otros problemas de modelado. Debería prepararse para comenzar a usar un ABM para producir y analizar resultados significativos y abordar preguntas científicas, que es lo que hacemos en Capítulo 5 . Objetivos de aprendizaje para Capítulo 4 son a: Comprender cómo traducir un modelo a partir de su descripción escrita en formato ODD al código NetLogo. Comprender cómo definir variables globales, de tortuga y de parche. Familiarícese con las primitivas más importantes de NetLogo, como ask, set, let, create-turtles, ifelse y one-of. Empiece a aprender buenas prácticas de programación, como hacer cambios muy pequeños, comprobarlos constantemente y escribir comentarios en su código. Produzca su propio software para el modelo Butterfly descrito en Capítulo 3 . 4.2 ODD y NetLogo En Capítulo 3 introdujimos el protocolo ODD para describir un ABM y, como ejemplo, proporcionamos la formulación ODD de un modelo de mariposa en la cima. ¿Qué hacemos cuando llega el momento de hacer que un modelo descrito en ODD se ejecute realmente en NetLogo? Resulta bastante sencillo porque las organizaciones de ODD y NetLogo se corresponden estrechamente. Los elementos principales de una formulación ODD tienen elementos correspondientes en NetLogo. Propósito A partir de ahora, incluiremos las descripciones ODD de nuestros ABM en la pestaña Información de NetLogo. Estas descripciones comenzarán con una breve declaración del propósito general del modelo. Entidades, variables de estado y escalas Las entidades básicas para ABM están integradas en NetLogo: el mundo de los parches cuadrados, las tortugas como agentes móviles y el observador. Las variables de estado de las tortugas y los parches (y quizás otros tipos de agentes) se definen mediante las declaraciones turtles-own [] y parches-own [], y las variables que caracterizan el entorno global se definen en la declaración globals []. En NetLogo, como en ODD, estas variables se definen desde el principio. Resumen y programación del proceso Esto, exactamente, está representado en el procedimiento go. Debido a que un procedimiento go bien diseñado simplemente llama a otros procedimientos que implementan todos los submodelos, proporciona una descripción general (pero no la implementación detallada) de todos los procesos y especifica su programación, es decir, la secuencia en la que se ejecutan cada tick. Conceptos de diseño Estos conceptos describen las decisiones que se toman al diseñar un modelo y, por lo tanto, no aparecen directamente en el código NetLogo. Sin embargo, NetLogo proporciona muchas primitivas y herramientas de interfaz para respaldar estos conceptos; la parte II de este libro explora cómo se implementan los conceptos de diseño en NetLogo. Inicialización Esto corresponde a un elemento de cada programa NetLogo, el procedimiento de configuración. Pulsar el botón de configuración debería hacer todo lo que se describe en el elemento de inicialización de ODD. Datos de entrada Si el modelo usa una serie temporal de datos para describir el entorno, el programa puede usar las primitivas de entrada de NetLogo para leer los datos de un archivo. Submodelos Los submodelos de ODD se corresponden estrechamente, pero no exactamente, con los procedimientos de NetLogo. Cada uno de los submodelos de un modelo debe codificarse en un procedimiento NetLogo separado que luego se llama desde el procedimiento inicial. (A veces, sin embargo, es conveniente dividir un submodelo complejo en varios procedimientos más pequeños). Estas correspondencias entre ODD y NetLogo hacen que escribir un programa a partir de la formulación ODD de un modelo sea fácil y directo. La correspondencia entre ODD y el diseño de NetLogo, por supuesto, no es accidental: tanto ODD como NetLogo fueron diseñados para capturar y organizar las características importantes de los ABM. 4.3 Butterfly Hilltopping: de ODD a NetLogo Ahora, vamos a escribir por primera vez un programa de NetLogo que traduzca una formulación ODD para el modelo Butterfly. La forma en que vamos a hacer esto es jerárquica y paso a paso, con muchas pruebas intermedias. Le recomendamos encarecidamente que siempre desarrolle programas de esta manera: Primero programe la estructura general de un modelo, antes de comenzar con cualquiera de los detalles. Esto evita que se pierda temprano en los detalles. Una vez que la estructura general esté en su lugar, agregue los detalles uno a la vez. Antes de agregar cada elemento nuevo (un procedimiento, una variable, un algoritmo que requiere un código complejo), realice algunas pruebas básicas del código existente y guarde el archivo. De esta manera, siempre procedes desde “terreno firme”: si surge un problema de repente, es muy probable (aunque no siempre) que haya sido causado por el último pequeño cambio que hiciste. Primero, creemos un nuevo programa NetLogo, guárdelo e incluyamos la descripción ODD del modelo en la pestaña Información. Inicie NetLogo y utilice Archivo / Nuevo para crear un nuevo programa NetLogo. Use Archivo / Guardar para guardar el programa con el nombre “Butterfly-1.nlogo” en una carpeta apropiada. Obtenga el archivo que contiene la descripción ODD del modelo Butterfly del Capítulo 4 sección del sitio web de este libro. Vaya a la pestaña Información en NetLogo, haga clic en el botón Editar y pegue la descripción del modelo en la parte superior. Vuelva a hacer clic en el botón Editar. Ahora verá la descripción ODD del modelo Butterfly al principio de la documentación. Ahora, comencemos a programar este modelo con la segunda parte de su descripción ODD, las variables de estado y escalas. Primero, defina las variables de estado del modelo: las variables que poseen los parches, las tortugas y el observador. Vaya a la pestaña Procedimiento e inserte Haga clic en el botón Comprobar. No debería haber ningún mensaje de error, por lo que la sintaxis del código es correcta hasta ahora. Ahora, de la descripción de ODD vemos que las tortugas no tienen otras variables de estado que no sean su ubicación; Debido a que NetLogo ya tiene variables de tortuga integradas para la ubicación (xcor, ycor), no necesitamos definir nuevas variables de tortuga. Pero los parches tienen una variable de elevación, que no es una variable incorporada, por lo que debemos definirla. En el programa, inserte la elevación como una variable de estado de los parches: Si está familiarizado con otros lenguajes de programación, es posible que se pregunte dónde le decimos a NetLogo qué tipo de variable "elevación" es. La respuesta es: NetLogo descubre el tipo a partir del primer valor asignado a la variable a través de la primitiva de conjunto. Ahora necesitamos especificar la extensión espacial del modelo: cuántos parches tiene. Vaya a la pestaña Interfaz, haga clic en el botón Configuración y cambie "Ubicación de origen" a Esquina e Inferior izquierda; cambie el número de columnas (max- pxcor) y filas (max-pycor) a 149. Ahora tenemos un mundo, o paisaje, de 150 × 150 parches, con el parche 0,0 en la esquina inferior izquierda. Desactive las dos casillas de verificación de envoltura de mundo, de modo que nuestro mundo modelo tenga límites cerrados. Haga clic en Aceptar para guardar sus cambios. Probablemente verá que la pantalla del mundo (la “Vista”) ahora es extremadamente grande, demasiado grande para verla de una vez. Puedes arreglar esto: Vuelva a hacer clic en el botón Configuración y cambie "Tamaño de parche" a 3 más o menos, hasta que la Vista tenga un tamaño agradable. (También puede cambiar el tamaño del parche haciendo clic derecho en la Vista para seleccionarla y luego arrastrando una de sus esquinas). Lo siguiente que debe hacer es programar el procedimiento de configuración, donde se crean e inicializan todas las entidades y variables de estado. Nuestra guía, por supuesto, es la parte de Inicialización de la descripción ODD. De vuelta en la pestaña Procedimientos, comencemos de nuevo escribiendo un "esqueleto". Al final del programa existente, inserte esto: Vuelva a hacer clic en el botón Comprobar para asegurarse de que la sintaxis de este código sea correcta. Ya hay algo de código en este procedimiento de configuración: ca para eliminar todo, que casi siempre es el primero en el procedimiento de configuración, y reset-ticks, que casi siempre es el último. Se necesitará la declaración de solicitud de parches para inicializar los parches dándoles a todos un valor para su variable de elevación. El código para hacerlo irá entre corchetes de esta declaración. La asignación de elevaciones a los parches creará un paisaje topográfico para que las mariposas se muevan. ¿Cómo debería verse el paisaje? La descripción de ODD es incompleta: simplemente dice que comenzamos con una topografía artificial simple. Obviamente, necesitamos algunas colinas porque el modelo trata sobre cómo las mariposas encuentran las colinas. Podríamos representar un paisaje real (y lo haremos, en el próximo capítulo), pero para empezar es una buena idea crear escenarios tan simples que podamos predecir fácilmente lo que debería suceder. Crear solo una colina probablemente no sería lo suficientemente interesante, pero dos colinas bastarán. Agregue el siguiente código al comando ask patches: La idea es que hay dos colinas cónicas, con picos en las ubicaciones (coordenadas x, y) 30,30 y 120,100. La primera colina tiene una elevación de 100 unidades (supongamos que estas elevaciones están en metros) y la segunda una elevación de 50 metros. Primero, calculamos dos elevaciones ( elev1 y elev2) asumiendo que la elevación del parche disminuye en un metro por cada unidad de distancia horizontal entre el parche y el pico de la colina (recuérdese lo que hace el distancexy primitivo colocando el cursor sobre él y presionando la tecla F1). Entonces, para cada parche asumimos que la elevación es la mayor de dos elevaciones potenciales, elev1 y elev2: utilizando la primitiva ifelse, la elevación de cada parche se establece en la mayor de las dos elevaciones. Finalmente, la elevación del parche se muestra en la Vista configurando el color del parche pcolor en un tono del color verde que está sombreado por la elevación del parche en el rango 0 y 100 (busque el color de escala primitivo extremadamente útil). Recuerde que el comando ask patches establece un contexto de parche: todo el código dentro de sus corchetes debe ser ejecutable por parches. Por lo tanto, este código usa la variable de estado de elevación que definimos para los parches y la variable de parche incorporada pcolor. (Pudimos no han usado la variable incorporada color porque el color es una tortuga, no un parche, variable). Ahora, siguiendo nuestra filosofía de probar todo lo antes posible, queremos ver este panorama de modelos para asegurarnos de que se vea bien. Para hacerlo, necesitamos una forma de ejecutar nuestro nuevo procedimiento de configuración. En la Interfaz, presione el botón Botón, seleccione “Botón” y coloque el cursor en la Interfaz a la izquierda de la ventana Ver. Haga clic en el botón del mouse. Aparece un nuevo botón en la interfaz y se abre un cuadro de diálogo para su configuración. En el campo Comandos, escriba "configuración" y haga clic en Aceptar. Ahora hemos vinculado este botón al procedimiento de configuración que acabamos de programar. Si presiona el botón, se ejecuta el procedimiento de configuración y la interfaz debería verse como figura 4.1 . ¡Hay un paisaje con dos colinas! ¡Felicidades! (Si su Vista no se ve así, averigüe por qué revisando cuidadosamente todas las instrucciones. Recuerde que los errores que corrija no desaparecerán hasta que vuelva a presionar el botón de configuración). Rompecabezas de NetLogo Cuando hace clic en el botón de configuración nueva, ¿por qué NetLogo parece colorear los parches en puntos de toda la Vista, en lugar de simplemente comenzar desde arriba y trabajar hacia abajo? (Puede que tenga que girar el control deslizante de velocidad hacia abajo para ver esto con claridad). ¿Es esta una técnica de representación gráfica elegante utilizada por NetLogo? (Sugerencia: comience a leer la sección de la Guía de programación sobre conjuntos de agentes con mucho cuidado). Ahora necesitamos crear algunos agentes o, para usar la terminología de NetLogo, tortugas. Hacemos esto usando la primitiva create-turtles (abreviada crt). Para crear una tortuga, usamos crt 1 []. Para ver mejor la tortuga, es posible que deseemos aumentar el tamaño de su símbolo y también queremos especificar su posición inicial. Ingrese este código en el procedimiento de configuración, después de la declaración de solicitud de parches: Figura 4.1 El paisaje artificial del modelo Butterfly. Haga clic en el botón Verificar para verificar la sintaxis, luego presione el botón de configuración en la interfaz. Ahora hemos inicializado el mundo (parches) y los agentes (tortugas) lo suficiente para una primera versión mínima del modelo. Lo siguiente que necesitamos programar es el horario del modelo, el procedimiento de inicio. La descripción de ODD nos dice que el horario de este modelo incluye solo una acción, realizada por las tortugas: movimiento. Esto es fácil de implementar. Agregue el siguiente procedimiento: Al final del programa, agregue el esqueleto del movimiento del procedimiento: Ahora debería poder comprobar la sintaxis correctamente. Todavía falta una pieza importante. Aquí es donde, en NetLogo, controlamos la “extensión temporal” de un modelo: el número de pasos de tiempo que ejecuta antes de detenerse. En la descripción ODD de las variables y escalas de estado del modelo, vemos que las simulaciones del modelo Butterfly duran 1000 pasos de tiempo. En Capitulo 2 Aprendimos a usar el contador de ticks incorporado a través de las primitivas reset-ticks, tick y ticks. Lea la documentación de la parada primitiva y modifique el procedimiento de marcha para detener el modelo después de 1000 tics: Agregue un botón de ir a la interfaz. Haga esto tal como agregó el botón de configuración, excepto: ingrese "ir" como el comando que ejecuta el botón y active la casilla de verificación "Para siempre" para que al presionar el botón el observador repita el procedimiento de inicio una y otra vez. Nota de programación: Modificación de elementos de la interfaz Para mover, cambiar el tamaño o editar elementos en la interfaz (botones, controles deslizantes, gráficos, etc.), primero debe seleccionarlos. Haga clic con el botón derecho en el elemento y elija "Seleccionar" o "Editar". También puede seleccionar un elemento arrastrando el mouse de al lado del elemento para sobre él. Deseleccione un elemento simplemente haciendo clic en otro lugar de la interfaz. Si hace clic en ir, no sucede nada excepto que el contador de ticks sube a 1000; NetLogo está ejecutando nuestro procedimiento de ir 1000 veces, pero el procedimiento de movimiento al que llama sigue siendo solo un esqueleto. Sin embargo, verificamos que la estructura general de nuestro programa sigue siendo correcta. Y agregamos un Técnica muy utilizada en el procedimiento go: usar la primitiva tick y la variable ticks para realizar un seguimiento del tiempo de simulación y hacer que un modelo se detenga cuando lo deseamos. (¿Ha estado guardando su nuevo archivo NetLogo con frecuencia?) Ahora podemos dar un paso adelante nuevamente implementando el procedimiento de movimiento. Busque el elemento ODD "Submodelos" en la pestaña Información, donde encontrará los detalles de cómo se mueven las mariposas. Verás que una mariposa debe moverse, con una probabilidad q, a la celda vecina con mayor elevación. De lo contrario (es decir, con probabilidad 1 - q) se mueve a una celda vecina elegida al azar. Las mariposas siguen estas reglas incluso cuando han llegado a la cima de una colina local. Para implementar este proceso de movimiento, agregue este código al procedimiento de movimiento: La declaración ifelse debería resultar familiar: utilizamos una declaración similar en el procedimiento de búsqueda del modelo Mushroom Hunt de Capitulo 2 . Si q tiene un valor de 0.2, entonces en aproximadamente el 20% de los casos el número aleatorio creado por random-float será menor que q y la condición ifelse verdadera; en el otro 80% de los casos, la condición será falsa. En consecuencia, la declaración en el primer par de paréntesis (elevación cuesta arriba) se lleva a cabo con probabilidad q y el enunciado alternativo (mover a uno de los vecinos) se realiza con probabilidad 1– q. La primitiva cuesta arriba es típica de NetLogo: siguiendo un gradiente de una determinada variable (aquí, elevación) es una tarea requerida en muchos ABM, por lo que cuesta arriba se ha proporcionado como un atajo conveniente. Tener tales primitivas hace que el código sea más compacto y más fácil de entender, pero también hace que la lista de primitivas de NetLogo parezca bastante aterradora al principio. Las dos primitivas restantes en el procedimiento de movimiento (move-to y one-of) se explican por sí mismas, pero sería inteligente buscarlas para comprender claramente lo que hacen. Intente ir a la interfaz y haga clic en ir. NetLogo evita que salgamos de la pestaña de Procedimientos con un mensaje de error que nos indica que la variable q es desconocida para la computadora. (Si vuelve a hacer clic en la pestaña Interfaz, NetLogo cede y le permite ir allí, pero cambia la etiqueta de la pestaña Procedimientos a un rojo enojado para recordarle que las cosas no están del todo bien allí). Porque q es un parámetro que todas las tortugas necesitarán conocer, lo definimos como una variable global modificando la declaración global en la parte superior del código: Pero definiendo la variable q no es suficiente: también debemos darle un valor, así que lo inicializamos en el procedimiento de configuración. Podemos agregar esta línea al final de la configuración, justo antes del final: Las tortugas ahora se moverán de manera determinista al parche vecino más alto con una probabilidad de 0.4, y a un parche vecino elegido al azar con una probabilidad de 0.6. Ahora llega el gran momento: ¡puede ejecutar y verificar su primer ABM completo! Vaya a la Interfaz y haga clic en Configuración y luego vaya. Sí, la tortuga hace lo que queríamos que hiciera: encuentra la cima de una colina (la mayoría de las veces, la colina más alta, pero a veces la más pequeña), y su camino no es recto sino algo errático. Al igual que con el modelo MushroomHunt, ayudaría dejar el “corral” de la tortuga para que podamos ver su trayectoria completa. En el bloque crt del procedimiento de configuración (las declaraciones de código dentro de los corchetes después de crt), incluya una nueva línea al final con este comando: pen-down. Ahora puede comenzar a jugar con el modelo y su programa, por ejemplo, modificando el único parámetro del modelo, q. Simplemente edite el procedimiento de configuración para cambiar el valor de q ( o la ubicación inicial de la tortuga, o las ubicaciones de las colinas), luego regrese a la pestaña Interfaz y presione la configuración y listo botones. Un modelo típico para q = 0.2, por lo que las mariposas toman el 80% de sus decisiones de movimiento al azar, se muestra en figura 4.2 . Figura 4.2 Interfaz de la primera versión del modelo Butterfly, con q = 0,2. 4.4 Comentarios y el programa completo Ahora hemos implementado el núcleo del modelo Butterfly, pero todavía faltan cuatro cosas importantes: comentarios, observaciones, un paisaje realista y análisis del modelo. Abordaremos los comentarios aquí, pero pospondremos las otras tres cosas hasta Capítulo 5 . Comentarios son cualquier texto que siga un punto y coma (;) en la misma línea del código; NetLogo ignora dicho texto y, en cambio, es para personas. Los comentarios son necesarios para que el código sea más fácil de entender para otros, pero también son muy útiles para nosotros: después de que pasen unos días o semanas, es posible que no recuerde por qué escribió una parte de su programa como lo hizo en lugar de otra. camino. (Este problema sorprendentemente común suele ocurrir cuando el código fue más difícil de escribir y más fácil de estropear). Poner un comentario al comienzo de cada procedimiento que diga si el procedimiento está en el contexto de tortuga, parche o observador lo ayuda a escribir los procedimientos al hacerle pensar en su contexto, y facilita las revisiones. Como un buen comentario de ejemplo, cambie la primera línea de su procedimiento de movimiento a esto, para que siempre recuerde que el código de este procedimiento está en el contexto de la tortuga: Los ejemplos de código de este libro utilizan pocos comentarios (para que el texto sea breve y para obligar a los lectores a comprender el código). Los programas que puede descargar a través del sitio web del libro incluyen comentarios, y debe acostumbrarse a comentar su propio código. En particular, utilice los comentarios para: Describa brevemente lo que se supone que debe hacer cada procedimiento o parte no trivial del código; Explique el significado de las variables; Documente el contexto de cada procedimiento; Mantenga un registro de qué bloque de código o procedimiento finaliza con “]” o finaliza (consulte el ejemplo a continuación); y En programas largos, separe visualmente los procedimientos entre sí mediante el uso de líneas de comentarios como esta: Por otro lado, los comentarios detallados y extensos no sustituyen al código que está escrito con claridad y es fácil de leer. Especialmente en NetLogo, debe esforzarse por escribir su código para que no necesite muchos comentarios para comprenderlo. Use nombres para variables y procedimientos que sean descriptivos y haga que sus declaraciones de código se lean como lenguaje humano. Utilice pestañas y líneas en blanco para mostrar la organización del código. Demostramos este enfoque de código de “auto-comentarios” a lo largo del libro. Otro uso importante de los comentarios es desactivar temporalmente las declaraciones de código. Si reemplaza algunas declaraciones pero cree que podría querer recuperar el código anterior más adelante, simplemente "comente" las líneas colocando un punto y coma al comienzo de cada una. Por ejemplo, a menudo agregamos declaraciones de salida de prueba temporales, como este que se podría poner al final de la declaración de solicitud de parches en el procedimiento de configuración para verificar los cálculos que configuran la elevación: Si prueba esto una vez, verá que le brinda la información para verificar que la elevación esté configurada correctamente, pero también descubrirá que no desea repetir esta verificación cada vez que use la configuración. Entonces, cuando ya no necesite esta declaración, simplemente coméntela colocando un punto y coma delante de ella. Dejar la declaración en el código pero comentada proporciona documentación de cómo verificó las elevaciones y le permite repetir fácilmente la verificación cuando lo desee. Aquí está nuestro programa modelo Butterfly, incluidos los comentarios. Incluya comentarios en su programa y guárdelo. Lo segundo que falta ahora en el modelo es la observación. Hasta ahora, el modelo solo produce resultados visuales, lo que nos permite buscar errores obvios y ver cómo se comporta la mariposa. Pero para usar el modelo para su propósito científico —comprender el surgimiento de los “corredores virtuales” necesitamos resultados adicionales que cuantifiquen el ancho del corredor utilizado por una gran cantidad de mariposas. Otro elemento que debemos hacer más científico es el panorama modelo. Es bueno comenzar a programar y probar y analizar modelos con escenarios artificiales como lo hicimos aquí, porque hace que sea más fácil comprender la interacción entre el paisaje y el comportamiento del agente e identificar errores, pero ciertamente no queremos restringir nuestro análisis a artificiales. paisajes como el que tenemos ahora. Finalmente, todavía no hemos hecho ningún análisis sobre este modelo, por ejemplo para ver cómo el parámetro q afecta el movimiento de las mariposas y la aparición de pasillos virtuales. Trabajaremos en la observación, un paisaje realista y análisis en el próximo capítulo, pero ahora debería estar ansioso por jugar con el modelo. “Jugar” —pruebas creativas y modificación del modelo y programa (“Qué pasaría si ...”) - es importante en el modelado. A menudo, no comenzamos con una idea clara de qué observaciones debemos usar para analizar un modelo. Por lo general, tampoco estamos seguros de si nuestros submodelos son apropiados. NetLogo hace que jugar sea muy fácil. Ahora tiene la oportunidad de analizar heurísticamente (es decir: ¡jugar con él!) El modelo. 4.5 Resumen y conclusiones Si este libro solo tratara sobre la programación de NetLogo, este capítulo simplemente habría seguido adelante con la enseñanza de cómo escribir procedimientos y usar la interfaz. Pero debido a que este libro trata principalmente sobre el modelado basado en agentes en la ciencia, comenzamos el capítulo revisando el protocolo ODD para describir ABM y mostrando cómo podemos traducir directamente una descripción ODD en un programa NetLogo. En el modelado científico, comenzamos por pensar y escribir el diseño del modelo; ODD proporciona una forma productiva y estándar de hacer esto. Luego, cuando pensamos que tenemos suficiente diseño para implementar en la computadora, lo traducimos en código para que podamos comenzar a probar y revisar el modelo. El protocolo ODD se desarrolló independientemente de NetLogo, pero tienen muchas similitudes y se corresponden bastante estrechamente. Esto no es una coincidencia, porque tanto ODD como NetLogo se desarrollaron buscando las características clave de los ABM en general y las formas básicas en que se diferencian de otros tipos de modelos (y, por lo tanto, las formas en que su software debe ser único). Estas características clave se utilizaron para organizar ODD y NetLogo, por lo que es natural que se correspondan entre sí. En la sección 4.2 mostramos cómo cada elemento de ODD corresponde a una parte específica de un programa NetLogo. Este capítulo ilustra varias técnicas para comenzar a modelar de manera fácil y productiva. Primero, comience a modelar con la versión más simple del modelo imaginable; ignore muchos, si no la mayoría, de los componentes y procesos que espera incluir más adelante. La segunda técnica consiste en desarrollar programas de forma jerárquica: empezar con los esqueletos de las estructuras (procedimientos, pedir órdenes, conmutadores ifelse, etc.); pruebe estos esqueletos en busca de errores de sintaxis; y solo entonces, paso a paso, agregue “carne a los huesos” del esqueleto. ODD comienza con las características más generales del modelo; una vez que se han programado, tiene un “esqueleto” sólido: el propósito del modelo se documenta en la pestaña Información, se establecen las dimensiones de la Vista, se definen las variables de estado y se sabe qué procedimientos se deben llamar en el procedimiento de inicio. Luego puede completar en detalle, primero convirtiendo el elemento de Inicialización ODD en el procedimiento de configuración, y luego programando cada procedimiento en su totalidad. En cada paso del camino, puede agregar esqueletos como procedimientos vacíos y declaraciones de solicitud, En tercer lugar, si su modelo eventualmente incluirá un entorno complejo o realista, comience con uno artificial simplificado. Esta simplificación puede ayudarlo a comenzar antes y, lo que es más importante, le facilitará la identificación de errores (ya sea en la programación o en la lógica) en la forma en que los agentes interactúan con su entorno. Finalmente, formatear tu código de manera agradable y proporcionar los comentarios apropiados vale la pena el poco tiempo que lleva. Sus comentarios deben tener dos objetivos: facilitar la comprensión y la navegación por el código con pequeños recordatorios sobre qué contexto se está utilizando, qué bloques de código y procedimientos terminan con un] o un final, etc. y documentar cómo y por qué programó cosas no triviales como lo hizo. Pero recuerde que su código debe ser fácil de leer y comprender incluso con comentarios mínimos. ¡Estas no son solo preocupaciones estéticas! Si su modelo tiene éxito, usted y otras personas leerán y revisarán el código muchas veces, así que tómese unos segundos mientras lo escribe para facilitar el trabajo futuro. Ahora, retrocedamos de la programación y consideremos lo que hemos logrado hasta ahora. Queríamos desarrollar un modelo que nos ayudara a comprender cómo y dónde en un paisaje aparecen los “corredores virtuales” del movimiento de las mariposas. La hipótesis es que los corredores no están necesariamente vinculados a características del paisaje que son especialmente adecuadas para la migración, sino que también pueden surgir de la interacción entre la topografía y las decisiones de movimiento de las mariposas. Representamos estas decisiones de la manera más simple: diciéndoles a las mariposas que se muevan cuesta arriba, pero con su variabilidad en el movimiento representada por el parámetro q. Los primeros resultados de un altamente artificial El paisaje indica que de hecho nuestra regla de movimiento tiene el potencial de producir corredores virtuales, pero obviamente tenemos más que hacer. En el próximo capítulo agregaremos cosas necesarias para hacer un ABM real para el problema del corredor virtual: salida que cuantifica los “corredores” que usan las mariposas modelo, un paisaje realista para que vuelen y una forma de analizar corredores sistemáticamente. 4.6 Ejercicios 1. Cambie el número de mariposas a 50. Ahora, pruebe algunos valores diferentes del parámetro q. Predice lo que sucederá cuando q es 0.0 y 1.0 y luego ejecute el modelo; ¿Fue correcta tu predicción? 2. Modifique su modelo para que no todas las tortugas tengan la misma ubicación inicial, sino que su ubicación inicial se establezca al azar. (Sugerencia: busque primitivas que proporcionen ubicaciones aleatorias X e Y). 3. De los dos primeros ejercicios, debería haber visto que los caminos de las mariposas parecen inesperadamente artificiales. ¿Tiene una explicación para esto? ¿Cómo podría determinar qué lo causa? Intente analizar un mundo más pequeño y agregue etiquetas a los parches que indiquen numéricamente su elevación. (Sugerencia: los parches tienen un rótulo variable incorporado. Consulte el ejercicio 4). 4. Intente agregar "ruido" al paisaje, agregando un número aleatorio a la elevación del parche. Puede agregar esta declaración a la configuración, justo después de establecer la elevación del parche: establecer elevación de elevación + aleatorio 10. ¿Cómo afecta esto al movimiento? ¿Le ayudó este experimento a responder las preguntas del ejercicio 3? De las animaciones a la ciencia 5 5.1 Introducción y objetivos Los principiantes a menudo creen que el modelado se trata principalmente de formular e implementar modelos. Este no es el caso: comienza el verdadero trabajo después primero se implementó un modelo. Luego usamos el modelo para encontrar respuestas y soluciones a las preguntas y problemas con los que comenzamos nuestro proyecto de modelado, que casi siempre requiere modificar la formulación y el software del modelo. Este proceso iterativo de análisis y perfeccionamiento del modelo, el ciclo de modelado, por lo general no se documenta en las publicaciones producidas al final. En cambio, los modelos se presentan normalmente como entidades estáticas que se acaban de producir y utilizar. De hecho, la descripción de cada modelo es solo una instantánea de un proceso. La biblioteca de modelos de NetLogo tiene un problema similar: presenta los modelos y da (en la pestaña Información) algunas pistas sobre cómo analizarlos, pero no puede demostrar cómo hacer ciencia con ellos. Estos modelos son muy buenos para la animación: nos permiten ver qué sucede a medida que se ejecutan sus suposiciones y ecuaciones. Pero no le muestran cómo explorar ideas y conceptos, desarrollar y probar hipótesis y buscar explicaciones parsimoniosas y generales de los fenómenos observados. En este capítulo ilustramos cómo convertir un programa NetLogo en un modelo científico en lugar de solo un simulador, tomando el modelo Butterfly y agregando las cosas necesarias para hacer ciencia. Recuerde que el propósito de este modelo era explorar el surgimiento de “corredores virtuales”: lugares donde las mariposas se mueven en altas concentraciones aunque no haya nada allí que atraiga a las mariposas. Nuestro modelo hasta ahora simula el movimiento de las mariposas, pero no nos dice nada sobre los pasillos y cuándo y con qué fuerza emergen. Por lo tanto, ahora produciremos resultados cuantitativos que se pueden analizar, en lugar de solo la visualización visual del movimiento de la mariposa. También reemplazaremos nuestro paisaje muy simple y artificial con uno real leído de un archivo de topografía. Suponemos que a estas alturas ya ha aprendido lo suficiente sobre NetLogo para escribir código usted mismo mientras busca con frecuencia cosas en el Manual del usuario y obtiene ayuda de otros. Por lo tanto, ya no proporcionamos código completo ya que lo guiará a través de los cambios en el modelo, excepto cuando estén involucrados primitivos o enfoques particularmente complicados. Aquellos de ustedes que estén trabajando en este libro sin la ayuda de instructores y compañeros de clase pueden consultar nuestro sitio web para obtener ayuda si se quedan atascados. Y tenga en cuenta que la segunda parte de este libro debería reforzar y profundizar su comprensión de todas las técnicas de programación que se utilizan aquí. Si sientes que te acaban de arrojar a aguas profundas sin saber nadar, haz tu mejor esfuerzo y no te preocupes: las cosas se volverán más fáciles pronto. Los objetivos de aprendizaje de este capítulo son: Conozca la importancia del control de versiones: guarde versiones documentadas de sus programas cada vez que comience a realizar cambios sustanciales. Comprender el concepto de que el uso de un ABM para la ciencia requiere producir resultados cuantitativos y realizar experimentos de simulación; y ejecute su primer experimento de simulación. Aprenda a definir e inicializar una variable global creando un control deslizante o activando la Interfaz. Desarrolle una comprensión de lo que son los reporteros y cómo escribirlos. Empiece a aprender a encontrar y corregir errores en su código. Aprenda a crear resultados escribiendo en una ventana de resultados, creando un gráfico de series de tiempo y exportando los resultados del gráfico a un archivo. Pruebe una forma sencilla de importar datos a NetLogo, creando una versión del modelo Butterfly que utiliza datos topográficos reales. 5.2 Observación de pasillos Nuestro modelo Butterfly no está listo para abordar su propósito científico en parte porque carece de una forma de observar cuantitativamente hasta qué punto surgen los corredores virtuales. Pero, ¿cómo caracterizaríamos un corredor? Obviamente, si todos los individuos siguieran el mismo camino (como cuando todos comienzan en el mismo lugar y q es 1.0) el corredor sería muy estrecho; o si el movimiento fuera completamente aleatorio, no esperaríamos identificar ninguna característica similar a un corredor. Pero necesitamos cuantificar cómo cambia el ancho de las rutas de movimiento a medida que variamos cosas como q o la topografía del paisaje. Hagamos algo sobre este problema. Primero, porque estamos a punto de realizar un cambio importante en el programa: cree y guarde una nueva versión de su software de mariposa. Nota de programación: Control de versiones Cada vez que crea una nueva versión de un modelo, haga una nueva copia del programa guardándola con un nombre descriptivo, quizás en un directorio separado. (¡Haga esto primero, antes de cambiar nada!) Luego, a medida que cambie el modelo, use los comentarios en la pestaña Procedimientos para documentar los cambios que realizó en el programa y actualice la pestaña Información para describir la nueva versión. De lo contrario, lo lamentarás mucho. Es muy fácil sobrescribir accidentalmente una versión de modelo anterior que necesitará más adelante, u olvidar en qué se diferencia una versión de las demás. Incluso es una buena idea mantener una tabla que muestre exactamente qué cambios se realizaron en cada copia de un modelo. Incluso cuando juegues con un modelo, asegúrate de guardarlo primero como una versión temporal para no estropear el archivo permanente. Los programadores utilizan el término "control de versiones" para esta práctica de realizar un seguimiento de los cambios que se realizaron en qué copia del software. A lo largo de este curso realizaremos muchas modificaciones a muchos programas; Adquiera el hábito de un control de versiones cuidadoso desde el principio y evite muchos problemas y pérdidas de tiempo. Figura 5.1 La medida del ancho del corredor para un grupo de mariposas que migran cuesta arriba (aquí, 50 mariposas que comenzaron en la ubicación 85,95 con q = 0,4). El ancho del corredor es (a) el número de parches utilizados por las mariposas (los parches blancos aquí), dividido por (b) la distancia promedio en línea recta (en unidades de longitudes de parches) entre el parche inicial de las mariposas y la cima de la colina final. Aquí, la mayoría de las mariposas subieron por la colina grande hacia la parte inferior izquierda, pero algunas subieron por la colina más pequeña hacia la derecha. El número de manchas blancas es 1956 y la distancia media entre los puntos inicial y final de la mariposa (los puntos negros) es 79,2 manchas; por lo tanto, el ancho del pasillo es de 24,7 parches. Pe'er y col. (2005) cuantificaron el ancho del corredor dividiendo el número de parches visitados por todos los individuos durante 1000 pasos de tiempo por la distancia entre el parche de inicio y la cima de la colina. En nuestra versión del modelo, diferentes mariposas pueden comenzar y terminar en diferentes lugares, por lo que modificamos ligeramente esta medida. Primero, asumiremos que cada mariposa se detiene cuando llega a la cima de una colina local (un parche más alto que los ocho parches vecinos). Luego, cuantificaremos el ancho del "corredor" utilizado por todas las mariposas como (a) el número de parches que son visitados por cualquier mariposas dividido por (b) la distancia media entre las ubicaciones de inicio y finalización, sobre todas las mariposas ( figura 5.1 ). Esta medida del ancho del corredor debe ser baja (aproximándose a 1.0) cuando todas las mariposas siguen el mismo camino recto cuesta arriba, pero debe aumentar a medida que las mariposas individuales siguen caminos diferentes, cada vez más tortuosos. Por tanto, para analizar el modelo vamos a producir una gráfica de ancho de corredor vs. q. Esto es importante: al analizar un modelo, necesitamos tener una idea clara de qué tipo de gráfico queremos producir a partir de qué resultado, porque esto nos dice qué tipo de experimentos de simulación tenemos que realizar y qué resultados necesitamos que el programa realice. producir (ver también capitulo 22 ). Ahora que hemos determinado qué necesitamos cambiar en el modelo para observar y analizar el ancho del corredor, implementemos los cambios. Debido a que ahora es obvio que necesitamos realizar experimentos variando q y viendo su efecto, cree un control deslizante para ello en la pestaña Interfaz. (La Guía de interfaz del Manual del usuario de NetLogo le indicará cómo hacerlo). Configure el control deslizante de modo que q varíe de 0,0 a 1,0 en incrementos de 0,01. Cambie el procedimiento de configuración para que se creen 50 personas y comiencen desde la misma posición. Entonces varía q a través de su control deslizante y observe cómo cambia el área cubierta por todos los caminos de las mariposas. Nota de programación: Mover variables a la interfaz Cuando comenzamos a hacer experimentos en un modelo, a menudo necesitamos variar el valor de algún parámetro muchas veces. NetLogo proporciona controles deslizantes, interruptores (para variables booleanas) y selectores en la pestaña Interfaz para que esto sea conveniente: una vez que sabemos qué variable global queremos cambiar, la movemos a la Interfaz creando uno de estos elementos de Interfaz para controlar la variable. . Pero mover una variable a la interfaz suele ser una fuente de frustración para los principiantes. Es importante comprender que esta interfaz controla tanto definir y inicializar una variable; aquí hay algunos consejos. Primero, solo las variables globales se pueden controlar mediante controles deslizantes, interruptores y selectores; no variables de tortuga o parche. En segundo lugar, una vez que se ha creado uno de estos controles de interfaz para un variable, esa variable todavía no puede aparecer en la globales declaración en la parte superior de los Procedimientos. Recomendamos comentar la variable fuera del globales declaración de modo que cuando lea los procedimientos se le recuerde que la variable existe. El mayor problema potencial es olvidar eliminar las declaraciones que establecen el valor de la variable desde el configuración procedimiento. Si, por ejemplo, pones el modelo Butterfly q parámetro en un control deslizante y establezca el control deslizante en 0.5, pero olvide eliminar la declaración establecer q 0.2 desde el configuración procedimiento, configuración restablecerá el control deslizante a 0,2 en cada ejecución del modelo. NetLogo no le informará sobre este error. Entonces, cada vez que mueva una variable a la interfaz, comente su inicialización declaración en configuración. Modifique el procedimiento de movimiento para que las mariposas ya no se muevan si están en la cima de una colina. Una forma de hacer esto es probar si la tortuga está en un parche con una elevación mayor que la de todos sus vecinos y, de ser así, omitir el resto del procedimiento de movimiento. El código para esta prueba es un poco más complejo que otras declaraciones que ha usado hasta ahora, así que lo explicamos. Ponga esta declaración en el inicio del procedimiento de movimiento: Esta declaración incluye una expresión compuesta típica de NetLogo. Comenzando por la izquierda, usa la primitiva if, que primero verifica una condición verdadero-falso y luego ejecuta los comandos en un conjunto de corchetes. El enunciado termina con [detener], por lo que sabemos que (a) la condición verdadero-falso es todo el texto después de si y antes de [detener], y (b) si esa condición es verdadera, la primitiva de detención es ejecutado. Esta declaración puede confundirlo porque está claramente en el contexto de la tortuga, el procedimiento de movimiento lo ejecutan las tortugas, pero usa el parche elevación variable. La razón por la que funciona es que en NetLogo las tortugas siempre tienen acceso a las variables de su parche actual y pueden, como lo hacen aquí, leerlas y escribirlas como si fueran variables de tortuga. Para comprender el lado derecho de la condición de desigualdad (después de "> ="), Necesito comprender al reportero max-one-of, que toma un conjunto de agentes: aquí, el conjunto de parches devueltos por los vecinos reporteros y el nombre de un reportero. (Recuerde que un reportero es un procedimiento que devuelve o “informa” algo —un número, un agente, un conjunto de agentes, etc.— de regreso al procedimiento que lo llamó.) El reportero aquí es sólo [elevación], que informa la elevación de cada parche vecino. Es muy importante comprender que puede obtener el valor de las variables de un agente (por ejemplo, la elevación de un parche vecino) tratando a los reporteros de esta manera. También es necesario comprender la función de reportero. Aquí, en combinación con max-one-of, informa la elevación del parche vecino que tiene más elevación. Por lo tanto, la condición de la declaración if es "si la elevación de mi parche actual es mayor o igual que la elevación del parche circundante más alto". Expresiones compuestas como esta pueden parecer algo confusas al principio, lo cual no es sorprendente: esta declaración de una línea usa cinco primitivas. Pero aprenderá rápidamente a comprender y escribir tales expresiones y a apreciar lo fáciles que hacen muchas tareas de programación. Ahora necesitamos calcular y registrar el ancho del corredor de la población de mariposas. ¿Cómo? Recordando nuestra definición de ancho de pasillo ( figura 5.1 ), necesitamos (a) el número de parches visitados y (b) la distancia media entre los parches de inicio y fin de las mariposas. Podemos contar el número de parches utilizados por las mariposas dándole a cada parche una variable que registra si alguna vez ha estado allí una tortuga. Las tortugas, cuando dejan de moverse, pueden calcular la distancia desde su parche inicial si tienen una variable que registre su parche inicial. Por lo tanto, vamos a introducir una nueva variable de estado tanto para parches como para tortugas. Estas variables no son utilizadas por los parches y las tortugas en sí, sino por nosotros para calcular el ancho del corredor y analizar el modelo. Agregue una nueva variable a la declaración de parches-own: used ?. Esto es un booleano verdadero-falso), por lo que seguimos la convención de NetLogo de terminar el nombre de la variable con un signo de interrogación. Esta variable será verdadera si alguna mariposa ha aterrizado en el parche. Agregue una variable llamada start-patch a la declaración de las propias tortugas. En el procedimiento de configuración, agregue declaraciones para inicializar estas nuevas variables. Al final de la declaración que inicializa los parches (pregunte parches […]), agregue el conjunto usado? falso. Al final de la inicialización de las tortugas en la declaración crt, establezca start-patch en el parche en el que se encuentra la tortuga. El parche primitivo aquí informa el parche en el que se encuentra actualmente una tortuga. Cuándo asignamos este parche a la variable start-patch de la tortuga, el parche inicial de la tortuga se convierte en una de sus variables de estado. (Las variables de estado pueden ser no solo números, sino también agentes, listas y conjuntos de agentes). Nota de programación: Inicializando variables En NetLogo, las nuevas variables tienen un valor de cero hasta que el programa les asigna otro valor. Entonces: Si Está bien que una variable comience con un valor de cero, no es esencial inicializarla. excepto que es muy importante formar el hábito de asignar siempre un valor inicial a todas las variables. La razón principal es evitar los errores que resultan de olvidarse de inicializar variables (como parámetros globales) que necesitan valores distintos de cero; estos errores son fáciles de cometer, pero pueden ser muy difíciles de detectar y encontrar. Ahora necesitamos los parches para realizar un seguimiento de si alguna vez se ha posado una mariposa sobre ellos. Podemos dejar que las mariposas hagan esto: Agregue una instrucción al procedimiento de movimiento que hace que la mariposa, una vez que haya movido a un nuevo parche, para establecer la variable del parche utilizada? a "verdadero". (Recuerde que las tortugas pueden cambiar las variables de su parche como si fueran las variables de la tortuga). Finalmente, podemos calcular el ancho del corredor al final de la simulación. En la declaración del procedimiento go que detiene el programa después de 1000 tics, inserte una declaración que se ejecute una vez antes de que se detenga la ejecución. Esta declaración utiliza el primitiva muy importante let para crear una variable local final-corridor-width y darle el valor producido por un nuevo reporter corridor-width. Escriba el esqueleto de un procedimiento de reportero a lo ancho del corredor, que reporta el ancho medio del camino de las tortugas. Busque la palabra clave to-report en el Diccionario NetLogo y lea acerca de los reporteros en la sección "Procedimientos" de la Guía de programación. En el nuevo procedimiento de ancho de pasillo: Cree una nueva variable local y configúrela con el número de parches que se han visitado al menos una vez. (Sugerencia: use el recuento primitivo). También cree una nueva variable local que sea la media, sobre todas las tortugas, de la distancia desde el parche actual de la tortuga y su parche inicial. (Mira el primitivas media y distancia.) A partir de las dos nuevas variables locales anteriores, calcule el ancho del corredor e informe su valor como resultado del procedimiento. En el procedimiento go, después de establecer el valor de final-corridor-width llamando a corridor-width, imprima su valor en una ventana de salida que agregue a La interfaz. No solo imprima el valor de final-corridor-width en sí, sino también el texto "Corridor width:". (Vea las primitivas de entrada / salida y cadenas en el Diccionario NetLogo). Si hizo todo bien, debe obtener un ancho de pasillo de aproximadamente 25 cuando q es 0,4. La ventana de salida ahora debería verse así figura 5.2 . Figura 5.2 Una ventana de salida que muestra el ancho del pasillo. Nota de programación: Consejos para solucionar problemas Ahora está escribiendo código en gran parte por su cuenta, por lo que, como principiante, a veces se quedará atascado. Quedarse atascado está bien porque las buenas estrategias para la resolución de problemas son algunas de las cosas más importantes que debe aprender ahora. Los enfoques importantes son: Proceda lentamente agregando solo pequeños fragmentos de código y probando antes de continuar; Consultar frecuentemente el Manual de Usuario; Buscar código en la biblioteca de modelos y ejemplos de código; Usar los monitores de agentes y colocar temporalmente declaraciones "mostrar" (use el show primitivo para generar el valor actual de una o varias variables) en su programa para ver qué está sucediendo paso a paso; Buscando discusiones sobre su problema en el Foro de usuarios de NetLogo; y Usando tanto lógica ("Debería funcionar de esta manera porque ...") como heurística ("Déjame probar esto y ver qué pasa ..."). Y tenga en cuenta que el siguiente capítulo está dedicado por completo a encontrar, corregir y evitar errores. 5.3 Análisis del modelo Ahora podemos analizar el modelo Butterfly para ver cómo la salida del ancho del corredor se ve afectada por el parámetro q. Si usa el control deslizante para variar q en un amplio rango, anote los anchos de los corredores resultantes y luego grafique el ancho del pasillo contra q, deberías obtener una gráfica similar a figura 5.3 . (NetLogo tiene una herramienta llamada BehaviorSpace que ayuda con este tipo de experimento; aprenderá a usarla en Capítulo 8 .) Estos resultados no son muy sorprendentes porque muestran principalmente que con menos aleatoriedad en las decisiones de movimiento de las mariposas, el movimiento es más recto y, por lo tanto, el ancho del pasillo es más pequeño. Parece probable que un paisaje menos artificial produzca resultados más interesantes, pero nuestro paisaje simplificado nos permitió probar si el resultado de la observación se comporta como esperábamos. Hay una pequeña sorpresa en los resultados: el ancho del corredor está muy por debajo de 1.0 (aproximadamente 0.76) cuando q es 1.0. ¿Cómo es posible que el número de parches visitados sea un 24% menor que la distancia entre los parches iniciales y finales? ¿Las mariposas escapan de los confines de la geometría euclidiana y encuentran un camino que es más corto que la distancia en línea recta? Hay algo mal con la distancia primitiva? Dejamos encontrando una explicación a los ejercicios. 5.4 Resultados de series de tiempo: adición de gráficos y salida de archivos Ahora intentemos algo que a menudo necesitamos hacer: examinar los resultados a lo largo del tiempo a medida que avanza la simulación en lugar de solo al final de la ejecución del modelo. Los gráficos son extremadamente útiles para observar los resultados a medida que se ejecuta un modelo. Sin embargo, todavía necesitamos anotar los resultados para poder analizarlos, y ciertamente no queremos anotar los resultados para cada paso de tiempo de un gráfico o la ventana de salida. En su lugar, necesitamos que NetLogo escriba los resultados en un archivo que podamos analizar. Figura 5.3 Ancho del corredor del modelo Butterfly, utilizando la topografía y el parche de inicio en figura 5.1 , en función del parámetro q. Los puntos son el resultado de una simulación por cada valor de q. Pero antes de que podamos agregar cualquiera de estas salidas de series de tiempo, tenemos que cambiar el programa del modelo Butterfly para que produzca resultados en cada paso de tiempo. Actualmente calculamos el ancho del corredor solo una vez, al final de una simulación; ahora tenemos que cambiar ligeramente la programación del modelo para que las mariposas calculen su ancho de ruta en cada paso de tiempo. El procedimiento de Go puede tener este aspecto: La nueva declaración de trazado hace dos cosas: llama al reportero del ancho del corredor para obtener el valor actual del ancho del corredor, y luego envía ese valor para que sea el siguiente punto en un trazado en la pestaña Interfaz. (Comenzando con la versión 5.0, NetLogo le permite escribir el código para actualizar los gráficos directamente en el objeto del gráfico en la interfaz. Preferimos que mantenga las declaraciones de trazado en su código, donde es más fácil de actualizar y es menos probable que se olvide. En el cuadro de diálogo que se abre cuando agrega un gráfico a la interfaz, puede haber una ventana etiquetado como "comandos de actualización" que contiene texto como tortugas de recuento de parcelas. Simplemente borre ese texto). Cambie el procedimiento de inicio como se ilustra arriba. Lea la sección de la Guía de programación sobre "Trazado" y agregue un trazado a la interfaz. Nombra la parcela "Ancho del corredor". Borre cualquier texto en la parte de "Comandos de actualización" del cuadro de diálogo de trazado. Pruebe el modelo con varios valores de q. Mirar esta gráfica nos da una idea de cómo cambia el ancho del corredor con q y con el tiempo, pero para hacer un análisis real necesitamos estos resultados escritos en un archivo. Una forma de obtener la salida del archivo (veremos otras formas en Capítulo 9 ) es con la primitiva export-plot, que escribe todos los puntos de una gráfica a la vez en un archivo. Lea las entradas del Diccionario NetLogo para export-plot y word, y luego modifique la declaración que detiene el programa en 1000 ticks para que primero escriba el el contenido de la trama en un archivo. El nombre del archivo incluirá el valor de q, por lo que obtendrá diferentes archivos cada vez que cambie q. Utilice esta declaración: Ahora, con varias ejecuciones del modelo y un poco de trabajo en la hoja de cálculo, debería poder hacer análisis como figura 5.4 , que muestra cómo cambia el ancho del corredor con el tiempo para varios valores de q. Figura 5.4 Cómo cambia el ancho del corredor durante las simulaciones, para cinco valores de q. Cada línea se genera a partir de una ejecución de modelo. Nota de programación: Archivos CSV Cuando NetLogo "exporta" un archivo a través de parcela de exportación y otra exportar- primitivas, las escribe en un formato llamado valores separados por comas o .csv. Este formato de archivo se usa comúnmente para almacenar y transferir datos, y los archivos .csv se abren fácilmente con software de datos común, como aplicaciones de hojas de cálculo. Si no está familiarizado con el formato .csv, consulte, por ejemplo, el artículo de Wikipedia sobre valores separados por comas, o simplemente abra un archivo .csv en un procesador de texto o editor de texto para ver cómo se ve. El formato es muy simple: cada línea del archivo corresponde a un registro de datos (por ejemplo, una fila de una hoja de cálculo); los valores o campos están separados por comas y, opcionalmente, los valores pueden ir entre comillas dobles. En Capítulo 6 aprenderá a escribir sus propios archivos de salida en formato .csv. Los archivos .csv producidos por parcela de exportación y otras primitivas pueden causar confusión en las computadoras que usan comas como marcador decimal y punto y coma como delimitador de campo en archivos .csv (como hacen muchos europeos). Los archivos .csv producidos por NetLogo siempre usan comas para delimitar campos y puntos como marcador decimal. Si tiene este problema, puede resolverlo editando la salida para reemplazar "," con ";" y luego reemplace "." con ",". O puede cambiar temporalmente su computadora para usar formatos numéricos en inglés mientras importa su archivo de salida NetLogo a una hoja de cálculo u otro software de análisis. 5.5 Un paisaje real Ahora veremos qué sucede con el comportamiento de las mariposas y los pasillos virtuales cuando usamos un paisaje real y complejo. Importar topografías de paisajes reales (o cualquier otro dato espacial) en un programa NetLogo es sencillo, una vez que los datos están preparados para NetLogo. En el sitio web de este libro, proporcionamos un archivo de texto sin formato que puede importar a NetLogo y usar como paisaje. Este archivo (llamado ElevationData.txt) es de uno de los sitios donde Guy Pe'er llevó a cabo estudios de campo y análisis de modelos de movimientos de mariposas (Pe'er 2003; Pe'er et al. 2004, 2005). El archivo contiene la elevación media de parches de 25 metros. Nota de programación: Una forma sencilla de importar datos espaciales A continuación, se muestra una forma de importar datos espaciales basados en cuadrículas como variables de parche. Por "basado en cuadrículas", nos referimos a registros de datos que incluyen una coordenada x, una coordenada y y un valor variable (que podría ser la elevación o cualquier otra cosa que varíe en el espacio) para puntos o celdas espaciados uniformemente tanto en x como en y direcciones como los parches de NetLogo. La parte desafiante es transformar los datos para que se ajusten a los requisitos de NetLogo's World. Los datos reales se encuentran típicamente en sistemas de coordenadas (p. Ej., UTM) que no pueden ser utilizados directamente por NetLogo porque NetLogo requiere que las coordenadas del parche sean enteros y que el mundo incluya la ubicación 0,0. Las transformaciones se pueden realizar a través del código NetLogo a medida que se leen los datos, pero es más seguro hacerlo en un software, como una hoja de cálculo, que le permite ver y probar los datos antes de que entren en NetLogo. Estos pasos prepararán un archivo de entrada que proporciona el valor de una variable espacial para cada parche. (Se modifica fácilmente para leer varias variables de parche a la vez). La entrada espacial debe incluir una línea de datos para cada punto de cuadrícula o celda en un espacio rectangular. La línea de datos debe incluir la coordenada x, la coordenada y y el valor de la variable espacial para esa ubicación. NetLogo requiere que el punto 0,0 esté en el mundo. Es más fácil poner 0,0 en la esquina inferior izquierda identificando las coordenadas xey mínimas en los datos originales y luego restando sus valores de las coordenadas xey de todos los puntos de datos. Los parches de NetLogo están separados por una unidad de distancia, por lo que los datos deben transformarse para que los puntos estén separados exactamente por una unidad. Divida las coordenadas xey de cada punto por la resolución espacial (tamaño de la cuadrícula, la distancia entre puntos), en las mismas unidades en las que están los datos. Por ejemplo, si los puntos representan cuadrados de 5 metros de lado y el las coordenadas están en metros, luego divida las coordenadas xey entre 5. Como resultado, todas las coordenadas ahora deben ser números enteros, y las coordenadas de la cuadrícula deben comenzar en 0 y aumentar en 1. Guarde los datos como un archivo de texto sin formato. En la ventana Configuración del modelo de NetLogo, configure las dimensiones para que coincidan con las de su conjunto de datos (o, en el procedimiento de configuración, utilice la primitiva resize-world). Desactive la envoltura del mundo (al menos temporalmente) para que NetLogo le diga si uno de los puntos en el archivo de entrada está fuera de la extensión del mundo. Coloque el archivo de datos espaciales (aquí, ElevationData.txt) en el mismo directorio como su programa NetLogo. (Consulte el archivo de usuario primitivo para ver una alternativa). Use un código como este (que asume que está leyendo datos de elevación) en su procedimiento de configuración: La instrucción ask patch simplemente le dice al parche correspondiente a la ubicación que acaba de leer del archivo (ver parche primitivo) que establezca su elevación en el valor de elevación recién leído del archivo. (Si espera usar datos espaciales de manera extensiva, eventualmente debería familiarizarse con la extensión GIS de NetLogo; consulte la sección 24.5). Cree una nueva versión de su modelo y cambie su procedimiento de configuración para que se lea en elevaciones del archivo ElevationData.txt. (Por qué deberías no coloque el nuevo código para leer el archivo y establezca las elevaciones del parche dentro del ¿antigua pregunta sobre parches [] declaración?) Mire el archivo de datos de elevación para determinar qué dimensiones debería tener su mundo. Cambie la declaración que sombrea los parches por su elevación para que el color se escale entre las elevaciones mínima y máxima. (Ver las primitivas max y min.) Cuando probamos el programa ahora con el paisaje real, nos damos cuenta de que la regla que hace que las mariposas dejen de moverse cuando llegan a la cima de una colina fue quizás buena para cuantificar el ancho del corredor en un paisaje artificial, pero en este paisaje real hace que las mariposas se atasquen rápidamente. colinas locales. Es más interesante ahora utilizar el modelo original de Pe'er et al. (2005) y dejar que los individuos sigan moviéndose durante 1000 garrapatas incluso después de llegar a la cima de una colina. Comente la declaración que hace que las mariposas se detengan si están en la cima de una colina local. También es posible que queramos dejar que nuestras mariposas partan no de un solo parche, sino de una pequeña región. En el bloque crt, asigne valores aleatorios xcor e ycor que estén dentro de un pequeño cuadrado de 10 por 10 parches, ubicado en el lugar que elija. El mundo modelo ahora debería verse como figura 5.5 , en el que 50 individuos comienzan en un pequeño cuadrado y luego se mueven por 1000 pasos de tiempo con q establecido en 0,4. Figura 5.5 Topografía de un paisaje real que muestra (izquierda) las ubicaciones de inicio de las mariposas (x inicial varía 100-109; y es 130-139) y (derecha) corredores virtuales que emergen del comportamiento del movimiento y la topografía con q = 0.4. 5.6 Resumen y conclusiones El título de este capítulo promete llevarlo de usar NetLogo solo para animaciones simples a hacer ciencia basada en agentes, pero por supuesto, solo dimos algunos primeros pasos: modelar un sistema de múltiples agentes, agregar observaciones cuantitativas que podemos analizar, comenzando utilizar experimentos de simulación y utilizar datos espaciales reales. Sin embargo, continuaremos desarrollando tales habilidades para hacer ciencia con ABM durante el resto del libro. El modelo Butterfly es extremadamente simple, pero ya requiere algunas decisiones difíciles; hay, por ejemplo, varias formas diferentes de definir los anchos de ruta y los tamaños de corredor, que probablemente producirían diferentes resultados. Por tanto, es importante que aprenda a analizar modelos simples antes de pasar a modelos más complejos. Una de las razones por las que el modelo Butterfly es bueno para empezar es que personas de todas las disciplinas pueden entenderlo, a pesar de que se ha utilizado en investigaciones ecológicas serias (Pe'er et al. 2004, 2005, 2006). Pero recuerde que los ABM y NetLogo no se limitan a organismos que se mueven a través de paisajes. Se pueden usar casi exactamente las mismas técnicas y códigos para modelar tipos muy diferentes de agentes (personas, organizaciones, ideas ...) que se mueven a través de muchos tipos de "espacios" (paisajes políticos o económicos, redes sociales, etc.), y NetLogo puede modelar agentes que interactúan sin moverse en absoluto. 5.7 Ejercicios 1. Implementar las nuevas versiones del modelo Butterfly que presentamos en este capítulo. 2. Las huellas dejadas por las tortugas en su modo de "pluma abajo" son útiles para ver su camino, pero dificultan ver la ubicación final de las tortugas. Cree un nuevo botón en la interfaz de uno de sus modelos de mariposa que borre estos rastros. (Sugerencia: para mover y dibujar, a menudo hay un elemento primitivo que hace exactamente lo que usted quiere). 3. ¿Su versión del modelo de la sección 5.2 produce el resultado de que el ancho del corredor es menor que 1.0 cuando q es 1.0? ¿Cómo puede ser esto? (Pista: hay dos razones. Observa cómo se mueven las mariposas, piensa en cómo se representa el espacio y asegúrate de entender cómo el primitivo la distancia funciona.) 4. Intente ejecutar el modelo Butterfly con las mariposas todas comenzando en una esquina del espacio. Recuerde que tenemos el ajuste del mundo desactivado, por lo que el modelo se detendría e informaría un error si una tortuga intentara cruzar el borde del mundo. ¿Por qué las mariposas no cruzan el borde y salen del mundo, causando un error, sin importar cuán bajo sea el valor de q ¿tu usas? 5. Usando la versión del modelo con un paisaje real, varíe el parámetro q y vea cómo afecta la interacción entre el paisaje y el movimiento de las mariposas. Inicie las mariposas en varios lugares. Con solo mirar la vista, ¿qué valor de q parece mejor para encontrar pareja en las colinas o cerca de ellas?