Simulación Basada en Agentes · Tema 01

¿Qué es la simulación basada en agentes?

El paradigma bottom-up: poblar un mundo con agentes que perciben, deciden y actúan, y observar qué orden colectivo emerge sin que nadie lo ordene.

01 · Punto de partida

Lo colectivo empieza por individuos

Un embotellamiento, una ola de contagios, un barrio segregado o una bandada de pájaros tienen algo en común: nadie los dirige desde arriba. Son el resultado de muchos individuos tomando decisiones locales al mismo tiempo.

La simulación basada en agentes (ABM, del inglés agent-based modeling) nace de esa idea: en lugar de escribir una ecuación para el tránsito, el contagio o el mercado, programamos a cada agente —cada auto, persona o pájaro— y dejamos que el fenómeno aparezca solo.

  • ¿Quiénes son los individuos de este sistema?
  • ¿Qué ve cada uno y qué regla usa para decidir?
  • ¿En qué espacio se mueven e interactúan?
  • ¿Qué patrón global esperamos ver emerger?

02 · Definición

Agentes, entorno e interacciones

Todo modelo basado en agentes combina cuatro piezas mínimas, que recorreremos en todo el curso:

◉

Agentes

Entidades autónomas con estado propio que perciben, deciden y actúan. Ejemplo: cada persona, auto o celda.

▦

Entorno

El mundo donde viven: rejilla discreta o espacio continuo, con recursos, bordes y obstáculos.

⇄

Interacción + tiempo

Encuentros agente-agente y agente-entorno, actualizados paso a paso con un reloj de simulación.

El ciclo es siempre el mismo: percibir → decidir → actuar. Cada agente mira a sus vecinos y su entorno, aplica su regla y se mueve o cambia de estado. Repetimos eso cientos de pasos y medimos lo que aparece.

La misma lógica bottom-up sirve en dominios muy distintos.
FenómenoAgentesRegla local típica
TránsitoAutosSi el de adelante frena, freno y mantengo distancia.
EpidemiaPersonasSi un vecino está enfermo, me contagio con probabilidad p.
SegregaciónFamiliasSi pocos vecinos son como yo, me mudo.
BandadaPájarosVuelo al rumbo promedio de mis vecinos cercanos.

03 · Ubicación

¿En qué se diferencia de otros enfoques?

ABM no reemplaza a los demás paradigmas: elige cuándo conviene pensar en individuos.

Frente a ecuaciones agregadas

Modelos continuos

Una ecuación describe promedios (infectados totales). ABM describe a cada persona: permite heterogeneidad, espacio y azar individual.

Frente a eventos discretos

Colas y eventos

La simulación de eventos salta de evento en evento en un sistema centralizado. ABM avanza por pasos con muchos decisores descentralizados.

04 · Ejemplos

Un mismo molde, muchos mundos

Todos estos modelos comparten el molde percibir → actuar sobre vecinos y espacio:

Agentes→Vecinos + espacio→Patrón emergente
  1. 1
    Juego de la Vida.

    Celdas-agentes que nacen, sobreviven o mueren según vecinas vivas. Aparecen naves y osciladores.

  2. 2
    Schelling.

    Agentes que solo piden un 30 % de vecinos parecidos terminan creando barrios totalmente segregados.

  3. 3
    Contagio.

    Personas que se mueven y contagian a vecinas cercanas generan olas epidémicas.

  4. 4
    Tráfico.

    Autos que aceleran y frenan según distancia producen embotellamientos fantasma sin accidente.

  5. 5
    Multitud.

    Peatones que buscan la salida y evitan choques forman carriles y arcos en la puerta.

05 · Representación en Python

Un agente es un diccionario, un mundo es una lista

En Python, el punto de partida más simple es representar cada agente con un diccionario (posición y estado) y la población con una lista. Todavía no hay entorno elegante: solo datos.

Python en tu navegador. Los bloques de esta página se ejecutan localmente con Pyodide, sin instalar nada. La primera ejecución tarda unos segundos; las siguientes son inmediatas. Podés editar el código y volver a ejecutarlo.

import random
random.seed(1)

agentes = [
    {"id": i, "x": random.random(), "y": random.random(), "estado": "sano"}
    for i in range(5)
]

for a in agentes:
    print(a["id"], round(a["x"], 2), round(a["y"], 2), a["estado"])

Consejo: cambiá la semilla o la cantidad de agentes y observá que ya obtuviste una población inicial distinta (Tema 40).

El corazón de ABM: el bucle por pasos

Simular es repetir percibir → decidir → actuar. Aquí cada agente da un pasito al azar (caminata aleatoria) y el entorno es un cuadrado con bordes que rebotan:

import random
random.seed(7)

def paso(agentes, velocidad=0.05):
    for a in agentes:
        a["x"] += random.uniform(-velocidad, velocidad)
        a["y"] += random.uniform(-velocidad, velocidad)
        # Bordes: el entorno devuelve al agente al mundo
        a["x"] = min(1.0, max(0.0, a["x"]))
        a["y"] = min(1.0, max(0.0, a["y"]))

poblacion = [{"id": i, "x": 0.5, "y": 0.5} for i in range(3)]
for t in range(4):
    paso(poblacion)
    print(t + 1, [(round(a["x"], 2), round(a["y"], 2)) for a in poblacion])

06 · Exploración

Laboratorio: encuentros que nadie ordenó

Movete los controles: N agentes caminan al azar durante T pasos. Cuando dos quedan cerca, dibujamos un enlace: es un encuentro. Nadie busca agruparse, pero aparecen grupos igual. Esa es la emergencia en su forma mínima.

EXPERIMENTO 01

Caminata aleatoria + encuentros

percibir → mover → encontrar

Los resultados numéricos aparecen debajo.
Réplica#1
Encuentros0
Agentes con vecinos0 %
LecturaDispersos

Con 60 agentes y 40 pasos, contamos los pares cercanos.

Cada punto es un agente. Las líneas unen pares a menos del radio de encuentro. Los agentes amarillos tienen al menos un vecino; los azules están aislados. Pulsá Nueva réplica: mismos parámetros, historia distinta.

Preguntas para explorar

  1. Dejá fijos los pasos y duplicá los agentes. ¿Los encuentros crecen al doble o mucho más? ¿Por qué?
  2. Poné 0 pasos y luego 100. ¿El azar inicial o el movimiento genera más encuentros?
  3. Pulsá Nueva réplica varias veces con los mismos valores. ¿El número de encuentros es idéntico? ¿Qué implica para experimentar?
Ver respuestas sugeridas
  1. Crecen mucho más que al doble: los pares posibles crecen con N². Pequeños aumentos de densidad disparan la interacción: no linealidad.
  2. Con 0 pasos solo ves el azar inicial. Con movimiento, los agentes exploran y los encuentros cambian: el tiempo crea oportunidades de interacción.
  3. No: cada réplica da un valor distinto. Por eso ABM exige ejecuciones múltiples y promedios, no una sola corrida (Temas 42–43).

07 · Comprensión

Confusiones frecuentes

«ABM es solo animar puntitos»

La animación ayuda a intuir, pero el modelo es la regla + el experimento con réplicas y métricas. Sin medición de lo emergente, solo hay un dibujo bonito.

«Más agentes siempre es mejor»

Más agentes cuestan tiempo y memoria y pueden tapar el mecanismo. Primero entendé el modelo con pocos agentes; después escalá (Temas 46–47).

«Si programé la regla, programé el resultado»

No: programaste lo local, pero lo global te sorprende. Esa es la gracia y el peligro: hay que medir lo emergente en lugar de suponerlo.

«Una corrida alcanza»

ABM suele llevar azar (posiciones, orden, decisiones). Una sola corrida es una anécdota: hacen falta réplicas para separar señal de ruido.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: crear la población

Ejecutá este código que crea 100 agentes sanos y cuenta cuántos hay. Luego cambiá el estado inicial de 5 a “enfermo”.

import random
random.seed(2)

poblacion = [{"id": i, "x": random.random(), "y": random.random(), "estado": "sano"} for i in range(100)]
poblacion[0]["estado"] = "enfermo"

sanos = sum(1 for a in poblacion if a["estado"] == "sano")
print("total:", len(poblacion), "sanos:", sanos)
Ver solución razonada

Hay 100 agentes y 99 sanos. El paciente cero es el agente 0. Este es el paso de inicialización: misma regla, distinto punto de partida, distinta historia.

Ejercicio 2: mover a todos un paso

Sin ejecutar primero: si todos parten de (0.5, 0.5) y la velocidad es 0, ¿dónde terminan tras 10 pasos? Comprobalo después.

import random
random.seed(3)

def paso(agentes, velocidad=0.05):
    for a in agentes:
        a["x"] = min(1.0, max(0.0, a["x"] + random.uniform(-velocidad, velocidad)))
        a["y"] = min(1.0, max(0.0, a["y"] + random.uniform(-velocidad, velocidad)))

grupo = [{"x": 0.5, "y": 0.5} for _ in range(4)]
for _ in range(10):
    paso(grupo, velocidad=0.0)
print([(a["x"], a["y"]) for a in grupo])
Ver solución

Todos siguen en (0.5, 0.5): con velocidad 0 la regla no mueve a nadie. Parece trivial, pero es tu primer experimento controlado: un parámetro en cero aísla el efecto del movimiento.

Ejercicio 3: contar encuentros

Dos agentes se “encuentran” si su distancia es menor que 0.1. Completá mentalmente y ejecutá: ¿hay encuentro entre (0.1, 0.1) y (0.15, 0.12)?

Ver una posible respuesta
import math

def hay_encuentro(a, b, radio=0.1):
    d = math.hypot(a["x"] - b["x"], a["y"] - b["y"])
    return d < radio

a = {"x": 0.1, "y": 0.1}
b = {"x": 0.15, "y": 0.12}
print(hay_encuentro(a, b))

Sí: la distancia es ≈ 0.054, menor que 0.1. Esta función es tu primer sensor: el modo en que un agente percibe a sus vecinos (Tema 11).

09 · Síntesis

Ideas para recordar

  • ABM modela individuos con reglas locales; el fenómeno colectivo emerge de la interacción.
  • Sus piezas son agentes, entorno, interacciones y tiempo por pasos.
  • Conviene cuando hay heterogeneidad, espacio e interacción descentralizada.
  • En Python, una población es una lista de agentes y simular es repetir percibir → decidir → actuar.
  • El azar obliga a correr réplicas y medir: una sola corrida no prueba nada.

En el próximo tema estudiaremos el concepto de agente: autonomía, estado y qué lo distingue de un simple objeto o variable.