/* A0910.java 9章1.解答 * 待時式入線無限大のシステム * (待ち合わせ制限あり) * (C) H.Ishikawa 2008 */ package simulation; import java.applet.*; import java.awt.*; import java.text.DecimalFormat; public class A0910 extends Applet{ int N = 5; /* サービスチャンネル数 */ double A = 20.0; /* 平均到着間隔 */ double H = 80.0; /* 平均サービス時間 */ int Q_LENGTH = 5 ; /* 待行列の最大の長さ */ double T_END = 1000000.0; /* シミュレーションを終る時刻 */ double INF = 1.0e100; /* 十分大きい値 */ double EPS = 1.0e-100; /* 十分小さい値 */ double P0 = 0.2; /* あきらめて立ち去る確率 */ double P1 = 0.4; /* あきらめて立ち去る確率 */ double P2 = 0.8; /* あきらめて立ち去る確率 */ public void paint(Graphics g) { double tt = 0.0; /* シミュレーション時刻 */ int i, j, k; /* forのカウンタ */ int sn[] = new int[N + 1]; /* サービスチャンネルの状態 sn[k]==0:空き,sn[k]==1:ビジー*/ double tn[] = new double[N +1]; /* サービスチャンネルが次に変化を起こすまでの時間 */ double an[] = new double[N + 1]; /* サービスチャンネルの稼働率 */ double tq[] = new double[Q_LENGTH + 5]; /* 待ち行列についた時刻 */ double fq[] = new double[Q_LENGTH + 5]; /* 待ち行列が長さqである割合 */ int q = 0; /* 待ち行列の長さ */ int nn = 0; /* サービスを終えた客の数 */ int mm = 0; /* あきらめて立ち去った客の数 */ double tm; /* 次に客が到着するまでの時間 */ double tw; /* 待ち時間 */ double x = 0.0; /* twの和 */ double x2 = 0.0; /* twの自乗和 */ double at; /* 時刻増分 */ int l = 10; /* 表示行 */ DecimalFormat exFormat1 = new DecimalFormat(" 0.00000"); /* 初期設定 */ tm = - A * Math.log(1.0 - Math.random()); for (k = 1; k <= N; k ++) { sn[k] = 0; tn[k] = INF; } /* 開始 */ while (tt <= T_END) { /* 到着 */ if (Math.abs(tm) < EPS) { tm = - A * Math.log(1.0 - Math.random()); if (q < Q_LENGTH) { q = q + 1; tq[q] = tt; } else if ((q == Q_LENGTH) && (P0 < Math.random())) {/* 以下をs0921.cから修正 */ q = q + 1; tq[q] = tt; } else if ((q == Q_LENGTH + 1) && (P1 < Math.random())) { q = q + 1; tq[q] = tt; } else if ((q == Q_LENGTH + 2) && (P2 < Math.random())) { q = q + 1; tq[q] = tt; } else { mm = mm + 1; } } /* サービス */ for (k = 1; k <= N; k++) { if (Math.abs(tn[k]) < EPS || sn[k] == 0 ) { /* tn[k]が0あるいはサービスチャンネルが空きのとき*/ if (q > 0) { sn[k] = 1; tn[k] = - H / 2.0 * Math.log(Math.random() * Math.random()); /* 保留時間はアーラン分布 */ tw = tt - tq[1]; x = x + tw; x2 = x2 + tw * tw; nn = nn + 1; q = q - 1; if (q > 0) { for (i = 1; i <= q; i ++) { tq[i] = tq[i + 1]; } } } else { sn[k] = 0; tn[k] = INF; } } } /* 次に状態変化の起る時刻を求める */ at = INF; if (tm < at) at = tm; for (k = 1; k <= N; k++) { if (tn[k] < at) at = tn[k]; } /* 時間を進める */ tm = tm - at; for (k = 1; k <= N; k++) { tn[k] = tn[k] - at; if (sn[k] > 0) { an[k] = an[k] + at;} } fq[q] = fq[q] + at; tt =tt + at; } /* 出力 */ for (k = 1; k <= N; k ++) { g.drawString(" an[" + k + "] =" + " " + exFormat1.format(an[k] / T_END) ,10 ,l); l = l + 12; } l = l + 12; for (q = 0; q <= Q_LENGTH + 4; q ++) { g.drawString(" fq[" + q + "] =" + " " + exFormat1.format(fq[q] / T_END) ,10 ,l); l = l + 12; } l = l + 12; g.drawString("平均待ち時間 =" + exFormat1.format(x / nn),10 , l); l = l + 12; g.drawString("待ち時間の標準偏差 =" + exFormat1.format(Math.sqrt((x2 - x * x / nn) / nn)) , 10 ,l); l = l + 12; g.drawString("サービスを受けた客の数 = " + nn, 10 , l); l = l + 12; g.drawString("あきらめて立ち去った客の数 = " + mm, 10, l); } }