Modelos y Simulación · Tema 33

Ejecución de la simulación

Corridas, control del tiempo y registro de datos: poner el plan en marcha sin perder ni contaminar evidencia.

01 · Punto de partida

Del plan a la pista

En el Tema 32 escribimos el plan: qué escenarios, cuántas réplicas y en qué orden. En el Tema 31 dejamos el motor listo. Ejecutar es juntarlos: lanzar cada corrida con su escenario y su semilla, controlar cuánto tiempo simulado corre cada una y guardar lo necesario para analizar después.

Parece trámite, pero aquí se arruinan muchos estudios: corridas que arrancan con restos de la anterior, promedios contaminados por el arranque en vacío y resultados que nadie puede rastrear hasta el escenario que los produjo.

  • ¿Cuánto tiempo simulado corre cada corrida?
  • ¿Qué parte del arranque se descarta como transitorio?
  • ¿Cada corrida arranca limpia y aislada?
  • ¿Qué se guarda de cada corrida y con qué traza?

02 · Vocabulario mínimo

Corrida, horizonte y registro

▶

Corrida

Una ejecución del simulador con un escenario y una semilla: la unidad mínima de evidencia.

◷

Horizonte

Cuánto tiempo simulado se corre: pasos fijos, fecha de fin o condición de corte.

▤

Registro

Lo que se guarda: métricas compactas más traza (escenario, semilla, versión, estado).

Qué se guarda de cada corrida.
QuéEjemploPara qué sirve
MétricasEspera promedio desde t = 20Comparar escenarios
TrazaEscenario, semilla, versión, horizonteRepetir la corrida idéntica
Estado finalOK, falló, recortada por corteNo mezclar éxitos con accidentes
Historia resumidaSerie o muestra, no todo crudoAuditar sin llenar el disco

03 · Tres controles

Tiempo, aislamiento y registro

  1. 1
    Tiempo.

    Fijá horizonte, warm-up y condición de corte antes de correr. El arranque en vacío no representa el régimen.

  2. 2
    Aislamiento.

    Cada corrida arranca limpia: estado reiniciado, generador propio, sin archivos compartidos a medio escribir.

  3. 3
    Registro.

    Guardá métricas + traza en el mismo acto. El resultado sin su escenario y su semilla es un huérfano.

Guardar todo crudo

Pesado e inmanejable

Cada paso de cada corrida al disco. Auditable en teoría, impagable en la práctica: gigabytes que nadie vuelve a leer.

Métricas + traza

Liviano y repetible

Se guarda lo compacto y lo que permite regenerar el resto. Menos disco, misma evidencia, réplica exacta si hace falta.

Horizonte
Tiempo simulado que dura la corrida: pasos, fecha o condición de fin.
Warm-up
Tramo inicial que se corre pero no se mide, para salir del arranque artificial.
Condición de corte
Regla de parada anticipada: vaciado, tope, presupuesto de cómputo.
Traza
Ficha de la corrida: escenario, semilla, versión, horizonte y estado final.

04 · Protocolo

La coreografía de cada corrida

Inicializar→Calentar→Medir→Cerrar→Guardar

Inicializar con escenario y semilla propios; calentar sin medir; medir en régimen; cerrar con estado explícito (OK o motivo de corte); guardar métricas con su traza. El Tema 34 analizará esos registros; el Tema 41 exigirá repetirlos.

05 · En Python

Correr con warm-up y traza

La corrida simula el horizonte completo pero mide solo desde el warm-up. Así el transitorio no contamina la métrica:

Python en tu navegador. Horizonte, descarte y registro con stdlib puro.

import random

def corrida(n0, entradas, salida, semilla, warmup=0):
    rng = random.Random(semilla)  # azar propio y aislado
    n = n0
    historia = []
    for e in entradas:
        ruido = rng.choice([-1, 0, 1])
        n = max(n + e + ruido - salida, 0)
        historia.append(n)
    medida = historia[warmup:]
    return {"semilla": semilla, "media": sum(medida) / len(medida),
            "historia": historia, "estado": "OK"}


print(corrida(0, [3] * 10, 2, semilla=7, warmup=3))

El lote ejecuta el plan entero

El lote recorre las corridas del Tema 32, atrapa fallos con estado explícito y devuelve una tabla lista para analizar:

def lote(corridas, horizonte=10):
    tabla = []
    for c in corridas:
        try:
            r = corrida(0, [3] * horizonte, 2, c["semilla"], warmup=3)
            tabla.append({"escenario": c["escenario"], **r})
        except Exception as e:
            tabla.append({"escenario": c["escenario"], "estado": f"FALLO: {e}"})
    return tabla


plan = [{"escenario": (1, "alta"), "semilla": 7000},
        {"escenario": (2, "alta"), "semilla": 7001}]
print(len(lote(plan)), "corridas registradas")

06 · Exploración

Laboratorio: el arranque engaña

El sistema arranca vacío y converge a su régimen. Si medís desde el paso cero, el promedio sale artificialmente bajo. Movete el horizonte y el warm-up y observá cómo la media medida se acerca a la real.

EXPERIMENTO 33

Medir en régimen

calentar → medir → guardar

Los resultados numéricos aparecen debajo.
Media sin descarte0
Media en régimen0
Sesgo del arranque0
LecturaSesgada

Con warm-up 15, el arranque deja de tirar la media hacia abajo.

Zona sombreada: warm-up que se corre pero no se mide. Línea clara: media contaminada. Línea amarilla: media en régimen.

Preguntas para explorar

  1. Con warm-up en 0, ¿la media queda por encima o por debajo del régimen? ¿Por qué?
  2. Subí el warm-up a 30. ¿El sesgo se achica? ¿A qué costo?
  3. Alargá el horizonte a 100 con warm-up 15. ¿El descarte «cuesta» lo mismo en proporción?
Ver respuestas sugeridas
  1. Por debajo: arrancar en cero tira el promedio hacia abajo aunque el régimen sea alto.
  2. Sí, casi desaparece, pero se mide menos: 30 de cada 60 pasos van a la basura. Equilibrio entre sesgo y muestra.
  3. No: 15 de 100 es 15%, contra 25% con horizonte 60. El horizonte largo diluye el costo del warm-up.

07 · Comprensión

Confusiones frecuentes

«Más pasos siempre es mejor»

Más horizonte sin warm-up solo promedia más arranque con más régimen: el sesgo persiste. Largo sirve si el warm-up está bien puesto.

«El transitorio se ve a ojo y listo»

El ojo ayuda a elegirlo, pero debe quedar escrito como parámetro (warmup = 15) y aplicado igual a todas las corridas comparadas.

«Guardar todo crudo es más seguro»

Es más disco, más tiempo y más filtraciones de datos personales o sensibles. Métricas + traza regeneran lo necesario.

«Si una corrida falla la descarto en silencio»

No: se registra como fallo con su motivo. Los fallos silenciosos sesgan: solo «sobreviven» los escenarios que anduvieron.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: medir con y sin warm-up

Corré 10 pasos desde cero y compará la media total con la media desde el paso 3.

historia = [0, 2, 4, 6, 7, 8, 8, 9, 9, 9]
total = sum(historia) / len(historia)
regimen = sum(historia[3:]) / len(historia[3:])
print("total:", total)
print("régimen:", regimen)
Ver solución razonada

El total da 6.2 y el régimen 8.0: el arranque en 0, 2 y 4 arrastra el promedio casi dos puntos hacia abajo.

Ejercicio 2: descartar por slicing

Escribí la función que separa warm-up de medición y devolvé ambas partes.

def partir(historia, warmup):
    return historia[:warmup], historia[warmup:]


print(partir([0, 2, 4, 6, 8, 9], 3))
Ver solución

Da ([0, 2, 4], [6, 8, 9]): lo primero se corrió pero no se mide; lo segundo es la muestra válida.

Ejercicio 3: lote que no pierde fallos

Simulá un lote de 3 corridas donde una falla y verificá que quede registrada con estado.

Ver una posible respuesta
tabla = []
for semilla in [7000, 7001, 7002]:
    try:
        if semilla == 7001:
            raise ValueError("corte por presupuesto")
        tabla.append({"semilla": semilla, "estado": "OK"})
    except Exception as e:
        tabla.append({"semilla": semilla, "estado": f"FALLO: {e}"})

print(tabla)

Las tres corridas quedan en tabla, una con FALLO: corte por presupuesto: el análisis decidirá después, con el registro completo a la vista.

09 · Síntesis

Ideas para recordar

  • Ejecutar es inicializar, calentar, medir, cerrar y guardar, corrida por corrida.
  • El horizonte y el warm-up se fijan antes: el arranque no se promedia.
  • Cada corrida va aislada, con semilla propia y estado reiniciado.
  • Se guardan métricas + traza + estado: liviano, auditable y repetible.
  • En Python: bucle sobre el plan, random.Random(semilla) por corrida y try/except con estado.

En el próximo tema leeremos esos registros: el análisis de resultados.