6A. Statistik dari nol (baca ini sebelum berkas 6 dan 7)
Berkas ini menjelaskan apa sebenarnya yang dilakukan sampst dan timest, memakai angka kecil yang bisa
kamu hitung sendiri, dan tanpa istilah yang belum dijelaskan. Semua kata yang mungkin membingungkan
didefinisikan di bagian 10 di bawah.
1. Apa yang ingin kita ketahui
Soal meminta angka rangkuman, misalnya “rata-rata lama menunggu” dan “rata-rata jumlah orang di bus”. Selama
simulasi 4800 menit terjadi ribuan kejadian. Kita butuh pencatat yang menyimpan angka-angkanya sepanjang jalan
dan merangkumnya di akhir. SIMLIB menyediakan dua pencatat itu: sampst dan timest.
Mana yang dipakai bergantung pada jenis angkanya. Ada dua jenis.
2. Dua jenis angka
Jenis 1: angka yang lahir satu kali, pada satu kejadian
Contoh: lama menunggu seorang penumpang. Angkanya baru diketahui satu kali, saat orang itu diambil dari antrian untuk naik. Orang A menunggu 12 menit, orang B 31 menit, orang C 20 menit. Setiap orang menghasilkan satu angka, lalu angka itu selesai.
Satu angka seperti ini kita sebut satu catatan.
Rata-ratanya biasa saja: jumlahkan semua catatan, bagi dengan banyaknya catatan. (12 + 31 + 20) ÷ 3 = 21 menit.
Analogi: nilai ujian. Setiap ujian menghasilkan satu nilai; rata-rata rapor adalah jumlah nilai dibagi banyaknya ujian.
Yang dihitung dengan cara ini: delay antrian (b), lama bus berhenti (d), lama satu putaran (e), lama di sistem (f).
Pencatatnya: sampst.
Jenis 2: sesuatu yang selalu ada dan nilainya berubah-ubah
Contoh: jumlah orang di bus. Kapan pun kamu melihat bus, jumlah orang di dalamnya punya nilai (misalnya 7). Nilai itu bertahan sampai ada yang naik atau turun, lalu berganti (misalnya 8).
Di dokumen ini, kata “level” artinya nilai yang sedang berlaku saat ini: untuk jumlah di bus, level adalah jumlah orang di bus pada saat itu. Bukan “tingkat” atau “pengalaman”.
Analogi: suhu ruangan. Suhu selalu punya nilai, dan berubah-ubah dari waktu ke waktu. Untuk mengetahui “rata-rata suhu hari ini”, kamu tidak cukup menjumlahkan beberapa angka; kamu harus memperhitungkan berapa lama tiap suhu berlaku.
Yang dihitung dengan cara ini: jumlah di bus (c) dan jumlah di antrian (a). Pencatatnya: timest
(untuk antrian, filest, yang pada dasarnya timest otomatis).
3. Kenapa jenis 2 butuh cara hitung yang berbeda
Misalkan jumlah di bus selama 40 menit seperti ini:
| Selama | Jumlah orang di bus (nilai yang berlaku) |
|---|---|
| 10 menit | 0 |
| 20 menit | 5 |
| 10 menit | 20 |
Cara keliru (rata-rata biasa dari ketiga nilai): (0 + 5 + 20) ÷ 3 = 8,3. Ini salah, karena memperlakukan nilai 20 sama pentingnya dengan nilai 5, padahal 20 hanya berlaku 10 dari 40 menit, sedangkan 5 berlaku 20 menit.
Cara benar (memperhitungkan lamanya): kalikan tiap nilai dengan lamanya, jumlahkan, lalu bagi dengan total waktu:
| Nilai | × lamanya | = |
|---|---|---|
| 0 | × 10 | 0 |
| 5 | × 20 | 100 |
| 20 | × 10 | 200 |
| jumlah | 300 |
300 ÷ 40 menit = 7,5. Itu rata-rata terhadap waktu. Kata “dibobot” di dokumen lain artinya persis ini: setiap nilai diberi pengaruh sebanding dengan berapa lama ia berlaku.
4. Bagaimana sampst menghitung (jenis 1)
Di dalam SIMLIB, satu statistik jenis 1 hanya disimpan sebagai empat angka: jumlah semua catatan, banyaknya
catatan, nilai terbesar, dan nilai terkecil. Setiap kali kita memanggil sampst(nilai, nomor), empat angka itu
diperbarui.
Contoh: tiga catatan 30, 10, 20.
| Panggilan | Jumlah semua | Banyaknya | Terbesar | Terkecil |
|---|---|---|---|---|
| (awal) | 0 | 0 | tidak ada | tidak ada |
sampst(30.0, 1) | 30 | 1 | 30 | 30 |
sampst(10.0, 1) | 40 | 2 | 30 | 10 |
sampst(20.0, 1) | 60 | 3 | 30 | 10 |
Saat diminta laporan: rata-rata = 60 ÷ 3 = 20, banyaknya = 3, terbesar = 30, terkecil = 10.
Hanya empat angka itu yang disimpan; SIMLIB tidak menyimpan daftar semua catatan.
5. Bagaimana timest menghitung (jenis 2)
SIMLIB menyimpan: (i) luas (jumlah dari nilai × lamanya, seperti tabel di bagian 3), (ii) nilai terakhir yang dicatat, (iii) kapan nilai itu dicatat, (iv) nilai terbesar, dan (v) terkecil.
Setiap kali kita memanggil timest(nilai_baru, nomor) saat nilai itu berubah, SIMLIB melakukan:
- hitung berapa lama nilai lama berlaku = waktu sekarang − waktu panggilan sebelumnya;
- tambahkan ke luas: nilai lama × lama itu;
- simpan nilai baru dan waktu sekarang.
Contoh yang sama (jumlah di bus), dengan jam simulasi:
| Waktu | Panggilan | Nilai lama | Berlaku selama | Luas bertambah | Luas total |
|---|---|---|---|---|---|
| 0 | timest(0.0, 1) (bus mulai kosong) | 0 | 0 | 0 | 0 |
| 10 | timest(5.0, 1) (5 orang naik) | 0 | 10 | 0 × 10 = 0 | 0 |
| 30 | timest(20.0, 1) (15 orang naik lagi) | 5 | 20 | 5 × 20 = 100 | 100 |
| 40 | laporan | 20 | 10 | 20 × 10 = 200 | 300 |
Rata-rata terhadap waktu = luas total ÷ seluruh waktu = 300 ÷ 40 = 7,5. Terbesar = 20, terkecil = 0.
Dua aturan yang muncul dari cara kerja ini:
| Aturan | Alasannya |
|---|---|
Panggil timest setiap kali nilainya berubah, dengan nilai barunya | SIMLIB hanya tahu kapan kita memberi tahu; ia tidak melihat sendiri bus berubah |
Panggil timest(0.0, ...) di awal | supaya SIMLIB tahu nilai awalnya 0 sejak t = 0 |
Karena itulah model memanggil hook jumlah-di-bus setiap kali ada yang naik atau turun, dan stats_init memanggil
timest(0.0, ...) di awal.
6. “Laci”: satu statistik, satu nomor
Setiap statistik punya nomor sendiri (di kode disebut variabel sampst atau timest; di dokumen ini saya
memakai kata “laci”). Angka yang kita catat masuk ke laci bernomor itu, dan hanya laci itu yang dilaporkan saat
diminta. Dengan begitu delay lokasi 1 tidak tercampur dengan delay lokasi 2.
| Statistik | Pencatat | Nomor laci |
|---|---|---|
| (b) delay antrian lokasi 1, 2, 3 | sampst | 1, 2, 3 |
| (d) lama berhenti lokasi 1, 2, 3 | sampst | 4, 5, 6 |
| (e) lama satu putaran | sampst | 7 |
| (f) lama di sistem asal 1, 2, 3 | sampst | 8, 9, 10 |
| (c) jumlah di bus | timest | 1 |
Laci sampst dan laci timest adalah dua kelompok nomor terpisah, jadi sampst nomor 1 dan timest nomor 1
tidak bertabrakan.
7. Mencatat dan meminta laporan: satu fungsi, dua mode
| Panggilan | Artinya |
|---|---|
sampst(30.0, 1) (nomor positif) | catat angka 30,0 ke laci 1 |
sampst(0.0, -1) (nomor negatif) | minta laporan laci 1; angka pertama (0,0) diabaikan |
Tanda minus hanya kesepakatan SIMLIB supaya tidak perlu dua nama fungsi. Hasil laporan tidak dikembalikan sebagai
nilai; SIMLIB meletakkannya di larik transfer[], yang harus segera disalin karena panggilan SIMLIB berikutnya
menimpanya.
| Pembacaan laporan | transfer[1] | transfer[2] | transfer[3] | transfer[4] |
|---|---|---|---|---|
sampst(0.0, -nomor) | rata-rata | banyaknya catatan | terbesar | terkecil |
timest(0.0, -nomor) atau filest(list) | rata-rata terhadap waktu | terbesar | terkecil | (tidak ada) |
8. Dari mana angkanya datang: “hook”
Simulasi punya banyak fungsi model (orang datang, naik, turun, bus berangkat). Supaya fungsi-fungsi itu tidak
perlu tahu cara mencatat statistik, setiap kali ada sesuatu yang perlu dicatat, ia memanggil sebuah fungsi kecil
bernama hook (secara harfiah “kait” atau “titik sambung”). Hook itulah yang memanggil sampst atau timest.
Analogi: kasir menekan tombol “catat transaksi” setiap kali ada pembeli. Kasir tidak perlu tahu cara laporan keuangan dihitung; ia hanya menekan tombol. Fungsi hook adalah tombol itu.
| Kapan sesuatu terjadi di model | Hook yang dipanggil | Yang dicatat | Pencatat |
|---|---|---|---|
| orang diambil dari antrian untuk naik | stats_queue_delay | lama orang itu menunggu | sampst |
| orang naik atau mulai turun (jumlah di bus berubah) | stats_bus_count_changed | jumlah di bus yang baru | timest |
| bus berangkat dari sebuah lokasi | stats_bus_stop | lama bus berhenti di situ | sampst |
| bus berangkat dari rental mobil | stats_bus_loop | lama satu putaran | sampst |
| orang selesai turun | stats_time_in_system | lama orang itu di sistem | sampst |
9. Statistik (a): antrian, tanpa hook
Jumlah orang di antrian juga jenis 2 (selalu ada, berubah-ubah). SIMLIB sudah mencatatnya sendiri setiap kali
sebuah orang masuk atau keluar antrian, jadi kita tidak perlu hook. Kita hanya meminta laporan dengan filest.
Contoh: antrian berisi 0 orang selama 5 menit, lalu 3 orang selama 5 menit. Rata-rata terhadap waktu = (0 × 5 + 3 × 5) ÷ 10 = 1,5 orang.
10. Daftar istilah di atas
| Istilah | Arti sederhana |
|---|---|
| Catatan (observasi) | satu angka yang dimasukkan ke pencatat (misalnya satu delay) |
| Level | nilai yang sedang berlaku saat ini (misalnya jumlah orang di bus sekarang); bukan “tingkat” |
| Rata-rata biasa | jumlah semua catatan dibagi banyaknya (untuk jenis 1) |
| Rata-rata terhadap waktu | jumlah (nilai × lamanya nilai itu berlaku) dibagi seluruh waktu (untuk jenis 2) |
| Dibobot | diberi pengaruh sebanding dengan lamanya berlaku |
| Laci | nomor statistik; satu statistik satu nomor |
| Hook | fungsi kecil yang dipanggil model pada saat tertentu untuk mencatat sesuatu |
| Luas | jumlah dari (nilai × lamanya) yang dihitung timest |
| Sentinel (1e30) | angka raksasa yang dipakai SIMLIB sebagai tanda “belum ada data”; tidak boleh dicetak apa adanya |
| Layout | urutan isi hasil laporan di transfer[1], [2], dan seterusnya |
Cast (double) | mengubah tipe angka: bilangan bulat menjadi desimal supaya cocok dengan fungsi yang memintanya |
| Disalin segera | angka dipindah dari transfer[] ke variabel lokal, karena transfer[] ditimpa panggilan SIMLIB berikutnya |
11. Hitung sendiri (jawaban di bawah)
- Tiga orang menunggu 5, 15, dan 40 menit. Berapa rata-rata, terbesar, dan terkecil yang akan dilaporkan
sampst? - Jumlah di bus: 0 selama 20 menit, 10 selama 30 menit, 4 selama 10 menit. Berapa rata-rata terhadap waktu? Berapa jika dihitung dengan rata-rata biasa dari ketiga nilai (yang keliru)?
- Kenapa
timestharus dipanggil setiap kali jumlah di bus berubah?
Jawaban:
- Rata-rata (5 + 15 + 40) ÷ 3 = 20, terbesar 40, terkecil 5.
- Total waktu 60 menit. Luas = 0 × 20 + 10 × 30 + 4 × 10 = 340. Rata-rata = 340 ÷ 60 = 5,67. Cara keliru: (0 + 10 + 4) ÷ 3 = 4,67, salah karena mengabaikan lamanya.
- SIMLIB hanya mengetahui perubahan kalau kita memberi tahu; tanpa panggilan itu, ia tidak tahu kapan nilai berubah dan luasnya salah.