<?php /******************************/ /* 複雑な待ち行列問題 */ /* coded by Y.Suganuma */ /******************************/ /**********************/ /* 指数分布乱数の発生 */ /* m : 平均値 */ /* rerutn : 乱数 */ /**********************/ function Exp_b($m) { return -$m * log(mt_rand() / mt_getrandmax()); } /*********************/ /* クラスInletの定義 */ /*********************/ class Inlet { public $name; // 入り口名 public $out; // 待ち行列名 public $out_n; // 待ち行列番号 public $arrive_time; // 客の到着時刻(負:客がない) public $a_t; // = -n : 到着する客の人数を負の値にしたもの // =0 : 指数分布 // =1 : 一定時間間隔 public $mean; // 到着時間間隔またはその平均 public $que; // 客の到着時刻リスト /*************************************************************/ /* コンストラクタ */ /* name1 : 入り口名 */ /* a_t1; // = -n : 到着する客の人数を負の値にしたもの */ /* // =0 : 指数分布 */ /* // =1 : 一定時間間隔 */ /* m_a: 到着時間間隔またはその平均 */ /* que1 : 客の到着時刻リスト */ /* name2 : 待ち行列名 */ /*************************************************************/ function Inlet ($name1, $a_t1, $m_a, $que1, $name2) { $this->name = $name1; $this->out = $name2; $this->a_t = $a_t1; $this->mean = $m_a; if ($this->a_t == 0) $this->arrive_time = Exp_b($this->mean); else if ($this->a_t == 1) $this->arrive_time = 0; else { $this->que = $que1; $this->arrive_time = array_shift($this->que); } } } /*********************/ /* クラスQueueの定義 */ /*********************/ class Queue { public $name; // 待ち行列名 public $nc; // 待ち行列への到着客数カウンタ public $max_q_l; // 最大待ち行列長 public $c_ql; // 待ち行列長にその長さが継続した時間を乗じた値の累計 public $ql_t; // 現在の待ち行列長になった時間 public $max_wt; // 最大待ち時間 public $c_wt; // 待ち時間の累計 public $n; // =0 : 入り口から入る // >0 : 複数の窓口から入る(窓口数) public $in; // 入り口名,または,窓口名 public $in_n; // 入り口番号,または,窓口番号 public $m; // 処理する窓口数 public $out; // 窓口名 public $out_n; // 窓口番号 public $que; // 待ち行列 /*********************************************/ /* コンストラクタ */ /* name1 : 待ち行列名 */ /* n1 : =0 : 入り口から入る */ /* >0 : 複数の窓口から入る(窓口数) */ /* in1 : 入り口名,または,窓口名 */ /* m1 : 処理する窓口数 */ /* out1 : 窓口名 */ /*********************************************/ function Queue($name1, $n1, $in1, $m1, $out1) { $this->name = $name1; $this->n = $n1; $this->in = $in1; $this->m = $m1; $this->out = $out1; $this->nc = 0; $this->max_q_l = 0; $this->c_ql = 0.0; $this->ql_t = 0.0; $this->max_wt = 0.0; $this->c_wt = 0.0; $this->in_n = array(); $this->out_n = array(); $this->que = array(); } } /**********************/ /* クラスEntityの定義 */ /**********************/ class Entity { public $name; // 窓口名 public $end_time; // サービス終了時刻(負:何も処理していない) public $s_t; // =0 : 指数分布 // =1 : 一定時間 public $mean; // 平均サービス時間 public $busy_t; // 窓口がふさがった時刻 public $c_busy; // 窓口がふさがっている時間の累計 public $service; // サービス中の客番号(0のときは無し) public $in; // 待ち行列(入力)の名前 public $in_n; // 待ち行列(入力)番号 public $to; // =0 : システムの外に出る // =1 : 待ち行列に入る public $out; // 待ち行列(出力)の名前 public $out_n; // 待ち行列(出力)番号 /****************************************/ /* コンストラクタ */ /* name1 : 窓口名 */ /* s_t1; // =0 : 指数分布 */ /* // =1 : 一定時間 */ /* m_s:サービス時間またはその平均 */ /* name2 : 待ち行列(入力)の名前 */ /* sw : =0 : システムの外に出る */ /* =1 : 待ち行列に入る */ /* name3 : 待ち行列(出力)の名前 */ /**********************************+++***/ function Entity($name1, $s_t1, $m_s, $name2, $sw, $name3) { $this->name = $name1; $this->to = $sw; $this->in = $name2; if ($this->to > 0) $this->out = $name3; $this->end_time = -1.0; $this->s_t = $s_t1; $this->mean = $m_s; $this->service = 0; $this->busy_t = -1.0; $this->c_busy = 0.0; } } /************************/ /* クラスCustomerの定義 */ /************************/ class Customer { public $time; // 到着時刻 public $state1; // 客の状態1 // =0 : 待ち行列に入っている // =1 : サービスを受けている public $state2; // 客の状態2(待ち行列番号,または,窓口番号) /*********************/ /* コンストラクタ */ /* s1,s2 : 状態 */ /* t : 到着時刻 */ /*******************************/ function Customer($s1, $s2, $t) { $this->time = $t; $this->state1 = $s1; $this->state2 = $s2; } } /**********************/ /* クラスQ_baseの定義 */ /**********************/ class Q_base { public $p_time; // 現在時刻 public $max_c; // 最大系内客数 public $nc; // システムへの到着客数カウンタ public $now_c_t; // 現在の系内客数になった時間 public $c_now_c; // 系内客数にその数が継続した時間を乗じた値の累計 public $c_sys; // 滞在時間の累計 public $max_sys; // 最大滞在時間 public $end; // シミュレーション終了時間 public $cus; // 系内にいる客のリスト public $inl; // Inletオブジェクトリスト public $que; // Queueオブジェクトリスト public $ent; // Entityオブジェクトリスト /***************************************/ /* コンストラクタ */ /* v_i : Inletオブジェクトリスト */ /* v_q : Queueオブジェクトリスト */ /* v_e : Entityオブジェクトリスト */ /* e : シミュレーション終了時刻 */ /***************************************/ function Q_base($v_i, $v_q, $v_e, $e) { // 接続関係のチェック print("\n"); // Inlet $this->inl = $v_i; $this->que = $v_q; $this->ent = $v_e; for ($i1 = 0; $i1 < count($this->inl)-1; $i1++) { for ($i2 = $i1+1; $i2 < count($this->inl); $i2++) { if ($this->inl[$i1]->name == $this->inl[$i2]->name) exit("***error 同じ名前の入り口があります ".$this->inl[$i1]->name."\n"); } } $k; for ($i1 = 0; $i1 < count($this->inl); $i1++) { $k = -1; for ($i2 = 0; $i2 < count($this->que); $i2++) { if ($this->inl[$i1]->out == $this->que[$i2]->name) { $k = $i2; break; } } if ($k >= 0) $this->inl[$i1]->out_n = $k; else exit("***error 入り口から入る待ち行列名が不適当です ".$this->inl[$i1]->out."\n"); } // Queue for ($i1 = 0; $i1 < count($this->que)-1; $i1++) { for ($i2 = $i1+1; $i2 < count($this->que); $i2++) { if ($this->que[$i1]->name == $this->que[$i2]->name) exit("***error 同じ名前の待ち行列があります ".$this->que[$i1]->name."\n"); } } for ($i1 = 0; $i1 < count($this->que); $i1++) { if ($this->que[$i1]->n == 0) { $k = -1; for ($i2 = 0; $i2 < count($this->inl); $i2++) { if ($this->que[$i1]->in[0] == $this->inl[$i2]->name) { $k = $i2; break; } } if ($k >= 0) array_push($this->que[$i1]->in_n, $k); else exit("***error 待ち行列に入る入り口名が不適当です ".$this->que[$i1]->in[0]."\n"); } else { for ($i2 = 0; $i2 < $this->que[$i1]->n; $i2++) { $k = -1; for ($i3 = 0; $i3 < count($this->ent); $i3++) { if ($this->que[$i1]->in[$i2] == $this->ent[$i3]->name) { $k = $i3; break; } } if ($k >= 0) array_push($this->que[$i1]->in_n, $k); else exit("***error 待ち行列に入る窓口名が不適当です ".$this->que[$i1]->in[$i2]."\n"); } } for ($i2 = 0; $i2 < $this->que[$i1]->m; $i2++) { $k = -1; for ($i3 = 0; $i3 < count($this->ent); $i3++) { if ($this->que[$i1]->out[$i2] == $this->ent[$i3]->name) { $k = $i3; break; } } if ($k >= 0) array_push($this->que[$i1]->out_n, $k); else exit("***error 待ち行列を処理する窓口名が不適当です ".$this->que[$i1]->out[$i2]."\n"); } } // Entity for ($i1 = 0; $i1 < count($this->ent)-1; $i1++) { $k = -1; for ($i2 = $i1+1; $i2 < count($this->ent); $i2++) { if ($this->ent[$i1]->name == $this->ent[$i2]->name) exit("***error 同じ名前の窓口があります ".$this->ent[$i1]->name."\n"); } } for ($i1 = 0; $i1 < count($this->ent); $i1++) { $k = -1; for ($i2 = 0; $i2 < count($this->que); $i2++) { if ($this->ent[$i1]->in == $this->que[$i2]->name) { $k = $i2; break; } } if ($k >= 0) $this->ent[$i1]->in_n = $k; else exit("***error 窓口に入る待ち行列名が不適当です ".$this->ent[$i1]->in."\n"); if ($this->ent[$i1]->to > 0) { $k = -1; for ($i2 = 0; $i2 < count($this->que); $i2++) { if ($this->ent[$i1]->out == $this->que[$i2]->name) { $k = $i2; break; } } if ($k >= 0) $this->ent[$i1]->out_n = $k; else exit("***error 窓口の出口にある待ち行列名が不適当です ".$this->ent[$i1]->out."\n"); } } // 初期設定 $this->p_time = 0.0; $this->max_c = 0; $this->nc = 0; $this->now_c_t = 0.0; $this->c_now_c = 0.0; $this->c_sys = 0.0; $this->max_sys = 0.0; $this->end = $e; $this->cus = array(); // 乱数の初期設定 mt_srand(); } /**************/ /* 全体の制御 */ /**************/ function Control() { $sw = array(2); $sw[0] = 0; while ($sw[0] > -2) { $this->Next($sw); // 次の処理の選択 if ($sw[0] == -1) $sw[0] = $this->End_o_s(); // シミュレーションの終了 else { if ($sw[0] == 0) $this->Arrive($sw[1]); // 客の到着処理 else $this->Service($sw[1]); // サービスの終了 } } } /*********************************************/ /* 次の処理の決定 */ /* sw[0] : =-1 : シミュレーションの終了 */ /* =0 : 客の到着処理 */ /* =1 : 窓口のサービス終了 */ /* [1] : 入り口番号 or 窓口番号 */ /*********************************************/ function Next(&$sw) { $tm = $this->end; // 次の処理時刻 $sw[0] = -1; // 次の客の到着時刻 for ($i1 = 0; $i1 < count($this->inl); $i1++) { $x = $this->inl[$i1]; if ($x->arrive_time >= 0.0 && $x->arrive_time < $tm) { $sw[0] = 0; $sw[1] = $i1; $tm = $x->arrive_time; } } // サービス終了時刻 for ($i1 = 0; $i1 < count($this->ent); $i1++) { $x = $this->ent[$i1]; if ($x->service > 0 && $x->end_time <= $tm) { $sw[0] = 1; $sw[1] = $i1; $tm = $x->end_time; } } if ($sw[0] < 0) $this->end = $this->p_time; } /**********************************/ /* 終了処理 */ /* return : =-1 : 終了前処理 */ /* =-2 : 実際の終了 */ /**********************************/ function End_o_s() { $sw = -2; $this->p_time = $this->end; // 現在時刻 for ($i1 = 0; $i1 < count($this->ent); $i1++) { $x = $this->ent[$i1]; if ($x->service > 0) { // サービス中の客はいるか? if ($sw == -2) { $sw = -1; $this->end = $x->end_time; // 窓口$i1のサービス終了時刻 } else { if ($x->end_time > $this->end) $this->end = $x->end_time; // 窓口$i1のサービス終了時刻 } } } return $sw; } /************************/ /* 客の到着処理 */ /* kk : 入り口番号 */ /************************/ function Arrive($kk) { /* 客数の増加と次の客の到着時刻の設定 */ $this->nc += 1; // 到着客数カウンタ $this->p_time = $this->inl[$kk]->arrive_time; // 現在時刻 if ($this->inl[$kk]->a_t == 0) // 次の客の到着時刻 $this->inl[$kk]->arrive_time = $this->p_time + Exp_b($this->inl[$kk]->mean); else if ($this->inl[$kk]->a_t == 1) $this->inl[$kk]->arrive_time = $this->p_time + $this->inl[$kk]->mean; else { if (count($this->inl[$kk]->que) <= 0) $this->inl[$kk]->arrive_time = -1.0; else $this->inl[$kk]->arrive_time = array_shift($this->inl[$kk]->que); } if ($this->inl[$kk]->arrive_time >= $this->end) $this->inl[$kk]->arrive_time = -1.0; /* 系内客数の処理 */ $this->c_now_c += count($this->cus) * ($this->p_time - $this->now_c_t); // 系内客数にその数が継続した時間を乗じた値の累計 $this->now_c_t = $this->p_time; // 現在の系内客数になった時刻 if (count($this->cus)+1 > $this->max_c) $this->max_c = count($this->cus) + 1; // 最大系内客数 /* 空いている窓口を探す */ $k1 = $this->inl[$kk]->out_n; $this->que[$k1]->nc++; $k = -1; for ($i1 = 0; $i1 < $this->que[$k1]->m; $i1++) { $k2 = $this->que[$k1]->out_n[$i1]; // 処理窓口 if ($this->ent[$k2]->service == 0) { $k = $k2; break; } } /* 窓口に空きがない場合 */ if ($k < 0) { $ct_p = new Customer(0, $k1, $this->p_time); $this->cus['no'.strval($this->nc)] = $ct_p; // 客の登録(系内客数) $this->que[$k1]->c_ql += count($this->que[$k1]->que) * ($this->p_time - $this->que[$k1]->ql_t); // 待ち行列長にその長さが継続した時間を乗じた値の累計 array_push($this->que[$k1]->que, $this->nc); // 客の登録(待ち行列) $this->que[$k1]->ql_t = $this->p_time; // 現在の待ち行列長になった時刻 if (count($this->que[$k1]->que) > $this->que[$k1]->max_q_l) $this->que[$k1]->max_q_l = count($this->que[$k1]->que); // 最大待ち行列長 } /* すぐサービスをうけられる場合 */ else { $ct_p = new Customer(1, $k, $this->p_time); $this->cus['no'.strval($this->nc)] = $ct_p; // 客の登録(系内客数) $this->ent[$k]->service = $this->nc; // サービスを受けている客番号 $this->ent[$k]->busy_t = $this->p_time; // 窓口がふさがった時刻 if ($this->ent[$k]->s_t == 0) // 窓口のサービス終了時刻 $this->ent[$k]->end_time = $this->p_time + Exp_b($this->ent[$k]->mean); else $this->ent[$k]->end_time = $this->p_time + $this->ent[$k]->mean; } } /**********************************/ /* サービス終了時の処理 */ /* kk : サービス終了窓口番号 */ /**********************************/ function Service($kk) { /* 時間の設定 */ $this->p_time = $this->ent[$kk]->end_time; // 現在時刻 $this->ent[$kk]->end_time = -1.0; // サービス終了時間 /* システムの外へ出る場合 */ if ($this->ent[$kk]->to == 0) { /* 系内客数の処理 */ $this->c_now_c += count($this->cus) * ($this->p_time - $this->now_c_t); // 系内客数にその数が継続した時間を乗じた値の累計 $this->now_c_t = $this->p_time; // 現在の系内客数になった時刻 /* 滞在時間の処理 */ $it = $this->cus['no'.strval($this->ent[$kk]->service)]; // サービス中の客 $x1 = $this->p_time - $it->time; $this->c_sys += $x1; // 滞在時間の累計 if ($x1 > $this->max_sys) $this->max_sys = $x1; // 最大滞在時間 unset($this->cus['no'.strval($this->ent[$kk]->service)]); // 客の削除(系内客数) } /* 他の窓口処理へ入る場合の処理 */ else { $k1 = $this->ent[$kk]->out_n; $this->que[$k1]->nc++; $sw = 1; $k2 = 0; if (count($this->que[$k1]->que) == 0) { for ($i1 = 0; $i1 < $this->que[$k1]->m; $i1++) { $k2 = $this->que[$k1]->out_n[$i1]; // 窓口 if ($this->ent[$k2]->service == 0) { $sw = 0; break; } } } /* 待ち行列がある場合 */ if ($sw > 0) { $this->que[$k1]->c_ql += count($this->que[$k1]->que) * ($this->p_time - $this->que[$k1]->ql_t); // 待ち行列長にその長さが継続した時間を乗じた値の累計 array_push($this->que[$k1]->que, $this->ent[$kk]->service); // 客の登録(待ち行列) $this->que[$k1]->ql_t = $this->p_time; // 現在の待ち行列長になった時刻 if (count($this->que[$k1]->que) > $this->que[$k1]->max_q_l) $this->que[$k1]->max_q_l = count($this->que[$k1]->que); // 最大待ち行列長 $it = $this->cus['no'.strval($this->ent[$kk]->service)]; $it->state1 = 0; // 客の状態変更(待ち行列) $it->state2 = $this->ent[$kk]->out_n; // 客の状態変更(待ち行列番号) } /* すぐサービスをうけられる場合 */ else { $this->ent[$k2]->service = $this->ent[$kk]->service; // サービスを受けている客番号 $this->ent[$k2]->busy_t = $this->p_time; // 窓口がふさがった時刻 if ($this->ent[$k2]->s_t == 0) // 窓口のサービス終了時刻 $this->ent[$k2]->end_time = $this->p_time + Exp_b($this->ent[$k2]->mean); else $this->ent[$k2]->end_time = $this->p_time + $this->ent[$k2]->mean; } } /* 窓口使用時間の処理 */ $this->ent[$kk]->service = 0; // 窓口を空き状態にする $this->ent[$kk]->c_busy += ($this->p_time - $this->ent[$kk]->busy_t); // 窓口がふさがっている時間の累計 /* この窓口に対する待ち行列がある場合 */ $k3 = $this->ent[$kk]->in_n; if (count($this->que[$k3]->que) > 0) { $this->que[$k3]->c_ql += count($this->que[$k3]->que) * ($this->p_time - $this->que[$k3]->ql_t); // 待ち行列長にその長さが継続した時間を乗じた値の累計 $n = array_shift($this->que[$k3]->que); // 待ち行列の先頭にいる客 $this->que[$k3]->ql_t = $this->p_time; // 現在の待ち行列長になった時刻 $it = $this->cus['no'.$n]; $x1 = $this->p_time - $it->time; $this->que[$k3]->c_wt += $x1; // 待ち時間の累計 if ($x1 > $this->que[$k3]->max_wt) $this->que[$k3]->max_wt = $x1; // 最大待ち時間 for ($i1 = 0; $i1 < $this->que[$k3]->m; $i1++) { $k4 = $this->que[$k3]->out_n[$i1]; // 窓口 if ($this->ent[$k4]->service == 0) { $this->ent[$k4]->service = $n; // 窓口の客番号 $this->ent[$k4]->busy_t = $this->p_time; // 窓口がふさがった時刻 if ($this->ent[$k4]->s_t == 0) // 窓口のサービス終了時刻 $this->ent[$k4]->end_time = $this->p_time + Exp_b($this->ent[$k4]->mean); else $this->ent[$k4]->end_time = $this->p_time + $this->ent[$k4]->mean; $it->state1 = 1; // 客の状態変更(サービス中) $it->state2 = $k4; // 客の状態変更(窓口番号) break; } } } } /**************************/ /* 統計量の計算と最終出力 */ /**************************/ function Output() { // System printf("全客数 %d", $this->nc); printf(" 最大系内客数 %d 最大滞在時間 %.3f\n", $this->max_c, $this->max_sys); printf("平均系内客数 %.3f", $this->c_now_c / $this->p_time); printf(" 平均滞在時間 %.3f", $this->c_sys / $this->nc); printf(" 終了時間 %.3f\n", $this->p_time); // Entity for ($i1 = 0; $i1 < count($this->ent); $i1++) { $e = $this->ent[$i1]; print("Entity ".$e->name); printf(" 稼働率 %.3f\n", $e->c_busy / $this->p_time); } // Queue for ($i1 = 0; $i1 < count($this->que); $i1++) { $q = $this->que[$i1]; print("Queue ".$q->name); printf(" 客数 %d", $q->nc); printf(" 最大待ち行列長 %d", $q->max_q_l); printf(" 最大待ち時間 %.3f\n", $q->max_wt); printf(" 平均待ち行列長 %.3f", $q->c_ql / $this->p_time); printf(" 平均待ち時間 %.3f\n", $q->c_wt / $q->nc); } } } /****************/ /* main program */ /****************/ // 入り口 printf("入り口(Inlet)の数は? "); fscanf(STDIN, "%d", $n_i); $inl = array(); for ($i1 = 0; $i1 < $n_i; $i1++) { printf("%d 番目の入り口(Inlet)\n", $i1+1); printf(" 名前は? "); fscanf(STDIN, "%s", $name1); $que = array(); printf(" 到着分布(=0:指数分布,=1:一定時間間隔,<0:指定,客数の負値)? "); fscanf(STDIN, "%d", $n); if ($n == 0) { printf(" 到着時間間隔の平均値は? "); fscanf(STDIN, "%lf", $m_a); } else if ($n == 1) { printf(" 到着時間間隔は? "); fscanf(STDIN, "%lf", $m_a); } else { for ($i2 = 0; $i2 < -$n; $i2++) { printf(" 到着時間は? "); fscanf(STDIN, "%lf", $x); array_push($que, $x); } } printf(" 並ぶ待ち行列の名前は? "); fscanf(STDIN, "%s", $name2); $inl_e = new Inlet($name1, $n, $m_a, $que, $name2); array_push($inl, $inl_e); } // 待ち行列 printf("待ち行列(Queue)の数は? "); fscanf(STDIN, "%d", $n_q); $que = array(); for ($i1 = 0; $i1 < $n_q; $i1++) { printf("%d 番目の待ち行列(Queue)\n", $i1+1); printf(" 名前は? "); fscanf(STDIN, "%s", $name1); printf(" 入り口(0),または,窓口(n>0,窓口の数)から? "); fscanf(STDIN, "%d", $n); $in = array(); if ($n == 0) { printf(" 入り口の名前は? "); fscanf(STDIN, "%s", $name2); array_push($in, $name2); } else { for ($i2 = 0; $i2 < $n; $i2++) { printf(" %d 番目の窓口の名前は? ", $i2+1); fscanf(STDIN, "%s", $name3); array_push($in, $name3); } } printf(" 処理する窓口の数は? "); fscanf(STDIN, "%d", $m); $out = array(); for ($i2 = 0; $i2 < $m; $i2++) { printf(" %d 番目の窓口の名前は? ", $i2+1); fscanf(STDIN, "%s", $name4); array_push($out, $name4); } $que_e = new Queue($name1, $n, $in, $m, $out); array_push($que, $que_e); } // 窓口 printf("窓口(Entity)の数は? "); fscanf(STDIN, "%d", $n_e); $ent = array(); for ($i1 = 0; $i1 < $n_e; $i1++) { printf("%d 番目の窓口(Entity)\n", $i1+1); printf(" 名前は? "); fscanf(STDIN, "%s", $name1); printf(" サービス分布(=0:指数分布,=1:一定時間)? "); fscanf(STDIN, "%d", $s_t); if ($s_t == 0) { printf(" サービス時間の平均値は? "); fscanf(STDIN, "%lf", $m_s); } else { printf(" サービス時間は? "); fscanf(STDIN, "%lf", $m_s); } printf(" 待ち行列(入力)の名前は? "); fscanf(STDIN, "%s", $name2); printf(" 終了後,外部(0),または,待ち行列(1)? "); fscanf(STDIN, "%d", $sw); $name3 = ""; if ($sw > 0) { printf(" 待ち行列(出力)の名前は? "); fscanf(STDIN, "%s", $name3); } $ent_e = new Entity($name1, $s_t, $m_s, $name2, $sw, $name3); array_push($ent, $ent_e); } // 全体の制御を行うクラス printf("シミュレーション終了時間? "); fscanf(STDIN, "%lf", $end); $base = new Q_base($inl, $que, $ent, $end); // 全体の制御を行うクラス // 実行 $base->Control(); // 出力 $base->Output(); /* ------------入力例(簡単な場合)----------- 1 Inlet 0 5 Queue 1 Queue 0 Inlet 2 Entity1 Entity2 2 Entity1 0 4 Queue 0 Entity2 0 4 Queue 0 10000 ------------入力例(複雑な場合)----------- 2 Inlet1 0 5 Queue1 Inlet2 0 5 Queue2 3 Queue1 0 Inlet1 1 Entity1 Queue2 0 Inlet2 1 Entity2 Queue3 2 Entity1 Entity2 2 Entity3 Entity4 4 Entity1 0 4 Queue1 1 Queue3 Entity2 0 4 Queue2 1 Queue3 Entity3 0 3 Queue3 0 Entity4 0 3 Queue3 0 10000 */ ?>