01 · Punto de partida
Un escenario es una fila completa
Un escenario no es un número suelto: es una fila con todas las entradas sorteadas. Ejemplo: {demanda: 100, costo: 112, falla: 0}. N escenarios = N filas que alimentan el modelo.
Y todo sale de una sola fuente: U ~ U(0,1). Si sabés transformar un uniforme en cualquier F, sabés construir cualquier escenario.
- ¿Qué columnas tiene mi escenario?
- ¿Cómo paso de U(0,1) a cada columna?
- ¿Las columnas son independientes?
- ¿El escenario es reproducible con semilla?
02 · Definición
La receta universal: transformada inversa
Uniforme base
U ~ U(0,1): la materia prima. Cada columna usa un U fresco e independiente.
Transformación
Regla que convierte U en la F deseada: cortes acumulados, a + (b−a)·U, Box-Muller.
Escenario
La fila armada: una muestra de cada entrada con su transformación. Lista para g(xᵢ).
| Quiero X ~ … | Regla con U | Código |
|---|---|---|
| Bernoulli(p) | 1 si U < p else 0 | 1 if random.random() < p else 0 |
| Discreta {80,100,120} 30/40/30 | Cortes 0,3 / 0,7 / 1 | choices(val, weights) |
| Uniforme(a,b) | a + (b−a)·U | a + (b-a)*random.random() |
| Exponencial(λ) | −ln(1−U)/λ | -math.log(1-u)/lam |
| Normal(μ,σ) | Box-Muller con 2U | random.gauss(mu, sigma) |
03 · Cómo armarlos
Escenarios conjuntos en 3 pasos
- 1Sortear un U por columna.
Demanda usa U₁, costo usa U₂, falla usa U₃. Nunca reutilizar el mismo U.
- 2Transformar cada uno.
Aplicar su regla: cortes, escala o gauss. Cada columna queda con su F.
- 3Combinar en fila.
Juntar en tupla o dict:
{"D": 100, "costo": 112}. Esa fila es el escenario.
- Independencia
- U frescos ⇒ columnas independientes. Es el supuesto por defecto; si hay correlación se modela aparte.
- Reproducibilidad
- Misma semilla ⇒ mismos U ⇒ mismos escenarios. Ideal para depurar y comparar políticas.
- Tamaño del escenario
- Cantidad de columnas, no de filas. Más columnas = modelo más rico, pero más F por justificar.
04 · Ejemplos
Cuatro transformaciones a mano
- 1Moneda.
U = 0,72, p = 0,5 → 0 (ceca). U < p decide.
- 2Demanda 30/40/30.
U = 0,55 → cae en [0,3, 0,7) → D = 100. Cortes acumulados.
- 3Uniforme(10, 20).
U = 0,25 → 10 + 10·0,25 = 12,5. Escala lineal.
- 4Escenario doble.
U₁ = 0,2 → D = 80; U₂ = 0,9 → costo alto. Fila: (80, costo alto).
05 · Representación en Python
Fábrica de escenarios con dicts
Cada escenario es un diccionario; la lista de dicts es la simulación cruda.
Python en tu navegador. Generá 5 escenarios y leelos como filas: así entra al modelo.
import random
import math
def generar_escenario():
u1, u2, u3 = random.random(), random.random(), random.random()
# demanda 80/100/120 con 30/40/30
D = 80 if u1 < 0.3 else (100 if u1 < 0.7 else 120)
# costo Normal(100,15) via gauss (usa 2 uniformes por dentro)
costo = max(0, random.gauss(100, 15))
# falla Bernoulli(0.05)
falla = 1 if u3 < 0.05 else 0
return {"D": D, "costo": round(costo, 1), "falla": falla}
random.seed(8)
for i in range(5):
print(generar_escenario())
06 · Exploración
Laboratorio: nube de escenarios
Cada punto es un escenario (demanda, costo). La demanda toma 80/100/120 y el costo es Normal(100, 15). Con pocos puntos se ven huecos; con miles, la nube se estabiliza.
N escenarios, N filas
xᵢ = (Dᵢ, costoᵢ)
Tocá «Generar» para construir los escenarios.
Tres columnas verticales (80, 100, 120) con dispersión vertical del costo. Si reutilizaras el mismo U, verías diagonales falsas.
Preguntas para explorar
- Con N = 100, ¿las tres columnas tienen puntos? ¿Y con N = 5 000?
- ¿La nube se inclina (correlación) o es recta? ¿Por qué?
- ¿Qué pasaría si generaras costo con el mismo U de la demanda?
Ver respuestas sugeridas
- Con N chico alguna columna queda rala por ruido. Con N grande las proporciones 30/40/30 se notan.
- Es recta: sorteamos independientes. La correlación ≈ 0 es la prueba visual de independencia.
- Demanda alta traería costo alto siempre: correlación 1 falsa que sesga la ganancia.
07 · Comprensión
Confusiones frecuentes
«Un escenario es un número»
Es la fila completa. Evaluar el modelo pide todas las columnas sorteadas, no una sola.
«Reutilizo el U para ahorrar»
Ahorrás un random y arruinás la independencia. Un U por columna, siempre.
«Transformar es opcional»
Sin transformación todo es U(0,1). El modelo espera demandas y costos reales, no uniformes.
«La semilla le quita azar»
No: la hace reproducible. Cambiá la semilla y verificá que la conclusión aguante.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: cortes a mano
Convertí U en demanda 80/100/120 con cortes 0,3 y 0,7, sin usar choices.
import random
def demanda_desde_u(u):
if u < 0.3:
return 80
if u < 0.7:
return 100
return 120
print([demanda_desde_u(random.random()) for _ in range(10)])
Ver solución razonada
Es la transformada inversa discreta: acumular probabilidades y cortar U. choices hace esto por dentro.
Ejercicio 2: uniforme escalado
Generá Uniforme(10, 20) desde random() puro y verificá la media.
import random
N = 10000
m = sum(10 + 10 * random.random() for _ in range(N)) / N
print(m)
Ver solución
~15. La fórmula a + (b−a)·U es la transformada inversa de la uniforme.
Ejercicio 3: escenario completo
Armá 3 escenarios con demanda, costo y falla, y evaluá ganancia con Q = 100.
Ver una posible respuesta
import random
def escenario():
D = random.choices([80, 100, 120], weights=[30, 40, 30])[0]
costo_extra = 200 if random.random() < 0.05 else 0
return {"D": D, "extra": costo_extra}
def ganancia(esc, Q=100):
return 5 * min(Q, esc["D"]) - 2 * Q - esc["extra"]
escenas = [escenario() for _ in range(3)]
print(escenas)
print([ganancia(e) for e in escenas])
Cada dict es una fila lista para el modelo: así se encadenan escenarios y salidas.
09 · Síntesis
Ideas para recordar
- Escenario = fila con todas las entradas sorteadas, una por réplica.
- Todo nace de U(0,1): transformar es aplicar F⁻¹(U).
- Un U fresco por columna garantiza independencia.
- En Python: dict por escenario, lista de dicts por simulación.
- Semilla fija para depurar y comparar; semillas variadas para validar.
En el próximo tema decidiremos el número de simulaciones: cuántas filas hacen falta.