Pendahuluan
Simulasi adalah metode untuk melakukan eksperimen, sistem nyata yang dipelajari digantikan oleh model. Dalam model seperti itu, Anda bisa kehilangan situasi individu dan banyak dari mereka. Statistik yang dikumpulkan dapat membantu menarik kesimpulan tentang proses dalam sistem, serta garis besar jalur optimisasi.
Pemodelan simulasi sering dianggap sebagai semacam tes eksperimental, tetapi pada saat yang sama lebih murah, memungkinkan Anda untuk dengan cepat mengubah parameter dan mengamati sistem simulasi dalam dinamika.
Sudah sekitar setengah abad dalam pemodelan simulasi, model komputer telah digunakan. Banyak program dan kerangka kerja yang berbeda telah dibuat untuk pengembangannya, di antaranya, menurut saya, yang paling berkembang adalah alat untuk pemodelan sistem antrian (QS). Salah satu program yang paling terkenal dan sederhana untuk simulasi QS - GPSS World (Sistem Simulasi Tujuan Umum - sistem pemodelan tujuan umum), dapat ditemukan secara lebih rinci di tautan
[1] ,
[2] .
Konsep program ini adalah dasar dari kerangka kerja simulasi on Go.
Simulasi dalam GPSS
Model dalam GPSS adalah urutan blok (perintah) yang menggambarkan objek yang disimulasikan di mana transaksi bergerak. Ketika transaksi memasuki blok, peristiwa dihasilkan yang mengarah baik ke perubahan dalam keadaan objek yang dimodelkan atau ke perubahan dalam status / parameter transaksi.
Blok utama dari urutan sepuluh: GENERATE, TERMINATE, ASSIGN, SEIZE, RELEASE, QUEUE, ADVANCE, DEPART, START. Ada sekitar tiga lusin blok secara total. Blok memiliki parameter, yang bisa berupa angka, nama fungsi, label dalam program simulasi, nama variabel. Rincian lebih lanjut tentang blok dapat ditemukan, misalnya, di
sini .
Objek dalam GPSS memiliki seperangkat atribut numerik standar (NAV) dan atribut logis standar (ALS). Misalnya, untuk antrian, salah satu NAV adalah panjangnya saat ini, dan contoh ALS untuk beberapa peralatan akan BENAR atau sibuk (SALAH).
Dalam beberapa versi GPSS ada visualisasi dari proses pemodelan, tetapi paling sering tidak ada. Berdasarkan hasil simulasi, laporan dihasilkan dalam GPSS, menunjukkan NAV dan ALS untuk semua objek.
Go implementasi
Implementasi di Go adalah pengembangan dari serangkaian objek yang fungsinya mirip dengan blok GPSS. Yang pertama dibuat Pipeline - objek di mana simulasi dilakukan.
Berdasarkan
map
berisi daftar komponen untuk menggambarkan sistem yang disimulasikan. Karena, selama simulasi, transaksi harus melalui urutan blok dalam urutan yang ketat, dalam metode penambahan komponen
Append
, prosedur penambahan dengan indikasi simultan tujuan transaksi dari mereka diimplementasikan. Nama komponen digunakan sebagai kunci
map
, sehingga setiap komponen harus memiliki nama yang unik.
Setelah menambahkan semua komponen, Anda dapat memulai simulasi menggunakan metode
Start
. Di dalamnya, bypass siklik dari semua komponen diimplementasikan untuk waktu simulasi yang diberikan. Di akhir simulasi, Anda dapat mencetak laporan yang berisi NAV dan ALS.
Elemen penting kedua adalah komponen aktual untuk menggambarkan simulasi. Diimplementasikan: Generator - menghasilkan transaksi, Advance - menciptakan keterlambatan di jalur transaksi, Antrian - antrian transaksi, Fasilitas - perangkat yang secara eksklusif ditangkap oleh transaksi untuk sementara waktu, Lubang - "lubang" di mana transaksi gagal di akhir jalur. Tentu saja, set seperti itu tidak cukup untuk membuat model simulasi yang kompleks, tetapi cukup untuk menyelesaikan solusinya dan membandingkannya dengan hasil GPSS. Semua komponen menerapkan antarmuka IBaseObj, yang mencakup fungsionalitas minimum yang disyaratkan.
Setiap komponen memiliki antrian transaksi. Langsung sebagai antrian, hanya digunakan dalam Antrian, untuk komponen lain, itu hanya repositori. Antrian diimplementasikan berdasarkan
map
. Dalam proses pemodelan, komponen lulus pada gilirannya dan memeriksa kesiapan (pemenuhan kondisi tertentu) dari transaksi untuk transmisi ke komponen berikutnya. Transfer dilakukan melalui metode
AppendTransact
dari komponen selanjutnya. Jika transfer berhasil, maka transaksi dihapus dari antrian, masing-masing, komponen selanjutnya membawanya secara bergantian. Karena beberapa penerima ditentukan untuk setiap komponen, maka jika tidak mungkin mengirim transaksi ke satu penerima, kami mencoba mengirimkannya ke yang lain.
Untuk menghasilkan variabel acak saat menentukan waktu penampilan transaksi dan membuat penundaan, fungsi PRNG di Go digunakan.
Karena ketika membuat model, pada saat yang sama, ada banyak transaksi yang bergerak di antara berbagai komponen, muncul ide untuk menggunakan goroutine di dalam komponen. Pipeline, melewati komponen-komponen, memulai penangan
HandleTransacts
untuk masing-masing, di mana goroutine dibuat. Setelah semua goroutine selesai, penghitung waktu model bertambah dan
HandleTransacts
dipanggil
HandleTransacts
.
Objek kunci terakhir adalah transaksi itu sendiri. Dia memiliki pengidentifikasi, waktu kelahiran dan kematian, pemilik (di mana komponen dia sekarang), sejumlah parameter untuk menghitung SCA dan SCHL.
Dalam gbr. 1 adalah diagram struktural dari interaksi objek utama kerangka selama pemodelan.
Fig. 1. Diagram struktural umum dari interaksi objek utama dalam simulasiContoh simulasi
Misalkan Anda perlu mensimulasikan pekerjaan penata rambut. Ini adalah contoh terkenal dari GPSS. Pengunjung pergi secara acak, dengan frekuensi 18 ± 6 menit, jumlah mereka tidak diketahui sebelumnya. Kami memiliki satu penata rambut, ia menghabiskan 16 ± 4 menit untuk memotong rambut. Jadi, berapa banyak orang yang akan dia potong untuk hari kerja? Berapa banyak orang yang akan mengantri? Berapa rata-rata waktu yang dibutuhkan untuk memotong rambut dan berapa lama orang menunggu dalam antrean? Banyak pertanyaan dan simulasi sederhana. Diagram blok pada Gambar. 2.
Fig. 2. Skema struktural pemodelan seorang penata rambutKode untuk membangun model adalah sebagai berikut.
barbershop := NewPipeline("Barbershop", true)
Hasil simulasi dapat ditemukan di sini.Nama pipa "Barbershop"
Waktu simulasi 480
Nama objek "Kursi"
Konten maks. 1
Total entri 26
Entri nol 11
Entri nol entri 42,31%
Dalam antrian 0
Rata-rata waktu / trans 2,58
Rata-rata waktu / trans tanpa entri 4.47
Nama objek "Klien"
Dihasilkan 26
Nama objek "Tuan"
Uang muka rata-rata 16.46
Pemanfaatan rata-rata 89,17
Entri angka 26,00
Transaksi 26 dalam fasilitas
Nama objek "Keluar"
Terbunuh 25
Uang muka rata-rata 16.56
Kehidupan rata-rata 19.44
Melayani 25 pelanggan, tanggal 26 pada saat penyelesaian simulasi masih di kursi master. Antriannya tidak lebih dari 1 orang, 11 orang tidak menunggu (zero pass) dan langsung memotong rambut. Rata-rata, orang menghabiskan 2,58 menit dalam antrian, dan dari mereka yang menunggu (bukan nol lulus), 4,47 menit. 89,17% waktunya, seorang penata rambut, dicukur secara intensif.
Tentu saja, jika Anda melakukan simulasi lain, hasilnya akan berubah. Tetapi selama serangkaian simulasi, tingkat keseluruhan pemuatan penyihir dan jumlah klien yang dilayani akan terlihat. Simulasi serupa di GPSS menghasilkan hasil yang serupa.
Contoh lain. Ada kantor, memiliki 10 karyawan dan satu toilet. Orang ingin pergi ke toilet setiap 90 ± 60 menit, pergi ke toilet selama 5 ± 3 menit, mengambil toilet selama 15 ± 10 menit, kembali ke kantor selama 5 ± 3 menit. Kami akan melakukan simulasi selama 9 jam (8 jam kerja + 1 jam makan siang), dalam gambar. 3 adalah diagram struktural.
Fig. 3. Diagram struktural dari model pekerjaan toilet: di sebelah kiri dengan satu toilet, di sebelah kanan dengan duaDi sebelah kiri adalah model dengan satu toilet, di sebelah kanan dengan dua. Berikut ini adalah kode model.
waterclosetsim := NewPipeline("Water Closet Simulation", false) office := NewGenerator("Office", 0, 0, 0, 10, nil) wantToToilet:= NewAdvance("Wanted to use the toilet", 90, 60) pathToWC := NewAdvance("Path to WC", 5, 3) queue := NewQueue("Queue to the WC") pathFromWC := NewAdvance("Path from WC", 5, 3) wc := NewFacility("WC", 15, 10) pathToOffice:= NewAdvance("Path from WC", 5, 3) waterclosetsim.Append(office, wantToToilet) waterclosetsim.Append(wantToToilet, pathToWC) waterclosetsim.Append(pathToWC, queue) waterclosetsim.Append(queue, wc) waterclosetsim.Append(wc, pathFromWC) waterclosetsim.Append(pathFromWC, wantToToilet) waterclosetsim.Start(540) <-waterclosetsim.Done waterclosetsim.PrintReport()
Hasil simulasi adalah sebagai berikut.Nama pipa "Simulasi Lemari Air"
Waktu simulasi 540
Nama objek "Kantor"
Dihasilkan 10
Nama objek "Path from WC"
Uang muka rata-rata 5,77
Nama objek "Jalur ke WC"
Uang muka rata-rata 5,22
Nama objek "Antrian ke WC"
Konten maks. 4
Total entri 36
Tidak ada entri 8
Entri nol entri 22,22%
Isi saat ini 4
Konten rata-rata 1,78
Waktu rata-rata / trans 24,11
Rata-rata waktu / trans tanpa entri nol 31,00
Nama objek "WC"
Uang muka rata-rata 14,69
Pemanfaatan rata-rata 87,04
Entri angka 32,00
Transaksi 2 dalam fasilitas
Nama objek "Ingin menggunakan toilet"
Uang muka rata-rata 95,85
Ada hingga 4 orang dalam antrean, 8 kali seseorang langsung masuk ke toilet, selama hari kerja toilet digunakan sebesar 87,04%. Yang paling penting, menurut saya, adalah orang-orang menunggu sekitar setengah jam (31 menit) dalam antrean untuk toilet. Mungkin ini disebabkan oleh fakta bahwa hanya ada satu toilet, dan mungkin karena fakta bahwa rata-rata orang duduk di dalamnya selama 14,69 menit.
Setelah menambahkan toilet lain, saya melihat bahwa antrian berkurang menjadi 3 orang, 29 kali orang langsung masuk toilet. Tetapi yang paling penting, ekspektasi menurun hampir tiga kali lipat.
Kesimpulan
Kerangka yang dibuat pada lutut cukup sederhana dan masih terbatas. Berencana untuk meningkatkan fungsinya ke level GPSS. Nilai praktis dari kerangka kerja adalah kemampuan untuk dengan cepat dan mudah merakit model simulasi di Go dan mendapatkan hasil.
Kode diposting di GitHub .