/* A0830.java 8章3.解答 * 機械修理の問題 (変化点方式 グラフと統計出力) * (C) H.Ishikawa 2008 */ package simulation; import java.applet.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; import window.Window; public class A0830 extends Applet implements ActionListener{ Button button0; Button button1; boolean sw = false; public void init() { button0 = new Button(" 実行 "); button1 = new Button("クリア"); add(button0); add(button1); button0.addActionListener(this); button1.addActionListener(this); } public void actionPerformed(ActionEvent e) { String label = e.getActionCommand(); if (label.equals(" 実行 ")) sw = true; else sw = false; repaint(); } public void paint(Graphics g) { Window w; w = new Window(); int height; int width; int SPACE = 30; int M = 5; /* 機械の台数 */ int N = 2; /* 修理者の人数 */ double A = 10.0; /* 平均故障発生間隔 */ double H = 4.0; /* 平均修理時間 */ double DT = 0.5; /* 時刻増分 */ double T_END = 10000.0; /* シミュレーションを終る時刻 */ double INF = 1.0e100; /* 十分大きい値 */ double EPS = 1.0e-100; /* 十分小さい値 */ double tt = 0.0; /* シミュレーションクロック */ int i; /* 待ち行列のforのカウンタ */ int j; /* 機械のforのカウンタ */ int k; /* 修理者のforのカウンタ */ int q = 0; /* 待ち行列の長さ */ int l = 50; /* 表示行 */ int sm[] = new int[M + 1]; /* 機械jの状態 */ double tm[] = new double[M + 1]; /* 機械に次の状態変化が起るまでの時間 */ int sn[] = new int[N + 1]; /* 修理者kの状態 */ double tn[] = new double[N + 1]; /* 修理者に次の状態変化が起るまでの時間 */ int sq[] = new int[M + 1]; /* 待ち行列 */ double p[] = new double[M + 1]; /* 機械がf台故障している時間の割合 */ double at; /* 時刻増分 */ double am[] = new double[M + 1]; /* 機械の稼働時間 */ double an[] = new double[N + 1]; /* 修理者の稼働時間 */ double tq[] = new double[M + 1]; /* 待行列にならんだ時刻 */ double pf[] = new double[M + 1]; /* 機械の故障している時間 */ int fr[] = new int[50]; /* uの頻度 */ int ff = 0; /* ある時刻における故障機械の台数 */ int nn = 0; /* 修理した機械の台数 */ int u; /* twの整数部分 */ double tw; /* 待ち時間 */ double x = 0; /* twの和 */ double x2 = 0; /* twの自乗和 */ DecimalFormat exFormat1 = new DecimalFormat(" 0.0000"); /* スクリーンの大きさを読み取る */ width = getSize().width; height = getSize().height; /* グラフィックの準備 */ w.setWindow(0, 0.0,0.0,T_END,0.5, 5 * SPACE,height-SPACE,width-SPACE, SPACE); w.axis(0, "時刻", T_END/10, "p[ j ]", 0.1, g); w.moveTo(0, 0.0, 0.0, g); if (sw == true) { /* 初期設定 */ for (j = 1; j <= M; j ++) { sm[j] = 0; tm[j] = -A * Math.log(1 - Math.random()); } for (k = 1; k <= N; k ++) { sn[k] = 0; tn[k] = INF; } /* 開始 */ while (tt <= T_END) { /* 故障発生 */ for (j = 1; j <= M; j ++) { if (Math.abs(tm[j]) < EPS) { // 機械jが故障発生 sm[j] = 1; tm[j] = INF; q = q + 1; sq[q] = j; tq[q] = tt; } } /* 故障修理 */ for (k = 1; k <= N; k ++) { if (Math.abs(tn[k]) < EPS) { // 修理者kの修理が完了 sm[sn[k]] = 0; tm[sn[k]] = -A * Math.log(1 - Math.random()); } if (Math.abs(tn[k]) 0) { // 待ち行列を取り出す sn[k] = sq[1]; tn[k] = -H * Math.log(1 - Math.random()); tw = tt - tq[1]; u = (int)tw; x = x + tw; x2 = x2 + tw * tw; fr[u] = fr[u] + 1; nn = nn + 1;q = q - 1; if (q > 0) { for (i = 1; i <= q; i ++) { sq[i] = sq[i + 1]; tq[i] = tq[i + 1]; } } } else { // 待ち行列が空なら修理者kは未稼働状態になる sn[k] = 0; tn[k] = INF; } } } /* 次に状態変化の起る時刻を求める */ at = INF; for (j = 1; j <= M; j ++) { if (tm[j] < at) at = tm[j]; } for (k = 1; k <= N; k++) { if (tn[k] < at) at = tn[k]; } for (j = 1; j <= M; j ++) { tm[j] = tm[j] - at; if (sm[j] == 1) { ff = ff + 1;} if (sm[j] == 0) { am[j] = am[j] + at;} } for (k = 1; k <= N; k++) { tn[k] = tn[k] - at; if (sn[k] > 0) { an[k] = an[k] + at;} } pf[ff] = pf[ff] + at; ff = 0; tt = tt+ at; /* グラフ表示 */ for (j = 0; j <= M; j ++) { g.setColor(Color.getHSBColor((float)( j / 10.0), (float)1.0, (float)1.0)); // 機械台数ごとに色を変えて表示 w.putPixel(0, tt, ((double)pf[j] / tt), g); } } /* 結果出力 */ g.setColor(Color.black); g.drawString("故障している時間の割合", 10, l); l = l + 12; for (j = 0; j <= M; j ++) { g.setColor(Color.getHSBColor((float)( j / 10.0), (float)1.0, (float)1.0)); g.drawString(" p[" + j + "] =" + exFormat1.format(pf[j] / T_END), 10, l);l = l + 12; } g.setColor(Color.black); g.drawString("機械の稼働率", 10, l); l = l + 12; for (j = 1; j <= M; j ++) { g.setColor(Color.getHSBColor((float)( j / 10.0), (float)1.0, (float)1.0)); g.drawString(" am[" + j + "] =" + exFormat1.format(am[j] / T_END), 10, l);l = l + 12; } g.setColor(Color.black); g.drawString("修理者の稼働率", 10, l); l = l + 12; for (k = 1; k <= N; k ++) { g.drawString(" an[" + k + "] =" + exFormat1.format(an[k] / T_END), 10, l);l = l + 12; } g.drawString("待ち時間の分布", 10, l); l = l + 12; for (u = 0; u <= 9; u ++) { g.drawString(" fr[" + u + "] =" + exFormat1.format((double)fr[u] / nn), 10, l);l = l + 12; } g.drawString("平均待ち時間 =" + exFormat1.format(x / nn), 10, l);l = l + 12; g.drawString("待ち時間の分散 = " + exFormat1.format((x2 - x * x / nn) / nn), 10, l); l = l + 12; } } }