• ベストアンサー

待ち行列のプログラム(Fortran)

Fortranで待ち行列(レジ待ち)のプログラムを作りたいのですが、途中で行き詰まってしまい、うまくできません!  待ち行列についてまだよく理解できてないのだと思います。指数乱数を発生させるプログラムだけだったらできるのですが、それをヒストグラムで示して、待ち行列がどのように変化するのか観察するプログラムができないのです。  待ち行列のプログラムについて詳しく載っているHPなどがあれば教えてください!!(本でもOKです)

質問者が選んだベストアンサー

  • ベストアンサー
  • kacchann
  • ベストアンサー率58% (347/594)
回答No.1

http://www.matsusaka-u.ac.jp/~aihara/pukiwiki2/index.php?%A5%E2%A5%F3%A5%C6%A5%AB%A5%EB%A5%ED%CB%A1%A1%CA%C2%D4%A4%C1%B9%D4%CE%F3%A1%CB http://www.ed.kuki.tus.ac.jp/~tamura/2002/ipe2/queue.htm 考え方は、こう。 銀行窓口のある1日を考える。 1日に客は10人来るものとする。 客が訪れる時刻はランダムである。 客が到着した時、まだ「窓口が空いていない(前客の処理が終わっていない)」場合は待たされる。 窓口が空いている場合は、客は待たず、すぐに窓口業務をしてもらう。 これを簡易的に表現したものが以下のプログラム。 このプログラムは「客が実際に待った時間」のデータを取るのが目的。 (注: 厳密にフォートランの文法に従ってない) integer kNumOfPerson=10//客の人数 real availableTime//窓口利用可能時刻 real arrival(kNumOfPerson)//各客の到着時刻 real need(kNumOfPerson)//各客の窓口処理に要する時間 real wait(kNumOfPerson)//各客が実際に「待たされた」時間を格納する real t, s, i //「各客の到着時刻」の配列作成 t = 0 do i= 1, kNumOfPerson   s=getRand(4.0)//平均4.0の乱数を取得(4.0は適当)   //※↑客同士の「到着間隔」が平均4(秒)だという考え      //sは「到着間隔」なので、これを時刻に直す   arrival(i)=t+s enddo //「各客の窓口処理に要する時間」の配列作成 do i= 1, kNumOfPerson   need(i)=getRand(3.0)//平均3.0の乱数を取得(3.0は適当) enddo //銀行窓口オープン! availableTime = 0 do i= 1, kNumOfPerson   //客の銀行到着時刻   s=arrival(i)   //客到着時にまだサービス利用可能でないなら   if (availableTime.gt.s) then     //「待ち」発生     wait(i)=availableTime-s   //客到着時にすでにサービス利用可能なら   else     //「待ち」なし     wait(i)=0     //サービス開始は客の到着を待ってから     availableTime=s   endif   //次のサービス利用可能時刻は   //現客の処理を終えてから。   availableTime=availableTime + need(i) enddo で、この時点で上記の配列wait (各客が実際に「待たされた」時間を格納した配列) が得られる。 これを使って、あとはヒストグラム(分布表)なり グラフなり好きに表示すればよい。

hachi777
質問者

お礼

とてもよくわかりました!!ありがとうございます! 教えていただいたHPも参考になりました!! 無事、ヒストグラムで出力でき、感動しました~*(^_^)* Fortran、まだまだ全く使いこなせてませんが、頑張ります!!

関連するQ&A

  • 確率統計 プログラム

    (1) 正規乱数の発生–中心極限定理の利用  中心極限定理を利用して,区間[0, 1) の一様乱数から標準正規分布N(0, 1) に従う正 規乱数を100,000 個発生し,そのデータから得られる以下の各項目を報告しなさい. ここでは,一様乱数の生成は合同式法を用い,また,正規乱数の生成は中心極限定 理を利用して,いずれも自分で作成したC 言語プログラムで実現すること.(既存の RAND 関数などを用いない) 1. 100,000 個の正規乱数の平均値.なお,理論値は0 である. 2. 100,000 個の正規乱数の標準偏差.なお,理論値は1 である. 3. 100,000 個の正規乱数のヒストグラム(頻度分布).ただしここでのヒストグラ ムは,区間[−5, 5] を100 分割したものとする. 4. 100,000 個の正規乱数のヒストグラム.ただしここでのヒストグラムは,区間 [2.5, 5] を25 分割したものとする.これは,前項3 の右端部を取り出したもので ある. 5. 正規乱数を発生して上項1 ∼ 4 を求めるために作成した,プログラムのソース. (2) 正規乱数の発生–Box-Muller 法  ボックス・ミュラー法により,区間[0, 1) の一様乱数から標準正規分布N(0, 1) に従う 正規乱数を100,000 個発生し,そのデータから得られる以下の各項目を報告しなさい. ここでは,一様乱数の生成は合同式法を用い,また,正規乱数の生成はBox-Muller 法 を用いて,いずれも自分で作成したC言語プログラムで実現すること.(既存のRAND 関数などを用いない) 1. 正規乱数の平均値. 2. 正規乱数の標準偏差. 3. 正規乱数のヒストグラム.区間[−5, 5] を100 分割したものとする. 4. 正規乱数のヒストグラム.区間[2.5, 5] を25 分割したものとする. 5. プログラムのソース. (3) 両者の比較課題1, 2 で得られた結果を比較し,2 つの方法で得られた正規乱数の性質 に違いが見い出されれば,それを考察しなさい. 何ですけどお願いいたします 期限は2009/7/27

  • EXCELで確率分布に従う乱数を発生させたい

    EXCELにて指数分布や正規分布、ポアソン分布などに従う 乱数を発生させたいのですがどうすればいいでしょうか? できれば、それらともとの分布関数とをヒストグラムで比較して意図した乱数が発生できているかを検討したいのですが・・・。

  • fortranでのNaNについて

    お忙しい所、NaNについて回答お願い致します。 fortranでプログラムを使用して数値計算を行っていますが、計算途中で結果がNaNとなり困っています。 NaNは、0で除算を行なったり、負の数の指数を求めようとした時に出る無限大や定義できない値のようなのですが、式を見ても0で除算を行なったり、負の数の指数を求めようとしている所はありません。 もし同じような経験をされて見事解決された方、居られましたらその時の対処法をお聞かせ願えないでしょうか。 何卒よろしくお願い致します。

  • ニューラルネットワークの重みの行列について

    ニューラルネットワーク(誤差逆伝播)では、重みを行列で表現して、行列計算を何回となくやっていくという風なプログラムになっていくと思います。”重み”というとどうしても重み付き平均が連想され、足して1になるようにする、というイメージにとらわれてしまうのですが、そのような制約はないということでもいいのでしょうか。足して1にならないということは増幅とか減衰が生じることを許容するということになりますが。 もし、それでOKならば、多くのテキストにみられる”重み”という言葉で説明しない方がいいのではないかと思いますが。そのあと、シグモイド関数で変換されたりするので、和の値が一定などの制約は必要なしなのだろうと思いますが。また、その”重み”の値も変化していくのでそうなのかなと思いますが。ニューラルネットワークはある意味、システムのルールさえ守っていれば融通無碍という風にも見えます。 また、ニューラルネットワークでは行きついた先が最適解である保証は取れるということになるでしょうか。行き当たりばったりを何回も繰り返すという印象をもってしまいます。あるいは別のタイプになりますが、乱数による総当たり戦の最終勝者を探すというような感じあります。そうすると乱数の発生の仕方に依存したりするように思えてきます。

  • C++言語について

    大学で研究室に配属された友達に勉強の相談をされました。 下の課題なのですが、どのようにプログラムすれば良いのでしょうか? 来年は、留年している僕の番なのでとても気になります。 丸投げで申し訳ないのですが、どなたかよろしくお願いいたします。 (1) 0から20の間の一様乱数を1000個作り、それをヒストグラムにする。 出来上がった分布の平均が10、分散が20÷√12になることを確認する。 (2) 平均値が10の指数関数分布exp(-ax)(0<x)になるように乱数を1000個作り、それをヒストグラムにする。 出来上がった分布の平均値が10に近いことを確認する。 (3) 平均値が5のpoisson分布になるように乱数を1000個作り、それをヒストグラムにする。 そのヒストグラムをpoisson分布関数、及びgauss分布でfitする。 (4) 平均値が10の指数関数分布exp(-ax)(0<x)になるように乱数からサンプルを1000個選び出し、その和を取りヒストグラムにする。 この操作を10000回繰り返す。 出来たヒストグラムをgauss分布関数でfitする。 僕にはもうサッパリ分かりません。。。

  • C++ による指数乱数発生プログラムを書きたいのですが。。。

    平均値(期待値)が、例えば30の指数乱数発生プログラムを、C++を使って書いてみたいのですが、どうやったらいいのかよく分かりません。いろいろなサイトを見て回ったのですが、これといったものが見付かりませんでした。 どなたか、大変申し訳ありませんが、ソースコードをご存知の方がいましたら教えていただけないでしょうか?

  • c言語がわからなく、教えていただきたいです。

    待ち行列のプログラミング 待ち行列をC言語でプログラミングしたいのですが、わからなくて困っています!! 誰か助けて下さい!! 2工程、3機械から成っている。2種の製品A,Bを製造している。第2工程では機械が2つあり、待ちが少ない方に進む。 ジョブ数は500、加工時間は指数乱数、到着間隔はポアソン到着、納期は加工時間*納期係数(10)です。 この待ち行列のプログラムを教えていただきたいです。 お願いいたします。

  • 待ち行列シュミレーションのプログラム

    今現在待ち行列シュミレーションを勉強しているのですが、M/M/2モデルのプログラムをそれぞれ窓口数1(M/M/1)、窓口数3(M/M/3)のプログラムにしたいのですが上手くできません。 窓口数2のプログラムを記載します(窓口数の増減に関係ないと思われる後半のプログラムは記載してません)ので、どなたかわかる方がいましたらご教授のほうお願いします。 M/M/2 待ち行列のモデル -- ポアソン到着 => 到着時間間隔は指数分布 -- 指数サービス => サービス時間は指数分布 */ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #define N_SERVICE 2 /* 窓口数 */ #define N_USER 10000 /* 総到着人数 */ #define ARRIVAL_INTERVAL 30.0 /* 平均到着間隔*/ #define SERVICE_TIME 70.0 /* 平均サービス時間 */ double uni_random(void); /* 区間[0,1]の一様乱数 */ double exp_random(double); /* 平均値を引数にとる指数乱数*/ int main(void){ int i; /* 客番号 */ int j; /*窓口番号*/ double arrival[N_USER]={0.0} /*N人の到着時刻 */ int counter[N_USER]={0}; /*N人の利用窓口*/ int current_user[N_SERVICE]={0};/*最近の窓口利用者 */ double srv_start[N_USER]={0.0}/* N人のサービス開始時刻 */ double wait[N_USER]={0.0}; /*N人の待ち時間 */ double srv_time[N_USER]={0.0}/* N人のサービス時間 */ double srv_finish[N_USER]={0.0}; /* N人のサービス終了時刻*/ double avr_wait; /* 平均待ち時間*/ double avr_srvtime; /* 平均サービス時間  */ double avr_srvrate[N_SERVICE]={0.0}; /* 窓口の稼働率 */ /* 乱数の「種」を初期化 */ srand((unsigned)time(NULL)); /* 最初の客が到着した時刻から開始. 窓口0に入ってすぐサービス開始 */ arrival[0]=0.0; counter[0]=0; current_user[0]=0; srv_start[0]=0.0; wait[0]=0.0; srv_time[0]=exp_random(SERVICE_TIME); srv_finish[0]=srv_start[0] + srv_time[0]; /* 2人目の客が到着. 窓口0が空いていれば窓口0に、塞がっていれば窓口1に入ってすぐサービス開始 */ arrival[1]=arrival[0]+exp_random(ARRIVAL_INTERVAL); if(srv_finish[0]>arrival[1]){ counter[1]=1; current_user[1]=1; } else{ counter[1]=0; current_user[0]=1; } srv_start[1]=arrival[1]; wait[1]=0.0; srv_time[1]=exp_random(SERVICE_TIME); srv_finish[1]=srv_start[1]+srv_time[1]; for(i=2; i<N_USER; i++){ /* 客の到着時刻 = 前の客の到着時刻 + 到着間隔 */ arrival[i]=arrival[i-1]+exp_random(ARRIVAL_INTERVAL); /* 利用窓口 = 2つに窓口で早く空くほう */ if(srv_finish[current_user[1]]<srv_finish[current_user[0]]){ counter[i]=1; } else{ counter[i]=0; }

  • 0 からa-1 までの整数の乱数をn 個発生させ、発生した整数のヒスト

    0 からa-1 までの整数の乱数をn 個発生させ、発生した整数のヒストグラムをプリントアウトしたいです.また,a とnはコマンドラインから引き渡します 0 からa-1 までの整数を発生する乱数の書き方は (int)((double)rand()/((double)RAND_MAX+1) *a); プログラムをRandHist としたとき RnadHist 10 1000 と入力すれば 0 982 1 1035 2 956 3 1102 ・ ・ 9 971 などと。出力されるようなプログラムを作る問題ですが,a とn は、任意に変えられるように したいです. どなたか教えてください.

  • パラメータの値を計算で出したい

    今、fortranを使って以下のようなプログラムを書いています。 1時間毎の温度(t)のデータがあり、それに対して指数関数でRが変化します。 R=a*exp(0.7*t) これに対して、1ヶ月間のRの積算値を測定値として持っています。 この測定値に最も近くなるように定数aの値を求めたいのですが fortranでどのようにプログラムしたらいいのかわかりません。 よろしくお願いします!

専門家に質問してみよう