• 締切済み

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

今現在待ち行列シュミレーションを勉強しているのですが、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; }

noname#130164
noname#130164

みんなの回答

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

> シュミレーション シミュレーション(simulation)が正しいです。 正しい用語を使いましょう。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「上手くできない」というのは, 何がどう「上手くできない」んでしょうか?

関連するQ&A

  • 逆行列のアルゴリズム

    現在逆行列を求めるアルゴリズムを勉強してるんですが、全然わかりません。 とあるサイトさんから逆行列を求めるソースを拝借させていただきました。 実際に2行2列の値を入れて手計算でプログラムを追っていったら23行目で対角成分に1を代入したり、33行目で対角成分以外の成分に0を代入しているのはわかるんですが、わかるのはその程度で、もっと詳しくアルゴリズムを教えていただきたいです。 わかりやすいサイトなどでも結構なんで教えていただけると助かります! よろしくおねがいします。 #include <stdio.h> 01:int main(void) 02:{ 03: 04: double exp_At[2][2]={{1,3},{2,1}}; //入力用の配列 05: double inv_exp_At[2][2]; //ここに逆行列が入る 06: double buf; //一時的なデータを蓄える 07: int i,j,k; //カウンタ 08: int num=2; //配列の次数 09: //単位行列を作る 10: for(i=0;i<num;i++) 11: { 12: for(j=0;j<num;j++) 13: { 14: inv_exp_At[i][j]=(i==j)?1.0:0.0; 15: } 16: } 17: /* 掃き出し法 */ 18: for(i=0; i<num; i++) /* 逆行列をexp(-At)求める */ 19: { 20: buf=1/exp_At[i][i]; 21: for(j=0; j<num; j++) 22: { 23: exp_At[i][j] *= buf; 24: inv_exp_At[i][j] *= buf; 25: } 26: for(j=0; j<num; j++) 27: { 28: if(i != j) 29: { 30: buf=exp_At[j][i]; 31: for(k=0; k<num; k++) 32: { 33: exp_At[j][k] -= exp_At[i][k] * buf; 34: inv_exp_At[j][k] -= inv_exp_At[i][k] * buf; 35: } 36: } 37: } 38: } 39://逆行列を出力 40: 41: printf("逆行列exp(-At)=\n"); 42: 43: for(i=0;i<num;i++) 44: { 45: for(j=0;j<num;j++) 46: { 47: printf(" %f",inv_exp_At[i][j]); 48: } 49: printf("\n"); 50: } 51:}

  • c プログラム 

    以下のプログラムは,第n項までのe^xのマクローリン展開をさせるものです. これを修正して,理論値と近似値の誤差がある値(自分で入力)になったときに,計算を終了させるにはどうしたらよいでしょうか.御教授いただければ幸甚 です. ---------------------------------------- #include <stdio.h> #include <math.h> int main(void) { int n; double x=1.0,y=1.0,e=1.0,err; int i; double f=1.0,p=1.0; printf("x="); scanf("%lf",&x); printf("n="); scanf("%d",&n); printf("Mclaurin展開によるn項までのexp(x)の\n n 理論値 近似値 誤差\n"); for(i=1;i<=n;i++){ f*=(double)i; p*=x; y+=p/f;近似値 e=exp(x);理論値 err=e-y;誤差 printf("%2d %12.8e %12.8e %12.8e\n",i,e,y,err); } return 0; }

  • このプログラムの結果は正しいのでしょうか?

    下記のプログラムはregister変数へのアクセスが高速であることを確認するためのプログラムです #include <stdio.h> #include <time.h> int i; /* これはグローバル変数なので、 register変数には変換されない */ int main(void) { register int j; int k; clock_t start, finish; start = clock(); for(k=0; k<100; k++) for(i=0; i<32000; i++); finish = clock(); printf("レジスタを使わないループの刻み数: %ld \n", finish - start); start = clock(); for(k=0; k<100; k++) for(j=0; j<32000; j++); finish = clock(); printf("レジスタを使ったループの刻み数: %ld \n", finish - start); return 0; } 【質問】 このプログラムを実行すると、 レジスタを使わないループの刻み数: 15 レジスタを使ったループの刻み数: 0 と表示されます。 この結果はregister変数へのアクセスが高速であることの証明になるのでしょうか? また「刻み数」とは何のことですか?教えて頂けないでしょうか?

  • 【C言語・BLAS】 行列ベクトル積におけるエラー

    今、BLASを使って行列ベクトル積を計算するのにどれくらい時間がかかるか計測しようとしています。 しかし、短いプログラムにも関わらずC用インターフェースのスレッド並列版BLASを呼び出す部分でFloating point exceptionエラーが出てしまいます。 なぜエラーが出るのか全く分からないので、どなたか分かる方ご意見いただけないでしょうか? #define SEED 1 #define N 100 /* extern void dgemv(char transa, int m, int n, double alpha, double *a, int lda, double *x, int incx, double beta, double *y, int incy); */ int main( int argc, char *argv[] ){  char TRANS = 'T';  int INC = 1;  double ALPHA = 1.0;  double BETA = 0.0;  int i, j, n1, n2;  double **matrix;  double *vector;  double *result;  double start_time;  double end_time;  fprintf( stdout, "____performance evaluation start____\n" );  srand(SEED);  matrix = Malloc2DDouble( N, N );  vector = (double *) malloc ( sizeof(double) * N );  result = (double *) malloc ( sizeof(double) * N );  n1 = N; n2 = N;  #pragma omp parallel  {   #pragma omp for private(j)   for( i=0; i<n1; i++ ){    for( j=0; j<n2; j++ ){     matrix[i][j] = ( ( rand() / (double)RAND_MAX ) - 0.5 );    }    vector[i] = ( ( rand() / (double)RAND_MAX ) - 0.5 );    result[i] = 0.0;   }  }  start_time = GetTime();  dgemv( TRANS, n2, n1, ALPHA, matrix[0], n2, vector, INC, BETA, result, INC );  end_time = GetTime();  return EXIT_SUCCESS; }

  • ソフトウェアの仕様書作成について(C言語)

    「電車の時刻表を画面に表示するプログラムについて、詳細仕様を検討して作成しなさい。要求は、ユーザが、現在時刻と到着したい希望時刻を入力すると、今から乗れそうな列車の候補をいくつか提示して欲しいということだけである。 この要求に沿って仕様を詳細に検討しなさい。」 という仕様書作成の問題なのですが、よくわかりません。 とりあえず自分なりにがんばってみたのですが(後述)、どうも不自然さがあふれてて困っています。 どこを直して行けばよいでしょうか? <************ここから*****************> 関数の形式:int train_time(int present_h, int present_m, int arrival_h, int arrival_m, const int time_table[][]) 関数の目的: 時刻表の電車の時間、分をそれぞれtime_table[i][0], time_table[i][1]に読み込み、(iは電車を区別する番号で整数である。) 現在の時間と分をそれぞれpresent_h, present_mから受け取り、また、到着したい希望時間と分をそれぞれarrival_h, arrival_mから受け取る。 時刻表の時刻と比較し、現在時刻以降に発車し、到着時刻以前に到着するすべての電車の発車時刻と到着時刻を表示する。 入力の形式:present_h, arrival_h, time_table[i][0]は、0以上24以下の時間を表す整数  present_m, arrival_m, time_table[i][1]は0以上60以下の分を表す整数 出力の形式:  -1、0以上の整数 説明:  時刻は24時間表記とする。  秒単位は考慮しない。 例外時の処理:  時刻で無いものを受け取った場合、例えば24以上の時間、60以上の分、文字列を受け取った場合などは-1を返す。  NULLを受け取った場合-1を返す

  • プログラムの実行時間計測方法について

    プログラムの実行時間の計測方法について、質問します。 以下に示すプログラムは、パケットが受信される度にmessage関数が呼び出され、message関数内で受信したパケットをfwrite関数を用いて処理をしています。 [質問内容] clock関数のclock_t型を用いて、プログラムの実行時間を計測したいと思っています。しかし、以下に示すプログラムの場合、パケットが受信されるたびにmessage関数が呼び出され、かつパケットが受信される度にstart = clock()で0秒からの開始になってしまいます。 なにか、対策方法はあるのでしょうか? よろしくお願いします。 [プログラム] void main(int argc, char** argv){ //パケットが受信される度にmessage関数が呼ばれる。 message(); } void message(){ double time; clock_t start,finish; if(equals(msg->selector,(byte*)"test",strlen("test"))){ start = clock(); fwrite(msg->payload,msg->payload_length,1,fp); finish = clock(); time = (double)(finish - start)/1000.0; printf("データ送信時間:%f[sec]\n",time); } else if(equals(msg->selector,(byte*)"finish",strlen("finish"))){ done = D_TRUE; } }

  • 配列を戻り値にして逆行列を求める関数

    #include(stdio.h) int main(){ double a[4][4]={{1,2,0,-1},{-1,1,2,0},{2,0,1,1},{1,-2,-1,1}}; //入力用の配列 double inv_a[4][4]; //ここに逆行列が入る double buf; //一時的なデータを蓄える int i,j,k; //カウンタ int n=4; //配列の次数 //単位行列を作る for(i=0;i<n;i++){ for(j=0;j<n;j++){ inv_a[i][j]=(i==j)?1.0:0.0; } } //掃き出し法 for(i=0;i<n;i++){ buf=1/a[i][i]; for(j=0;j<n;j++){ a[i][j]*=buf; inv_a[i][j]*=buf; } for(j=0;j<n;j++){ if(i!=j){ buf=a[j][i]; for(k=0;k<n;k++){ a[j][k]-=a[i][k]*buf; inv_a[j][k]-=inv_a[i][k]*buf; } } } } //逆行列を出力 for(i=0;i<n;i++){ for(j=0;j<n;j++){ printf(" %f",inv_a[i][j]); } printf("\n"); } } という、4次元正方行列の逆行列を求めるプログラムがあるのですが これを複数の行列の逆行列が求められる関数にする場合を教えてください・・行列は配列で作ってるのでよくわかりません、お願いします

  • γ関数のプログラム(初心者です)

    以下のようにγ関数のプログラムを組みました。 とりあえず整数値を入力すれば、正しい値は返しているということがprintfの4で確認できました。 もとはfortranで組んだプログラムをCに置き換えました。 ですが、実際走らせてみると、4で値は確認できますがsegmentation faultが出てしまいます。 ですからサブルーチンファイル(ユーザー関数?)として利用できません。 何がいけないのでしょうか? 正しくyが帰ってくるようにどうなおしたらよいのか教えてください。 #include <stdio.h> #include <math.h> double gamma(double x) { double c[8],y,a,r,b,s; int i; a=1.; r=1.; c[1]=5.771916e-01; c[2]=9.882058e-01; c[3]=8.970569e-01; c[4]=9.182068e-01; c[5]=7.567040e-01; c[6]=4.821993e-01; c[7]=1.935278e-01; c[8]=3.586834e-02; printf("0 %f\n",x); while(1){ if(x>2.){ x=x-1.; a=a*x; printf("1 %f %f\n",x,a); } else if(x<1.){ a=a/x; x=x+1.; printf("2 %f %f\n",x,a); } else{ break; } } x=x-1.; for(i=1;i<8;i++){ b=(double)(i); s=(c[i]*((double)(pow(-1,b))) *((double)(pow(x,b)))); printf("3 %d %f\n",i,c[i]); r=r+s; } y=a*(r+(0.03586834*((double)(pow(-1,8)))*((double)(pow(x,8))))); printf("4 %f\n",y); return y; } main() { double x,y; printf("数字を入力してください。"); scanf("%lf",&x); printf("メインプログラム %lf\n",x); y=gamma(x); printf("%f\n",y); }

  • C言語プログラムエラーについて

    構造体とポインタを使って関数電卓のプログラムを作ってコンパイルしたのですがひとつだけエラーがでて困っています。親切な方回答よろしくお願いします。 ソースコード↓ #include<stdio.h> #include<string.h> #include<math.h> int main(void) { int i; double result; char inp_buf[30]; double input_d; typedef struct{ char*f_name; double(*func)(double); }FUNC_TBL; FUNC_TBL f_tbl[] = { { "sin",sin }, { "cos",cos }, { "tan",tan }, { "exp",exp }, }; printf( ">" ); scanf( "%s %lf", inp_buf, &input_d); for( i=0;i< sizeof(f_tbl)/sizeof(FUNC_TBL);i++) { if(!strcmp(f_tbl[i],f_name,inp_buf)) { 29行目→ result = f_tbl[i],func(input_d); } } printf("%lf\n",result); return 0; } エラーメッセージ↓ (29):error C2440:`=`:`FUNC_TBL`から`double`に変換できません。

  • ネイピア数(e)のプログラム

    テイラー展開によってネイピア数の近似値を求める プログラミングが全くわかりません。 e = 2.71828 18284 59045 23536 02874 71352 … を計算したいのですが。 #include <stdio.h> #include <math.h> int kaijou(int p) { int cnt; int val=1; for(cnt=1 ; cnt<=p ; cnt++){ val=val*cnt; } return(val); } double napier(int p) { printf("eを計算します。E = (1+(1/k))^k\n"); printf("k=いくつまで計算しますか ?\n"); scanf("%d", &n); double E[n]; E[1] = 1; for (j = 1; j <= n; j++){ E[j] = E[j] + 1; } for (k = 1; k <= n; k++) { K = K + 1; A = 1 / K; // printf("A = %e, ",A); B = 1 + A; // printf("B = %e\n",B); for ( i = 1; i<=k; i++){ E[k] = E[k] * B; // printf("E[%3d]= %e\n",k,E[k]); } void main(void) { int n; int cnt; double answer; printf("計算する最大の項nを入力してください:"); scanf("%d",&n); for(cnt=1 ; cnt<=n ; cnt++){ answer=napier(cnt); printf("第%d項までの近似値:%f 真値:%f 差:%f\n",cnt,answer,exp(1),answer-exp(1)); } }

専門家に質問してみよう