Simulación Basada en Agentes · Tema 10

Comunicación entre agentes

De chocarse a avisarse: mensajes que viajan más lejos que el cuerpo y coordinan sin jefe.

01 · Punto de partida

Chocar no es avisar

En el Tema 9 dos agentes se encontraban y se influían en el acto: contagio, freno, copia. Pero ¿y si el otro ya se fue? ¿Y si quiero avisar a quien está lejos? La comunicación separa el mensaje del encuentro: emito ahora, otro lo lee después, acá o allá.

Esa separación funda la coordinación: alarmas, precios, rumores y feromonas permiten actuar juntos sin estar juntos. El precio es nuevo: el mensaje puede perderse, llegar tarde o mentir.

  • ¿Quién le avisa a quién y por qué canal?
  • ¿El mensaje va directo al otro o queda en el mundo?
  • ¿Llega siempre, a tiempo y sin ruido?
  • ¿Qué hace el receptor cuando lo recibe?

02 · Definición

Mensaje, canal y momento

Todo aviso combina qué se dice, por dónde viaja y cuándo se lee:

✉

Mensaje

El contenido con intención: alarma, precio, opinión, orden. Sin receptor que lo interprete es ruido.

➔

Directa

De agente a agente: grito dentro del radio, carta a un destinatario. Rápida y frágil si se alejan.

▣

Indirecta

Por el mundo: feromona, reseña, tablón de precios. El emisor y el lector nunca se cruzan: estigmergia.

El mismo esquema en cada dominio.
MundoMensaje directoMensaje indirecto
Hormiguerotoque de antenasrastro de feromona que se evapora
Mercadoregateo cara a caraprecio publicado en el tablón
Multitudgrito de alarmahuella y densidad que otros leen
Opinionescharla con el vecinoreseña que queda escrita

03 · Canales

Rápido y frágil frente a lento y persistente

Elegir el canal es elegir qué falla: el grito se pierde con la distancia, el tablón se desactualiza con el tiempo.

Canal directo

Boca en boca

Solo escucha quien está dentro del radio en esa ronda: si dist < radio → recibe. Veloz en grupos densos, inútil con agentes aislados.

Canal indirecto

Tablón en el mundo

El emisor publica y se va; el lector lee tarde y lejos. Persiste pero envejece: hay que poner fecha y evaporar.

Mensaje
Paquete con emisor, contenido y ronda: quién avisa qué y cuándo. Sin ronda no se sabe si es noticia o historia.
Canal
Medio con alcance y fallas: radio de escucha, probabilidad de pérdida, retardo. Todo canal pierde algo.
Ruido
Pérdida o distorsión: el mensaje no llega o llega cambiado. Se modela con probabilidad de éxito por intento.
Tablón
Memoria compartida del entorno donde se publica y se lee (Tema 8). Desacopla en tiempo y espacio.

04 · Ciclo

El paso con mensajes

Cada ronda emite, transmite y recién después actualiza a los receptores, en este orden:

emitir→transmitir→recibir
  1. 1
    Emitir.

    Quienes saben generan el mensaje con su ronda de emisión.

  2. 2
    Transmitir.

    El canal entrega a vecinos en radio o publica en el tablón, con pérdidas y retardos.

  3. 3
    Recibir.

    Los receptores actualizan su estado solo al inicio de la próxima ronda: nadie reenvía lo que aún no leyó.

05 · Representación en Python

Buzones que se llenan por rondas

El agente guarda lo que sabe y un buzón con lo que le llegó. Enviar es poner un mensaje en el buzón ajeno; recibir es vaciarlo.

Python en tu navegador. Cambiá el radio y observá quién escucha y quién queda aislado.

import math

class Agente:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.sabe = False
        self.buzon = []

def al_alcance(a, b, radio=0.2):
    return math.hypot(a.x - b.x, a.y - b.y) < radio

a = Agente(0.2, 0.2); a.sabe = True
b = Agente(0.3, 0.25)
c = Agente(0.9, 0.9)
print(al_alcance(a, b), al_alcance(a, c))

Con radio 0,2, b escucha (True) y c queda fuera (False): el alcance dibuja quién se entera.

Emitir y recibir en dos fases

Primero todos emiten a sus vecinos, después todos leen: nadie reenvía en la misma ronda lo recién recibido.

import random

def ronda(agentes, radio=0.2, p=0.85):
    envios = []
    for i, e in enumerate(agentes):
        if e.sabe:
            for j, r in enumerate(agentes):
                if not r.sabe and al_alcance(e, r, radio) and random.random() < p:
                    envios.append(j)
    for j in set(envios):
        agentes[j].buzon.append("aviso")
    for ag in agentes:
        if ag.buzon:
            ag.sabe = True
            ag.buzon.clear()
    return len(set(envios))

agentes = [Agente(0.2, 0.2), Agente(0.3, 0.25), Agente(0.9, 0.9)]
agentes[0].sabe = True
print(ronda(agentes), [ag.sabe for ag in agentes])

06 · Exploración

Laboratorio: boca en boca por radio

Los agentes están quietos: solo viaja el aviso. Empieza uno solo informado (amarillo). En cada ronda, cada informado avisa a sus vecinos dentro del radio con éxito del 85 %. Las líneas son avisos de la última ronda. ¿Cuántas rondas necesita el rumor para cubrir el mapa?

EXPERIMENTO 10

El aviso viaja más lejos que el cuerpo

si dist < radio → recibe con p = 0,85

Los resultados numéricos aparecen debajo.
Informados0 %
Avisos0
Aislados0
LecturaChisme

Con 40 agentes y radio 0,20, el aviso cubre una parte.

Cada punto es un agente fijo: amarillo informado, verde aún no. Las líneas grises son avisos exitosos de la última ronda. Pulsá Nueva réplica para otra disposición con los mismos parámetros.

Preguntas para explorar

  1. Con 0 rondas, ¿cuántos informados hay? ¿Por qué sin rondas no hay comunicación aunque haya canal?
  2. Con radio mínimo y 40 agentes, ¿cuántos quedan aislados? ¿Qué cambia si duplicás los agentes sin tocar el radio?
  3. Repetí la misma configuración 3 veces. ¿El porcentaje final es idéntico? ¿Qué parte es canal y qué parte es mapa?
Ver respuestas sugeridas
  1. Solo el inicial: el canal existe pero nadie emitió. Comunicar exige emitir y dar tiempo a transmitir.
  2. Muchos: con radio chico solo hablan los amontonados. Duplicar agentes densifica el mapa y crea puentes donde antes había silencio.
  3. No: la disposición inicial y las pérdidas del 15 % cambian cada historia. El canal (radio y p) es fijo; el mapa y la suerte no.

07 · Comprensión

Confusiones frecuentes

«Avisar es lo mismo que influir»

Influir cambia el estado en el encuentro; avisar deja un mensaje que el otro puede ignorar, olvidar o malinterpretar. Recibir no obliga a obedecer.

«El mensaje llega a todos al instante»

Eso es un jefe encubierto, no comunicación. Todo aviso tiene alcance, rondas y pérdidas: si es global e instantáneo, el modelo miente.

«Reenviar en la misma ronda acelera»

Acelera y falsea: el rumor cruza el mapa en una ronda porque nadie esperó su turno. Emitir y recibir van en fases separadas.

«Directo e indirecto son intercambiables»

El directo necesita coincidir en tiempo; el indirecto necesita un tablón que envejece. Uno falla por distancia, el otro por desactualización.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: quién escucha

Ejecutá y verificá quién está al alcance. Luego achicá el radio a 0,05 y comprobá que el vecino deja de escuchar.

import math
emisor = (0.2, 0.2)
vecinos = [(0.3, 0.25), (0.9, 0.9)]
radio = 0.2
for v in vecinos:
    d = math.hypot(emisor[0] - v[0], emisor[1] - v[1])
    print(v, d < radio)
Ver solución razonada

Solo (0.3, 0.25) escucha: está a ~0,11 < 0,2. Con radio 0,05 ninguno escucha: el canal se cierra por distancia.

Ejercicio 2: predecir el retardo

Sin ejecutar primero: A sabe, B no sabe y está en radio, C lejos de ambos. Tras una ronda con p = 1, ¿quién sabe? ¿Y tras dos rondas?

sabe = {"A": True, "B": False, "C": False}
# ronda 1: A -> B sí, A -> C no (lejos). B recibe al final.
sabe["B"] = True
print(sabe)
# ronda 2: B intenta con C pero sigue lejos
print(sabe)
Ver solución

Tras la ronda 1: A y B saben, C no. Tras la ronda 2: igual, porque C está fuera de todo radio. Sin puente no hay rumor.

Ejercicio 3: tablón que envejece

Un precio publicado en la ronda 2 se lee en la ronda 9. Si vence a las 3 rondas, ¿vale? Escribí la condición.

Ver una posible respuesta
emitida = 2
leida = 9
vigencia = 3
vale = (leida - emitida) <= vigencia
print(vale)

Da False: pasaron 7 rondas y solo vale 3. El tablón necesita fecha y evaporación, como la feromona del Tema 8.

09 · Síntesis

Ideas para recordar

  • Comunicar es emitir, transmitir y recibir: el mensaje viaja y puede perderse.
  • Directa necesita coincidir en tiempo y radio; indirecta usa el mundo y desacopla, pero envejece.
  • Todo canal tiene alcance, retardo y ruido: global e instantáneo es un jefe encubierto.
  • Se emite primero y se recibe después: nadie reenvía en la misma ronda.
  • En Python, enviar es llenar un buzón ajeno y recibir es vaciarlo con su ronda.

En el próximo tema estudiaremos la percepción: lo que cada agente puede ver de su mundo antes de decidir.