/* S0950.java * 多段待時式のシステム * (C) H.Ishikawa 2008 */ package simulation; import java.applet.*; import java.awt.*; import java.text.DecimalFormat; public class S0950 extends Applet{ int L = 3; /* サービスの段数 */ double A = 5.0; /* 平均到着間隔 */ int SIZE = 5; /* ヒストグラムの大きさ */ int MOD = 128; /* 客の番号の最大値 */ int NN_END = 10000; /* シミュレーションを終る客の数 */ double INF = 1.0e100; /* 十分大きい値 */ double EPS = 1.0e-100; /* 十分小さい値 */ public void paint(Graphics g) { double tt = 0.0; /* シミュレーション時刻 */ int i; /* サービス段に対するforのカウンタ */ int k; /* チャンネルに対するforのカウウタ */ int u; /* ヒストグラムに対するforのカウンタ */ int ii; /* 待行列の順番に対するforのカウウタ */ int n[] = {0, 4, 4, 3}; /* 各段ごとのチャンネル数 */ double h[] = {0.0, 10.0, 8.0, 8.0}; /* 各段ごとの平均サービス時間 */ int sn[][] = new int[L + 1][10]; /* サービスチャンネルの状態 * sn[i][k]==0:i段目のkチャンネルは空き * sn[i][k]==mm: 客mmをサービス中 */ double tn[][] = new double[L + 1][10]; /* サービスチャンネルが次に変化を起こすまでの時間 */ double ta[] =new double[MOD + 1]; /* 客ごとの到着時刻 */ int q[] = new int[L + 1] ; /* 各段ごとの待ち行列の長さ */ int sq[][] = new int[L + 1][20]; /* 各段ごとの待ち行列のii番目にならんでいる客の番号 */ int mm = 0; /* 客の番号 1からMODまで */ int nn = 0; /* サービスを終えた客の数 */ double tm; /* 次に客が到着するまでの時間 */ double ts; /* 全サービスを受けたトータルの時間 */ double fr[] = new double[100]; /* tsの分布 */ double x = 0.0; /* tsの和 */ double x2 = 0.0; /* tsの自乗和 */ double at; /* 次に状態の変化が起るまでの時間 */ int l = 12; /* 表示行 */ DecimalFormat exFormat1 = new DecimalFormat(" 0.00000"); /* 初期設定 */ tm = - A * Math.log(1.0 - Math.random()); for (i = 1; i <= L; i ++) { for (k = 1; k <= n[i]; k ++) { sn[i][k] = 0; tn[i][k] = INF; } } /* 開始 */ while (nn <= NN_END) { /* (1)到着 */ if (Math.abs(tm) < EPS) { if (mm < MOD) { mm = mm + 1; } else { mm = 1; } tm = - A * Math.log(1.0 - Math.random()); q[1] = q[1] + 1; sq[1][q[1]] = mm; /* 1段目の待行列にならぶ */ ta[mm] = tt; } /* (2)サービス */ for (i = 1; i <= L; i ++) { /* すべての段に対し */ for (k = 1; k <= n[i]; k ++) { /* すべてのチャンネルをスキャン */ if (Math.abs(tn[i][k]) < EPS) { /* チャンネルが空いた時 */ if (i < L) { q[i + 1] = q[i + 1] + 1; /* 次の段にならぶ */ sq[i + 1][q[i + 1]] = sn[i][k]; } else { /* (5)最後の段の場合統計をとる */ ts = tt - ta[sn[i][k]]; x = x + ts; x2 = x2 + ts * ts; fr[(int)(ts / SIZE)] = fr[(int)(ts / SIZE)] + 1;/* ヒストグラム */ nn = nn + 1; } } else if (sn[i][k] != 0) { /* そのチャンネルがビジーの時は */ continue; /* つぎのkを見に行く */ } if (q[i] > 0) { /* (3)待行列から取り出す処理 */ sn[i][k] = sq[i][1]; tn[i][k] = - h[i] * Math.log(1.0 - Math.random()); q[i] = q[i] - 1; if (q[i] > 0) { for (ii = 1; ii <= q[i]; ii++) { sq[i][ii] = sq[i][ii + 1]; } } } else { /* 待行列に誰もいない */ sn[i][k] = 0; tn[i][k] = INF; } } } /* 次に状態変化の起る時刻を求める */ at = INF; if (tm < at) at = tm; for (i = 1; i <= L; i ++) { for (k = 1; k <= n[i]; k++) { if (tn[i][k] < at) at = tn[i][k]; } } /* (4)時間を進める */ tm = tm - at; for (i = 1; i <= L; i ++) { for (k = 1; k <= n[i]; k ++) { tn[i][k] = tn[i][k] - at; } } tt =tt + at; } /* ヒストグラムの出力 */ g.drawString(" ts fr[ts]", 10, l); l = l + 12; for (u = 0; u < 19 ; u++) { g.drawString(" " + u*SIZE + "-" + (u+1)*SIZE + " "+ exFormat1.format((double)(fr[u])/NN_END), 10, l);l = l + 12; } g.drawString("全サービスを受けた平均時間 =" + exFormat1.format(x / NN_END), 10, l);l = l +12; g.drawString("その標準偏差 =" + exFormat1.format(Math.sqrt((x2 - x * x / NN_END) / NN_END)), 10, l);l = l + 12; } }