Diperkenalkan:
Beberapa waktu yang lalu, saya pergi ke bank untuk menangani bisnis, dan ada begitu banyak orang yang mengantri. Butuh waktu kurang dari 5 menit untuk menangani bisnis sendiri, tetapi saya menunggu selama dua jam (saya percaya banyak orang telah mengalami situasi ini). Saya terdiam tentang tingkat layanan ini, tetapi masalahnya muncul lagi. Bank harus membuka beberapa jendela untuk memastikan kualitas layanan secara keseluruhan dan tingkat pemanfaatan sumber daya? Selanjutnya, kami akan mensimulasikan masalah ini melalui teori antrian.
Pengantar teori antrian
Teori antrian adalah teori dan metode matematika yang mempelajari fenomena pengumpulan acak dan dispersi sistem dan rekayasa kerja sistem acak. Ia juga dikenal sebagai teori sistem layanan acak, dan merupakan cabang penelitian operasi. Mari kita sederhanakan teori antrian di bawah ini, dan lihat angka berikut terlebih dahulu:
Kami mengatur beberapa meja layanan biru di sisi kiri gambar, dengan pelanggan merah yang mungkin datang di sebelah kanan, dan ruang tunggu kuning di tengah. Jika meja layanan menganggur, pelanggan dapat secara langsung menerima layanan, jika tidak mereka harus menunggu di area kuning. Urutan Layanan Pelanggan mengadopsi prinsip layanan datang pertama dan saat ini. Sekarang jika kita mengetahui distribusi probabilitas pelanggan yang datang, lalu bagaimana kita dapat mengatur beberapa meja layanan di sebelah kiri untuk mencapai tingkat layanan yang lebih baik dan memastikan tingkat penggunaan meja layanan? Selanjutnya, kami akan membangun model untuk mensimulasikan masalah ini.
Teori antrian diimplementasikan langkah demi langkah
1) Untuk teori antrian, pertama -tama kita perlu menentukan atribut pelanggan, tahu kapan pelanggan tiba, waktu layanan diperlukan, dll. Kami pertama -tama membuat kelas pelanggan, di mana kami menentukan waktu maksimum dan minimum untuk layanan pelanggan. Di sini, untuk menyederhanakan, kami secara langsung berpikir bahwa waktu layanan sepenuhnya acak:
Public Class CustomerBean {// Waktu Layanan Minimum Private Static Int MinServetime = 3 * 1000; // waktu layanan maksimum private static int maxServetime = 15 * 1000; // Pelanggan mencapai waktu kedatangan long pribadi; // Pelanggan membutuhkan waktu layanan pribadi int servetime; pelanggan publik () {// atur kedatangan kedatangan kedatangan = system.currentTimeMillis (); // ACTE AT LAYANAN PELANGGAN LAYANAN SERVETIME = (INT) (Math.Random () * (MaxServetime - MinServetime) + MinServerime); }} 2) Kami mendefinisikan pelanggan di atas, dan kemudian kami perlu menentukan antrian antrian. Pertama -tama mari kita lihat atribut antrian. Di sini kami mendefinisikan array untuk menyelamatkan pelanggan yang antri, menentukan interval waktu minimum dan maksimum bagi pelanggan berikutnya untuk tiba dan probabilitas pelanggan datang (untuk dijelaskan secara singkat di sini, jika waktu interval dari pelanggan berikutnya adalah 3, tetapi jumlah yang lebih besar dan dipenuhi oleh pelanggan.
customer customerquene kelas publik {// menunggu antrian pelanggan linkedlist pribadi <sust customerbean> customer = new LinkedList <CelangganBean> (); // Waktu terpendek bagi pelanggan berikutnya untuk datang secara pribadi int mintime = 0; // Waktu maksimum bagi pelanggan berikutnya untuk datang secara pribadi int maxTime = 1 * 1000; // Probabilitas pelanggan yang akan datang tarif ganda pribadi = 0,9; // Identifikasi apakah bendera boolean pribadi pelanggan = true; // Jumlah maksimum orang antri int private int maxwaitnum = 0; } 3) Ketika ada pelanggan dan antrian, kami mengatur utas untuk menghasilkan pelanggan untuk terus menghasilkan pelanggan. Berikut adalah distribusi waktu dan probabilitas yang kami sebutkan di atas.
/ ***@Deskripsi: Hasilkan utas pelanggan*@Versi: 1.1.0*/ kelas privat Pelanggantread memperluas utas {private customerthread (nama string) {super (name); } @Override public void run () {while (flag) {// Tambahkan pelanggan baru di akhir tim if (math.random () <rate) {customers.addlast (customerbean baru ()); if (maxwaitnum <customers.size ()) {maxwaitnum = customers.size (); }} int sleepTime = (int) (math.random () * (maxTime - mintime) + mintime); coba {timeunit.milliseconds.sleep (sleeptime); } catch (Exception e) {E.PrintStackTrace (); }}}}} 4) Jika ada pelanggan dalam antrian antrian untuk memotong meja layanan gratis, Anda perlu mendapatkan pelanggan di kepala tim untuk menerima layanan.
Pelanggan yang disinkronkan publik getCustomerBean () {if (customer == null || customer.size () <1) {return null; } return customer.removefirst (); } 5) Atribut dan metode terkait pelanggan semuanya siap. Mari atur atribut terkait Meja Layanan. Di sini kami langsung mengatur meja layanan ke utas untuk menentukan beberapa indikator layanan, seperti jumlah pelanggan yang dilayani, total waktu tunggu, total waktu layanan, waktu tunggu maksimum, dll.
Kelas Publik ServantThread memperluas utas {// Jumlah pelanggan layanan private static int customernum = 0; // Total Waktu Tunggu Private Static Int SumwaitTime = 0; // Total waktu layanan private static int sumServetime = 0; // waktu tunggu maksimum private static int maxwaittime = 0; bendera boolean pribadi = false; nama string pribadi; } 6) Pekerjaan utama dari meja layanan adalah melayani pelanggan. Di sini kami menulis operasi yang terkait dengan melayani pelanggan ke dalam metode run utas.
public void run () {flag = true; while (flag) {customerbean customer = customerquene.getCustomerquene (). getCustomerBean (); // Jika utas pelanggan telah ditutup dan tidak ada pelanggan dalam antrian, utas meja layanan ditutup dan dirilis jika (customer == null) {if (! Customerquene.getcustomerquene (). IsFlag ()) {flag = false; mencetak(); } melanjutkan; } long now = system.currentTimeMillis (); int waittime = (int) (sekarang - customer.getArrivetime ()); // Simpan waktu tunggu maksimum jika (WaitTime> maxWaitTime) {maxWaittime = WaitTime; } // Waktu tidur adalah waktu layanan pelanggan, yang mewakili periode layanan selama periode waktu ini melayani pelanggan. Coba {timeunit.milliseconds.sleep (customer.getServetime ()); } catch (Exception e) {E.PrintStackTrace (); } System.err.println (Nama + "Waktu untuk melayani pelanggan:" + customer.getServeServetime () + "MS/T Pelanggan menunggu:" + WaitTime + "MS"); Customernum ++; SumwaitTime += WaitTime; sumServerMe += customer.getServetime (); }} 7) Akhirnya, kami menulis model tes untuk memverifikasi tingkat layanan
/ ** *@Deskripsi: */ paket com.lulei.opsearch.quene; impor java.util.concurrent.timeunit; tes kelas publik {public static void main (string [] args) {// buka pintu sistem.out.println ("Buka pintu dan ambil pelanggan!"); bendera boolean = true; Customerquene.getcustomerquene (); long a = system.currentTimemillis (); int servicenum = 10; untuk (int i = 0; i <servicenum; i ++) {servantThread thread = new ServantThread ("Layanan Desk"+i); thread.start (); } while (flag) {long b = system.currentTimeMillis (); if (b - a> 1 * 60 * 1000 && flag) {// tutup bendera = false; Customerquene.getcustomerquene (). Close (); System.out.println ("Tutup pintu dan jangan menjemput pelanggan!"); } System.out.println ("Sistem waktu berjalan:" + (b -a) + "ms"); System.out.println ("Sistem waktu idle:" + ((b -a) * servantnum - servantThread.getSumSerVetime ())); Servantthread.print (); coba {timeunit.seconds.sleep (2); } catch (Exception e) {E.PrintStackTrace (); }}}} Hasil berjalan
1) Mulai operasi
2) Pelanggan menghasilkan penutupan utas
3) Tingkat Layanan Akhir
Dengan memodifikasi jumlah meja layanan, Anda dapat mengevaluasi berapa banyak meja layanan yang harus diatur dalam situasi pelanggan saat ini.
Kode lengkap
1) Kategori Pelanggan
/ ** *@Deskripsi: */ paket com.lulei.opsearch.quene; Public Class CustomerBean {// Waktu Layanan Minimum Private Static Int MinServetime = 3 * 1000; // waktu layanan maksimum private static int maxServetime = 15 * 1000; // Pelanggan mencapai waktu kedatangan long pribadi; // Pelanggan membutuhkan waktu layanan pribadi int servetime; pelanggan publik () {// atur kedatangan waktu kedatangan = system.currentTimeMillis (); // Atur secara acak waktu layanan pelanggan servetime = (int) (math.random () * (maxservetime - minservetime) + minServetime); } public static int getMinserVetime () {return minservetime; } public static void setMinserVetime (int minSerVetime) {customerBean.minservetime = minservetime; } public static int getMaxServetime () {return maxServetime; } public static void setMaxSerVetime (int maxServetime) {customerBean.maxServetime = maxServetime; } public long getArrivetime () {return arrivetime; } public void setArrivetime (long arrivetime) {this.arrivetime = arrivetime; } public int getServetime () {return servetime; } public void setSerVetime (int servetime) {this.servetime = servetime; }}2) Antrian pelanggan
/ ** *@Deskripsi: */ paket com.lulei.opsearch.quene; impor java.util.linkedlist; impor java.util.concurrent.timeunit; customer customerquene kelas publik {// menunggu antrian pelanggan linkedlist pribadi <sust customerbean> customer = new LinkedList <CelangganBean> (); // Waktu terpendek bagi pelanggan berikutnya untuk datang secara pribadi int mintime = 0; // Waktu maksimum bagi pelanggan berikutnya untuk datang secara pribadi int maxTime = 1 * 1000; // Probabilitas Tarif Ganda Privat Pelanggan yang Datang = 0,9; // Identifikasi apakah pelanggan terus menghasilkan bendera boolean pribadi = true; // Jumlah maksimum orang antri int private int maxwaitnum = 0; publik int getmaxwaitnum () {return maxwaitnum; } public boolean isFlag () {return flag; } / ** * @return * @author: lulei * @description: Dapatkan pelanggan di kepala antrian * / pelanggan yang disinkronkan publik getCustomerBean () {if (customer == null || customer.size () <1) {return null; } return customer.removefirst (); } public void close () {if (flag) {flag = false; }} / ** * @return * @author: lulei * @description: Dapatkan jumlah pelanggan yang menunggu * / int getWaitCustomernum () {return customer.size (); } / ***@Deskripsi: Hasilkan utas pelanggan*@versi: 1.1.0* / kelas privat Pelanggantread memperluas utas {customerthread private (nama string) {super (name); } @Override public void run () {while (flag) {// Tambahkan pelanggan baru di akhir tim if (math.random () <rate) {customers.addlast (customerbean baru ()); if (maxwaitnum <customers.size ()) {maxwaitnum = customers.size (); }} int sleepTime = (int) (math.random () * (maxTime - mintime) + mintime); coba {timeunit.milliseconds.sleep (sleeptime); } catch (Exception e) {E.PrintStackTrace (); }}}}} // mode singleton Mulai kelas privat statis customerqueneen {customerquene customerquene customerquene = new customerquene (); } customerquene private () {customerthread customerthread = new customerthread ("customer generasi utas"); customerthread.start (); } public static customerquene getCustomerQuene () {return customerqueneen.customerquene; } // mode singleton end public int getMinTime () {return mintime; } public void setMinTime (int mintime) {this.mintime = mintime; } public int getMaxTime () {return maxTime; } public void setmaxTime (int maxTime) {this.maxTime = maxTime; } public double getRate () {laju pengembalian; } public void setrate (laju ganda) {this.rate = rate; }} 3) Benang Meja Layanan
/ ** *@Deskripsi: */ paket com.lulei.opsearch.quene; impor java.util.concurrent.timeunit; impor com.lulei.util.parseutil; Kelas Publik ServantThread memperluas utas {// Jumlah pelanggan layanan private static int customernum = 0; // Total Waktu Tunggu Private Static Int SumwaitTime = 0; // Total waktu layanan private static int sumServetime = 0; // waktu tunggu maksimum private static int maxwaittime = 0; bendera boolean pribadi = false; nama string pribadi; Public hambaThread (name string) {super (name); this.name = name; } public static int getmaxWaittime () {return maxwaittime; } public static int getSUMSerVetime () {return sumServetime; } @Override public void run () {flag = true; while (flag) {customerbean customer = customerquene.getCustomerquene (). getCustomerBean (); // Jika utas pelanggan telah ditutup dan tidak ada pelanggan dalam antrian, utas meja layanan ditutup dan dirilis jika (customer == null) {if (! Customerquene.getcustomerquene (). IsFlag ()) {flag = false; mencetak(); } melanjutkan; } long now = system.currentTimeMillis (); int waittime = (int) (sekarang - customer.getArrivetime ()); // Simpan waktu tunggu maksimum jika (WaitTime> maxWaitTime) {maxWaittime = WaitTime; } // Waktu tidur adalah waktu layanan pelanggan, yang mewakili cobalah pelanggan {timeunit.milliseconds.sleep (customer.getServetime ()); } catch (Exception e) {E.PrintStackTrace (); } System.err.println (Nama + "Waktu untuk melayani pelanggan:" + customer.getServetime () + "MS/T Pelanggan menunggu:" + WaitTime + "ms"); Customernum ++; SumwaitTime += WaitTime; sumServerMe += customer.getServetime (); }} public static void print () {if (customerNum> 0) { System.out.println ("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // output waktu tunggu rata -rata pelanggan, dan mempertahankan dua tempat desimal System.out.println ("Waktu tunggu rata -rata untuk pelanggan:" + parseutil.parsedubleTodouble ((sumwaitTime * 1.0 /customernum (2) + "ms"); / customernum), 2) + "ms"); 4) Uji model
/ ** *@Deskripsi: */ paket com.lulei.opsearch.quene; impor java.util.concurrent.timeunit; tes kelas publik {public static void main (string [] args) {// buka pintu sistem.out.println ("Buka pintu dan ambil pelanggan!"); bendera boolean = true; Customerquene.getcustomerquene (); long a = system.currentTimemillis (); int servicenum = 10; untuk (int i = 0; i <servicenum; i ++) {servantThread thread = new ServantThread ("Layanan Desk"+i); thread.start (); } while (flag) {long b = system.currentTimeMillis (); if (b - a> 1 * 60 * 1000 && flag) {// tutup bendera = false; Customerquene.getcustomerquene (). Close (); System.out.println ("Tutup pintu dan jangan menjemput pelanggan!"); } System.out.println ("Sistem waktu berjalan:" + (b -a) + "ms"); System.out.println ("Sistem waktu idle:" + ((b -a) * servantnum - servantThread.getSumSerVetime ())); Servantthread.print (); coba {timeunit.seconds.sleep (2); } catch (Exception e) {E.PrintStackTrace (); }}}}Di atas adalah pengantar terperinci tentang prinsip -prinsip Java yang menerapkan teori antrian. Saya berharap ini akan membantu untuk pembelajaran semua orang.