Einstieg · Galtonbrett

Lektion 3: Zufall und Zählen

Baue das Muster „Galtonbrett“ in Python und lerne dabei:

  • Zufallszahlen mit np.random.default_rng
  • True und False, gezählt als 1 und 0
  • Zählen mit np.bincount
  • eine List Comprehension
  • eine Simulation, mit einer Formel überprüft

Erst ansehen

Läuft nach einem Klick von YouTube.

galton-board.py
"""Galton board: every ball goes left or right at random at each of 12 rows of pegs.
Run: python galton-board.py   (needs: pip install numpy matplotlib)
"""
from math import comb

import numpy as np
import matplotlib.pyplot as plt

plt.style.use("dark_background")

rows, balls, p = 12, 5000, 0.5  # p: the chance of bouncing right
rng = np.random.default_rng()

bins = (rng.random((balls, rows)) < p).sum(axis=1)  # a ball's bin = how often it went right
counts = np.bincount(bins, minlength=rows + 1)

k = np.arange(rows + 1)
expected = [balls * comb(rows, i) * p**i * (1 - p) ** (rows - i) for i in k]  # the binomial curve

plt.figure(figsize=(7, 4))
plt.bar(k, counts, color="#5eead4", label="balls")
plt.xlabel("bin = times the ball went right")
plt.plot(k, expected, color="white", label="C(n, k) p^k (1-p)^(n-k)")
plt.legend()
plt.show()

# Try: p = 0.65 tilts the board; rows = 24 makes the bell narrower for its width

Kein Python auf diesem Computer? Das Notebook führt dasselbe Skript, die Übungen und die Lösungen in deinem Browser aus, in Google Colab. Das Notebook ist auf Englisch.

Zeile für Zeile

  1. rng = np.random.default_rng()

    Der Zufallszahlengenerator von numpy. Gib ihm eine Zahl, default_rng(1), und jeder Lauf ergibt dieselben „zufälligen“ Zahlen.

  2. bins = (rng.random((balls, rows)) < p).sum(axis=1)

    Eine Tabelle von 5000 × 12 Zufallszahlen zwischen 0 und 1. Jede unter p ist True, ein Sprung nach rechts; die Summe einer Zeile zählt ihre Trues, und das ist das Fach der Kugel.

  3. counts = np.bincount(bins, minlength=rows + 1)

    Wie viele Kugeln in jedem Fach von 0 bis 12 gelandet sind; minlength sorgt dafür, dass die leeren Randfächer als 0 gezählt werden.

  4. expected = [balls * comb(rows, i) * p**i * (1 - p) ** (rows - i) for i in k]

    Eine List Comprehension: die Binomialformel für jedes Fach i, mal die Zahl der Kugeln.

  5. plt.bar(k, counts, color="#5eead4", label="balls")

    Ein Balken pro Fach. Die weiße Linie, die danach gezeichnet wird, ist die Formel, zum Vergleich.

Probier es selbst

  1. Starte das Skript zweimal. Sind die Balken gleich? Dann sorge dafür, dass jeder Lauf gleich ist.

    Hinweis

    Gib default_rng eine Zahl.

    Lösung

    Die Balken unterscheiden sich jedes Mal ein wenig. rng = np.random.default_rng(1) ergibt jedes Mal denselben Lauf.

  2. Wie viele von 5000 Kugeln sollten bei 12 Reihen im mittleren Fach landen?

    Hinweis

    Der Anteil des mittleren Fachs ist comb(12, 6) / 2**12.

    Lösung

    5000 × 924 ÷ 4096 ≈ 1128.

  3. Kipp das Brett mit p = 0.65. Wo liegt jetzt die Mitte der Glocke?

    Hinweis

    Die Mitte ist rows · p.

    Lösung

    12 × 0,65 = 7,8, also wandert der Gipfel zu den Fächern 7 und 8.

Quiz

1. Was enthält rng.random((5000, 12)) < 0.5?
2. Warum ergibt .sum(axis=1) das Fach einer Kugel?
3. Was ist np.bincount([0, 2, 2, 3])?
4. Was ändert default_rng(1)?
5. Welcher Teil der Binomialformel zählt die Wege in Fach k?

Lernkarten

Lies die Vorderseite, sag dir die Rückseite vor, dann öffne die Karte.

  • np.random.default_rng(seed)

    Ein Zufallszahlengenerator; derselbe Seed ergibt dieselben Zahlen.

  • array < 0.5

    Ein Array aus True und False; True zählt beim Addieren als 1.

  • np.bincount(xs)

    Wie oft jede ganze Zahl 0, 1, 2, … in xs vorkommt.

  • [f(i) for i in k]

    Eine List Comprehension: eine neue Liste, in der f auf jedes Element von k angewendet ist.

  • comb(n, k)

    Die Zahl der Möglichkeiten, k Dinge aus n auszuwählen: math.comb(12, 6) ist 924.

Diese Lernkarten auf einer eigenen Seite →