Program yang memakai angka acak menghadapi persoalan klasik: hasilnya berbeda pada setiap eksekusi. Untuk permainan, perilaku itu justru diharapkan. Tetapi untuk pengujian dan pelaporan, hasil yang berubah-ubah menyulitkan: unit test bisa gagal tanpa penyebab yang jelas, angka pada laporan tidak dapat diperiksa ulang, dan bug hanya muncul kadang-kadang sehingga sulit dilacak.

Solusi NumPy ada pada seed: bilangan yang menentukan titik awal urutan pseudorandom. Aturannya satu kalimat — seed yang sama menghasilkan urutan yang sama. Bab ini membuktikan aturan itu, menunjukkan kapan sifat ini dibutuhkan, dan mengulas bentuk seed yang dapat diberikan pada default_rng.

Seed Sama, Urutan Sama #

Dua objek Generator yang dibuat terpisah dengan seed yang sama akan menarik angka dalam urutan yang identik. Kita buktikan dengan np.array_equal:

python
import numpy as np

rng_a = np.random.default_rng(42)
rng_b = np.random.default_rng(42)
a = rng_a.integers(0, 100, size=6)
b = rng_b.integers(0, 100, size=6)
print(a)
print(b)
print(np.array_equal(a, b))

Output yang Dihasilkan:

text
[ 8 77 65 43 43 85]
[ 8 77 65 43 43 85]
True

Bedah baris demi baris:

  1. Baris 3-4: dua objek Generator dibuat terpisah; keduanya ber-seed 42.
  2. Baris 5-6: masing-masing generator menarik enam integer pada rentang 0 sampai 99.
  3. Baris 7-9: kedua array tercetak identik, dan np.array_equal mengonfirmasinya dengan True.

Angka 42 tidak istimewa. Ganti dengan 7, 2024, atau bilangan lain, dan sifatnya tetap: seed sama, urutan sama. Kebiasaan menulis 42 di dokumentasi hanyalah tradisi komunitas.

Seed Berbeda, Urutan Berbeda #

Kebalikannya juga berlaku:

python
import numpy as np

rng_a = np.random.default_rng(42)
rng_c = np.random.default_rng(7)
print(rng_a.integers(0, 100, size=6))
print(rng_c.integers(0, 100, size=6))

Output yang Dihasilkan:

text
[ 8 77 65 43 43 85]
[94 62 68 89 57 77]

Seed 42 dan 7 menghasilkan enam angka yang sama sekali berbeda. Tidak ada pola yang dapat ditebak: seed yang berdekatan tidak menghasilkan urutan yang mirip. Inilah sifat yang diharapkan dari pembangkit pseudorandom yang baik.

Mengulang Program Secara Utuh #

Cara termudah mereproduksi hasil adalah menjalankan ulang program: default_rng(42) dibuat ulang dari awal sehingga seluruh urutan diulang persis. Contoh berikut mensimulasikan “eksekusi ulang” dengan membuat generator baru di tengah program:

python
import numpy as np

rng = np.random.default_rng(42)
print(rng.integers(0, 100, size=6))
print(rng.integers(0, 100, size=6))
rng_baru = np.random.default_rng(42)
print(rng_baru.integers(0, 100, size=6))

Output yang Dihasilkan:

text
[ 8 77 65 43 43 85]
[ 8 69 20  9 52 97]
[ 8 77 65 43 43 85]

Baris pertama dan ketiga identik: generator baru ber-seed 42 mengulang urutan dari titik awal. Baris kedua berbeda karena generator pertama telah maju satu langkah. Ketika program asli dijalankan ulang dari nol, ketiga baris kembali sama persis dengan eksekusi sebelumnya.

Sifat ini dibutuhkan pada banyak situasi:

  • Unit test: nilai yang di-assert tidak berubah antar eksekusi, sehingga pengujian simulasi menjadi stabil.
  • Laporan dan riset: pembaca dapat menjalankan ulang kode dan memperoleh angka yang sama dengan yang dilaporkan.
  • Berbagi kode: rekan tim melihat output yang sama tanpa perlu penjelasan tambahan.
  • Debugging: kesalahan dapat direproduksi secara konsisten, bukan muncul kadang-kadang.

Bentuk Seed: Int dan SeedSequence #

Seed yang paling umum adalah bilangan bulat non-negatif. Secara internal, NumPy tidak memakai bilangan itu mentah-mentah: nilai seed diolah oleh objek SeedSequence menjadi keadaan awal BitGenerator. Proses ini memastikan seed kecil sekalipun menghasilkan keadaan awal yang berkualitas secara statistik. Kita juga dapat membuat SeedSequence secara eksplisit dan meneruskannya ke default_rng — hasilnya identik dengan meneruskan int asalnya:

python
import numpy as np

ss = np.random.SeedSequence(42)
rng_dari_ss = np.random.default_rng(ss)
rng_dari_int = np.random.default_rng(42)
print(np.array_equal(
    rng_dari_ss.integers(0, 100, size=6),
    rng_dari_int.integers(0, 100, size=6),
))

Output yang Dihasilkan:

text
True

Bedah baris demi baris:

  1. Baris 3: SeedSequence(42) dibuat secara eksplisit.
  2. Baris 4-5: dua generator dibuat — satu dari objek SeedSequence, satu dari int 42.
  3. Baris 6-9: np.array_equal mengonfirmasi kedua generator menghasilkan urutan yang sama, karena default_rng(42) sendiri di dalamnya memakai SeedSequence(42).

Seluruh bab pada section ini memakai seed tetap pada contohnya, sehingga setiap output yang ditampilkan dapat kita periksa ulang di komputer mana pun.