01 · Punto de partida
El orden también es una regla
Hasta ahora movíamos, percibíamos y contagiábamos sin preguntar en qué orden cambian los agentes. Pero si el agente 1 contagia al 2 y el 2 ya contagia al 3 en la misma ronda, el rumor cruza el mapa a velocidad infinita. El orden de actualización decide qué ve cada uno.
La actualización síncrona congela el truco: todos deciden sobre la foto del inicio y recién después cambian juntos. Nadie ve cambios de esta ronda hasta la próxima.
- ¿Sobre qué foto decide cada agente: inicio o mitad de ronda?
- ¿Cuándo se aplican los cambios: uno por uno o todos juntos?
- ¿La oleada avanza uno por ronda o cruza todo de golpe?
- ¿Dónde se guardan los nuevos estados sin pisar los viejos?
02 · Definición
Foto, cálculo y aplicación
Toda ronda síncrona separa leer de escribir en tres fases indivisibles:
Foto
El estado t congelado: posiciones, salud, opiniones al abrir la ronda. Nadie lo toca mientras se decide.
Cálculo
Cada agente aplica su regla sobre la foto y anota su futuro en un buffer aparte, sin publicar.
Aplicación
El reloj vuelca todos los futuros a la vez: el mapa salta de t a t+1 de un golpe parejo.
| Mundo | Foto t | Salto a t+1 |
|---|---|---|
| Vida | vecinos vivos al abrir | nace, sobrevive o muere a la vez |
| Contagio | infectados al abrir | la ola avanza un vecino por ronda |
| Opiniones | promedio vecinal al abrir | todos corrigen juntos sin ventaja |
| Tráfico celular | celdas ocupadas al abrir | avanzan en paralelo sin chocar |
03 · Doble buffer
Síncrona que congela frente a in-place que encadena
Actualizar sobre el mismo arreglo parece más rápido: es otro modelo. El de adelante ve el futuro y corre con ventaja.
Síncrona con buffer
Reloj parejo
Se lee viejos y se escribe nuevos: nuevos[i] = f(viejos). La ola avanza un paso por ronda, reproducible y justa.
In-place sin querer
Ventaja del primero
Se lee y escribe el mismo arreglo: el agente 30 ve contagios de esta ronda que el 1 no vio. La ola cruza todo de golpe según el orden.
- Generación
- Foto completa del sistema en t. La ronda síncrona transforma una generación en la siguiente sin estados mixtos.
- Doble buffer
- Dos arreglos: se lee el viejo y se escribe el nuevo, luego se intercambian. La técnica que garantiza lo síncrono.
- Reloj global
- Señal que vuelca todos los cambios juntos. En la realidad rara vez existe: es una idealización útil y declarada.
- Artefacto de orden
- Patrón falso creado por el orden de actualización, no por las reglas. Cambia al mezclar y delata el bug.
04 · Ciclo
La ronda que congela el tiempo
Cada generación se construye sin pisar la anterior, en este orden:
- 1Fotografiar.
Congelar estados y vecindarios de t: esa foto no cambia durante la ronda.
- 2Calcular futuros.
Cada agente aplica su regla sobre la foto y guarda su nuevo estado en el buffer.
- 3Aplicar juntos.
Volcar el buffer sobre el mapa: todos saltan a t+1 al mismo tick.
05 · Representación en Python
Dos listas: se lee una, se escribe otra
El error clásico es escribir sobre lo que se lee. La versión correcta calcula todo en nuevos y recién después reemplaza.
Python en tu navegador. Compará el contagio parejo contra el que se dispara por actualizar en el lugar.
# MAL: in-place encadena contagios en la misma ronda
cadena = [True, False, False, False]
for i in range(1, len(cadena)):
if cadena[i - 1]:
cadena[i] = True
print(cadena)
Da 4 contagiados en 1 ronda: el 2 contagió al 3 con un estado que nació esta misma ronda. Velocidad infinita por bug.
Bien con doble buffer
Se lee viejos y se escribe nuevos: la ola avanza un vecino por ronda.
viejos = [True, False, False, False]
nuevos = viejos[:]
for i in range(1, len(viejos)):
if viejos[i - 1]:
nuevos[i] = True
print(nuevos)
06 · Exploración
Laboratorio: la ola que avanza de a un paso
Los agentes forman un anillo: cada uno mira a sus dos vecinos. Empiezan unos pocos activos (amarillo) y en cada ronda síncrona cada vecino de un activo se activa. La ola avanza exactamente un eslabón por lado y por ronda. Nada se adelanta.
El reloj parejo frena la prisa
nuevo(t+1) = f(vecinos(t))
Con 30 agentes y 1 foco, la ola avanza pareja.
Cada punto del anillo es un agente: amarillo activo, verde aún no. El anillo se cierra sobre sí mismo: el último es vecino del primero. Pulsá Nueva réplica para otros focos iniciales.
Preguntas para explorar
- Con 0 rondas, ¿cuántos activos hay? ¿Por qué sin ticks no hay contagio aunque haya focos?
- Con 1 foco y 8 rondas en anillo de 30, ¿cuántos activos esperás con avance de a 2 por ronda? Comprobalo.
- Si actualizara in-place en orden, ¿la ola avanzaría igual? ¿Qué delata al artefacto de orden?
Ver respuestas sugeridas
- Solo los focos: la foto inicial no se transforma sola. El contagio exige rondas de calcular y aplicar.
- 17: el foco más 2 por ronda y por lado (8 × 2 + 1). La cuenta pareja es la firma de lo síncrono.
- No: cruzaría el anillo en 1 ronda porque cada nuevo contagia al siguiente en el mismo barrido. Avanzar más de un vecino por ronda delata el in-place.
07 · Comprensión
Confusiones frecuentes
«Síncrono es recorriendo en orden»
Recorrer en orden y escribir ahí mismo es secuencial asíncrono. Síncrono es calcular todo sobre la foto y volcar junto al final.
«El buffer duplica memoria sin motivo»
Duplica para no mentir: sin copia el pasado se pisa y la ola corre de más. Es el costo de la justicia temporal.
«Da igual si la ola corre un poco más»
La velocidad de la ola es el resultado: epidemias, rumores y tráficos se juzgan por cuántos por ronda. Correr de más invalida la comparación.
«Síncrono es siempre lo realista»
Es una idealización con reloj global que la realidad rara vez tiene. Se elige por justicia y reproducibilidad, y se declara (Tema 17 discute la alternativa).
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: contar la ola parejo
Ejecutá la versión con buffer y verificá que avanza de a uno. Luego quitá el buffer y compará.
viejos = [True, False, False, False, False]
for ronda in range(2):
nuevos = viejos[:]
for i in range(1, len(viejos)):
if viejos[i - 1]:
nuevos[i] = True
viejos = nuevos
print(viejos)
Ver solución razonada
Tras 1 ronda hay 2 activos y tras 2 hay 3: un vecino por ronda. Sin buffer la primera ronda ya daría 5: toda la cadena de golpe.
Ejercicio 2: predecir el anillo
Sin ejecutar primero: anillo de 6 con foco en 0, avance a vecinos por ronda síncrona. ¿Activos tras 1 ronda?
n = 6
viejos = [i == 0 for i in range(n)]
nuevos = viejos[:]
for i in range(n):
if viejos[(i - 1) % n] or viejos[(i + 1) % n]:
nuevos[i] = True
print(sum(nuevos))
Ver solución
Hay 3 activos: el foco y sus dos vecinos. La simetría del anillo es la huella del vuelco parejo.
Ejercicio 3: promediar sin ventaja
Tres opiniones 0, 10 y 20 en anillo que promedian con vecinos síncronos. ¿Qué valor toma el del medio?
Ver una posible respuesta
viejos = [0, 10, 20]
nuevo = sum(viejos) / len(viejos)
print(nuevo)
Da 10.0 leyendo la foto: si leyera valores ya actualizados de esta ronda, el promedio se sesgaría al primero.
09 · Síntesis
Ideas para recordar
- Síncrona es fotografiar, calcular y aplicar: todos leen t y escriben t+1 juntos.
- El doble buffer separa leer de escribir: viejos intactos hasta el vuelco.
- La ola avanza un vecindario por ronda: más velocidad delata in-place.
- El orden no da ventajas: la justicia temporal es reproducible.
- En Python, nuevos se calcula desde viejos y reemplaza al final del tick.
En el próximo tema estudiaremos la actualización asíncrona: turnos aleatorios o secuenciales.