M/M/1/K待ち行列シミュレータを作成してください。 また、作成したシミュレータの正当性を何らかの方法で確認してください。 (参考)M/M/1待ち行列(システム容量が無限大) に関しては、 システム内平均パケット数 ̄Nの理論値は ̄N = ρ/(1-ρ)で与えられます。 ρはシステムの利用率で,ρ = λ/μ(λ:平均到着率、μ:平均サービス率) で定義されます。 また、M/M/1/K待ち行列も廃棄率などの統計量が理論的に導出されています。 作成の際の要求条件は以下のとおりです。 ○入力パラメータ: ・パケットの平均到着率 ・サーバの平均サービス率 ・システム容量 ・シミュレーション終了時間 ・シミュレーション開始時間(この時間までのシステムは過渡状態と考えて、統計はとらない。) ○出力: ・システム内平均パケット数 ・パケットの平均システム滞在時間 ・パケット廃棄率 ○できるだけ拡張性の高い仕様にしてください。 〇待ち行列規律 FIFOを適用する。FIFOとは、待ち行列に入った順にサービスしていくものです。(先着順サービス) 〇イベント駆動型シミュレーション 確率によって算出される、将来の各種事象が発生する時間をテーブル等で管理して、 ある時点における事象の処理が終了すると、次に最も近い将来に生起する事象に注目し、その生起時間に現在時刻を移動させる。 〇動作手順と事象表 シミュレーションを実施する上で大切なことは、事象(イベント)の定義と変化です。 事象としては (1) 客の到着 (2) サービスの終了 (3) シミュレーションの終了などに必要な制御用事象 が挙げられます。 これらの事象を事象表に記載しておいて、時刻の早い順にその事象を生起させる。 事象表には ・事象の種類 ・その発生時刻 ・その他の情報 が記入されます。 シミュレーションの手順は以下の通りです. 1、各種初期値を設定する. 2、事象表に、最初の事象を記入する. 3、事象表から、事象時刻の最も早い事象を取り出して、 (a) その事象の発生に伴う状態の変化(動作) を起こさせる。 (b) その事象の発生によって決まる次の事象を作り出し、事象表に登録する。 (c) 各種統計をとる。 (d) その事象を事象表から消去する。3の先頭に戻る。 /* 指数分布に従う乱数発生 */ double exp_rand(double x) /* xは平均到着率λに相当 */ { return fabs(-log(1.0-random())/x); } ただし、関数random()は0〜1の一様乱数を返す関数であると仮定している。 実際には、開発環境に応じて適切な乱数発生関数を使用する必要がある。 /*************************************** 変数の一例。 ポインタをどんどん使ってください。 mallocなどで領域を確保したら不要な領域はfreeしてください。 ****************************************/ #define K 50 /*システム容量*/ #include #include #include struct transaction{ /*事象表の各エントリの保持情報*/ double hassei_t; /*その事象の発生時刻*/ double tochaku_t; /*システムへの到着時刻*/ int num_kyaku; /*パケットの一連番号*/ int event_type; /*事象の種類*/ }; struct queue{ /*待ち行列のエントリを構成する構造体*/ double tochaku_t; /*システムへの到着時刻*/ int num_kyaku; /*パケットの一連番号*/ }; int queue_su =0; /*待ち行列表中のパケット数*/ int kyaku_su =0; /*到着パケット数*/ int mado_su =1; /*全窓口数*/ double max_time =10000.0; /*シミュレーション期間*/ double arrive_rate; /*パケットの平均到着率*/ double service_rate; /*サーバの平均サービス率*/ double ave_num_of_people; /*システム内平均パケット数*/ duoble ave_spent_time; /*パケットの平均システム滞在時間*/ double reject_ratio; /*パケットの廃棄率*/ double exp_rand(double x);