01 · Punto de partida
Un número para gobernarlos a todos
En el Tema 4 viste que una secuencia nace de x₀ → x₁ = f(x₀) → x₂ = f(x₁) → …. Ese x₀ es la semilla: el único grado de libertad que te deja un generador determinista. Fijada la semilla y la fórmula, toda la historia de millones de valores queda decidida.
Por eso la semilla es a la vez superpoder y responsabilidad: te da control total (repetir, depurar, compartir), pero un descuido —semilla cero en el generador equivocado, hora en segundos, semilla no anotada— arruina un experimento o una contraseña.
- ¿Qué es exactamente una semilla y qué no es?
- ¿Cómo se elige una buena semilla para simular y para variar?
- ¿Por qué la semilla 0 a veces «mata» al generador?
- ¿Qué hay que anotar junto a la semilla para ser reproducible?
02 · Definición
Semilla, estado y entropía de siembra
Tres ideas que suelen mezclarse y conviene separar:
Semilla
El x₀ que vos proveés. Puede ser un entero chico (42), un timestamp o 64 bits del sistema. Es pública en simulación, secreta en seguridad.
Estado inicial
Lo que el generador carga en memoria al arrancar. En un LCG es la semilla misma; en uno moderno es un vector derivado de ella por una función de mezcla.
Siembra
El acto de inicializar: random.seed(42). Sembrar dos veces con lo mismo rebobina la secuencia al inicio, no la «mezcla».
| Generador | Semilla válida | Trampa típica |
|---|---|---|
LCG mixto (a·x+c) mod m | Cualquiera en 0..m-1 | Creer que cambia el período (solo cambia el arranque) |
LCG multiplicativo (a·x) mod m | Nunca 0 | Con x₀=0 todo da 0 para siempre |
| Moderno (PCG, Mersenne) | Entero de 32/64 bits o vector | Semillas 1, 2, 3 correlacionadas al inicio si no hay mezcla |
03 · Elección y registro
Cómo elegir y anotar semillas sin sufrir
Elegir semilla no es arte: es decidir qué querés (repetir o variar) y dejarlo por escrito:
- Fija documentada
- Un entero arbitrario pero anotado:
seed = 2026en el código y en el informe. Es el estándar para papers, depuración y este curso. - Aleatoria del SO
- Pedida a
os.urandomosecretscuando querés variedad entre corridas. La imprimís y la guardás: variedad con trazabilidad. - Tiempo
int(time.time())solo para demos y juegos casuales. Colisiona en el mismo segundo y se adivina. Nunca para seguridad ni ciencia seria.- Secuencia de semillas
- Para réplicas:
[101, 102, …]o mejor, enteros espaciados al azar. Semillas 1, 2, 3 seguidas pueden dar arranques parecidos en algunos generadores (Tema 37).
Buena práctica
Semilla + contexto
Guardás semilla, algoritmo, versión de código y N. Con esos 4 datos cualquiera repite tu experimento bit a bit.
Mala práctica
Semilla fantasma
«Usé random sin seed y me dio 0,62». Nadie puede repetirlo, ni vos mismo. El resultado es anecdótico.
04 · Ejemplos
La misma fórmula, cuatro destinos
Con el LCG didáctico m = 16 se ven a ojo los destinos que una semilla puede tener:
- 1Semilla normal en mixto.
x₀=7, a=5, c=3: ciclo completo de 16, arranque en 7. Cambiar a 8 solo rota el anillo. - 2Semilla cero en mixto.
x₀=0, a=5, c=3: funciona igual, entra al mismo anillo por otra puerta. El cero no es trampa aquí. - 3Semilla cero en multiplicativo.
x₀=0, a=5, c=0:5·0 mod 16 = 0para siempre. Secuencia muerta0, 0, 0…. - 4Semillas correlativas.
1, 2, 3en un generador sin mezcla arrancan parecido las primeras posiciones. Para réplicas independientes conviene espaciarlas (Tema 37).
05 · Siembra en Python
Fijar, variar y registrar
Tres líneas cubren el 95 % de tus necesidades: fijar para repetir, pedir entropía para variar y guardar lo usado.
Python en tu navegador. Probá sembrar dos veces con lo mismo y observá el «rebobinado» exacto.
import random
random.seed(42)
print("primera:", [random.random() for _ in range(3)])
random.seed(42)
print("rebobinada:", [random.random() for _ in range(3)])
Idénticas: sembrar no agrega azar, reinicia la película desde el mismo fotograma.
Pedir una semilla al sistema y guardarla
Cuando querés variedad con trazabilidad, el sistema te da la semilla y vos la imprimís para el diario del experimento:
import os
import random
semilla = int.from_bytes(os.urandom(4), "big")
random.seed(semilla)
print("semilla usada:", semilla)
print([round(random.random(), 4) for _ in range(5)])
06 · Exploración
Laboratorio: la semilla elige la historia
Elegí semilla, tipo de generador y N. El modo mixto usa (5·x+3) mod 16; el multiplicativo usa (5·x) mod 16. Probá la semilla 0 en ambos y mirá qué pasa.
Semilla cero bajo la lupa
mixto vs. multiplicativo
Con semilla 7 ambos tipos parecen azar en N chico.
Cada punto es u(n) = x(n)/16. La línea plana en cero delata la trampa de la semilla cero en el multiplicativo.
Preguntas para explorar
- Con semilla 0 y tipo multiplicativo, ¿qué valores salen? ¿Y con semilla 0 y mixto?
- Con semilla 7, ¿distinguís a ojo mixto de multiplicativo en 32 valores? ¿Qué necesitarías para decidir?
- Si tu simulación dio un resultado raro con semilla 7, ¿cómo lo repetís exactamente para depurar?
Ver respuestas sugeridas
- Multiplicativo + 0 = todo cero (punto fijo absorbente). Mixto + 0 funciona normal: el
+3lo saca del cero. - No a ojo: ambos cubren valores parecidos en N chico. Necesitás período, tests y N grande (Temas 10 y 26+).
- Resembrando con 7 y corriendo el mismo código y N: obtendrás bit a bit lo mismo para inspeccionar el paso raro.
07 · Comprensión
Confusiones frecuentes
«Cualquier semilla sirve en cualquier generador»
No: el 0 mata a los multiplicativos puros y algunas semillas reservadas (todo ceros) son ilegales en generadores modernos. Leé el rango válido de tu generador.
«Resiembro con la hora en cada tiro para más azar»
Es peor: colisiona en el mismo segundo y correlaciona tus «azarosos». Se siembra una vez; después se itera.
«Semillas 1, 2, 3 dan réplicas independientes»
Pueden arrancar demasiado cerca y contaminar comparaciones. Para réplicas usá semillas espaciadas o derivadas con mezcla (Tema 37).
«La semilla no se anota, total el promedio da igual»
Sin semilla no hay depuración ni publicación: un promedio sin semilla es un rumor. Anotarla cuesta una línea.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: el rebobinado
Demostrá que sembrar dos veces rebobina: generá 3 valores, generá 3 más, resembrá y compará con los primeros 3.
import random
random.seed(99)
a = [random.random() for _ in range(3)]
b = [random.random() for _ in range(3)]
random.seed(99)
c = [random.random() for _ in range(3)]
print(a)
print(b)
print(c)
print("c == a:", c == a)
Ver solución razonada
c == a es True y b es la continuación, no una repetición. La semilla marca el inicio de la cinta, no un «batido».
Ejercicio 2: matar un generador con cero
Compará mixto y multiplicativo desde semilla 0 con el mismo a. ¿Cuál sobrevive?
def gen(semilla, a, c, m, n=8):
x = semilla
sal = []
for _ in range(n):
x = (a * x + c) % m
sal.append(x)
return sal
print("mixto:", gen(0, 5, 3, 16))
print("multi:", gen(0, 5, 0, 16))
Ver solución
El mixto produce valores variados; el multiplicativo queda en [0, 0, …]. Moraleja: c = 0 y semilla 0 son incompatibles.
Ejercicio 3: diario de experimento
Empaquetá semilla, parámetros y primeros valores para que tu yo del futuro pueda repetirlo.
Ver una posible respuesta
import random
corrida = {"semilla": 2026, "a": 5, "c": 3, "m": 16, "n": 6}
random.seed(corrida["semilla"])
vals = [round(random.random(), 4) for _ in range(corrida["n"])]
print(corrida)
print(vals)
Guardar el diccionario junto a la salida es tu «caja negra» de vuelo. En el Tema 6 lo convertiremos en protocolo completo de reproducibilidad.
09 · Síntesis
Ideas para recordar
- La semilla es el estado inicial: decide toda la secuencia futura.
- Sembrar dos veces con lo mismo rebobina, no agrega azar.
- Elegí fija documentada para ciencia, del SO para variedad; la hora solo para demos.
- El 0 es letal en generadores multiplicativos puros.
- Anotá semilla + algoritmo + versión + N: sin eso no hay experimento repetible.
En el próximo tema convertiremos esto en método: reproducibilidad mediante semillas, el protocolo para que tus simulaciones siempre puedan repetirse bit a bit.