待ち行列

待ち行列の表

教科書の表と同じものです。客の到着間隔とサービスにかかる時間がわかれば、表の全部の欄を埋めることができます。表の仕組みを理解するために、枠になっている欄内に数値を入れて採点してみてください。

客No 到着間隔 到着時刻 開始時刻 サービス時間 終了時刻 待ち時間
1 - 5
2 5
3 5
4 5
5 5

新規問題 採点 送信 正答数:  正答率: %

[新規問題]をクリックすると到着間隔が乱数で設定されます。サービス時間は5分に固定です。到着時刻、サービス開始時刻、サービス終了時刻、サービス開始までの待ち時間の空欄に数値を入れて、[採点]のボタンを押すと採点されます。

間違ったところを訂正して[採点]のボタンを押し全問正解をめざします。正解したら[送信]のボタンを押してください。

[新規問題]を押せばいつでも新しい問題に替わります。そのときは入力した数値がクリアされますから注意してください。

待ち時間が全員0分になることもあります。その場合は簡単過ぎますから、[新規問題]を押して少なくとも一人は待ち時間が1分以上になる例で100%正解にしてから送信してください。

課題13-1

面倒なのでC言語でプログラムを組んでみます。単純な作業の繰り返しですから、それほど難しくはないのですが、変数の名前を工夫しないと繰り返した時に間違うことがあります。

プログラム名 k1301.c

 1: /* 待ち行列 */
 2: #include <stdio.h>
 3: #include <stdlib.h>
 4: #include <time.h>
 5: #define DATANUM 100
 6: 
 7: int main()
 8: {
 9:     int kankakumax = 12;
10:     int maeTouchaku = 0;
11:     int maeShuryou = 0;
12:     int kankaku = 0;
13:     int i;
14:     int touchaku;
15:     int kaishi, svjikan, shuryou, machijikan;
16:     srand( (unsigned int)time( NULL ) ); /*乱数初期化*/
17:     for (i=1 ;DATANUM>=i ;i++){
18:       touchaku = maeTouchaku + kankaku;
19:       if (touchaku > maeShuryou){
20:           kaishi = touchaku;
21:       }
22:       else {
23:           kaishi = maeShuryou;
24:       }
25:       svjikan = 5;
26:       shuryou = kaishi + svjikan;
27:       machijikan = kaishi - touchaku;
28:       printf ("%5d %5d %8d %8d %5d %8d %5d\n"
29:               ,i,kankaku,touchaku,kaishi
30:               ,svjikan,shuryou,machijikan);
31:       maeTouchaku = touchaku;
32:       maeShuryou = shuryou;

33:       kankaku = rand()/(RAND_MAX+1.0)*kankakumax+1;
34:                                      /*1からkankakumaxの乱数*/
35:     }
36:     return 0;
37: }

プログラム解説 k1301.c

次の人が到着した時に、前の人のサービスが終わっているかどうかで開始時間が変わります。

5: #define DATANUM 100
コンパイルの最初に DATANUM という文字列が 100 に置換されます。100人分処理するという事です。
9: int kankakumax = 12
1分から12分の12の部分を後から変えられるようにしましたが1分の方を書いていないのはついうっかり。悔やまれるところです。
11: int maeShuryou = 0;
maeと付いているのは「前の人の」という意味。最初の人は前の人がいませんから初期値は0にしておきます。
16: srand( (unsigned int)time( NULL ) );
乱数の初期化です。時刻を種に使い実行ごとに異なる乱数系列が得られるようにする定番の書き方です。
17: for (i=1 ;DATANUM>=i ;i++){
冒頭で書いた人数分繰り返し行います
18: touchaku = maeTouchaku + kankaku;
間隔は前の人が到着してから次の人が来るまでの時間です。プログラムのあとの方で乱数により決めます。
19: if (touchaku > maeShuryou){
サービス開始時間は到着時刻と前の人のサービス終了時間の大きい方になりますが、ifを使ってわかりやすく表現しました。
25: svjikan = 5;
サービス時間はいつも5分ですが、あとで3分から7分までの一様乱数にするので、その時との比較のためにあえてここに書いています。
26: shuryou = kaishi + svjikan;
終了時間はもちろん開始時間にサービス時間を足したものです。
27: machijikan = kaishi - touchaku;
待ち時間を計算します。
28: printf ("%5d %5d %8d %8d %5d %8d %5d\n"
,i,kankaku,touchaku,kaishi
,svjikan,shuryou,machijikan);
3行に書いてありますが、コンパイラにとっては1行です。表の1行分を書きます。
31: maeTouchaku = touchaku;
32: maeShuryou = shuryou;
次の人のために現在の人の数値を前の人のものにします。
33: kankaku = rand()/(RAND_MAX+1.0)*kankakumax+1;
次の人が来るまでの時間を一様乱数で決定する。これで1から12分までの乱数になります。

実行結果 k1301.c

~/c$ ./k1301
    1     0        0        0     5        5     0
    2    12       12       12     5       17     0
    3    12       24       24     5       29     0
    4     3       27       29     5       34     2
    5    11       38       38     5       43     0
    6     4       42       43     5       48     1
    7    10       52       52     5       57     0
    8     8       60       60     5       65     0
    9     4       64       65     5       70     1
   10     4       68       70     5       75     2
   11     9       77       77     5       82     0
   12     2       79       82     5       87     3
   13     3       82       87     5       92     5
   14    10       92       92     5       97     0
   15     4       96       97     5      102     1
   16     2       98      102     5      107     4
   17     4      102      107     5      112     5
   18     3      105      112     5      117     7
   19     2      107      117     5      122    10
   20     5      112      122     5      127    10
   21     1      113      127     5      132    14
   22     2      115      132     5      137    17
   23     1      116      137     5      142    21
   24    12      128      142     5      147    14
   25     7      135      147     5      152    12
   26     5      140      152     5      157    12
   27     5      145      157     5      162    12
   28     5      150      162     5      167    12
   29     5      155      167     5      172    12
   30     8      163      172     5      177     9
   31     1      164      177     5      182    13
   32     8      172      182     5      187    10
   33     7      179      187     5      192     8
   34     1      180      192     5      197    12
   35    10      190      197     5      202     7
   36     6      196      202     5      207     6
   37     4      200      207     5      212     7
   38     7      207      212     5      217     5
   39     2      209      217     5      222     8
   40     8      217      222     5      227     5
   41    11      228      228     5      233     0
   42    10      238      238     5      243     0
   43     9      247      247     5      252     0
   44     1      248      252     5      257     4
   45     7      255      257     5      262     2
   46     1      256      262     5      267     6
   47     3      259      267     5      272     8
   48    10      269      272     5      277     3
   49     3      272      277     5      282     5
   50     4      276      282     5      287     6
   51     3      279      287     5      292     8
   52     4      283      292     5      297     9
   53     5      288      297     5      302     9
   54     3      291      302     5      307    11
   55     3      294      307     5      312    13
   56    12      306      312     5      317     6
   57     8      314      317     5      322     3
   58     8      322      322     5      327     0
   59     5      327      327     5      332     0
   60     1      328      332     5      337     4
   61     3      331      337     5      342     6
   62     6      337      342     5      347     5
   63     8      345      347     5      352     2
   64    10      355      355     5      360     0
   65     6      361      361     5      366     0
   66     6      367      367     5      372     0
   67     3      370      372     5      377     2
   68    10      380      380     5      385     0
   69    12      392      392     5      397     0
   70     4      396      397     5      402     1
   71     5      401      402     5      407     1
   72    11      412      412     5      417     0
   73     2      414      417     5      422     3
   74     2      416      422     5      427     6
   75    11      427      427     5      432     0
   76     8      435      435     5      440     0
   77     2      437      440     5      445     3
   78     2      439      445     5      450     6
   79     6      445      450     5      455     5
   80     5      450      455     5      460     5
   81     5      455      460     5      465     5
   82     9      464      465     5      470     1
   83     8      472      472     5      477     0
   84    10      482      482     5      487     0
   85    12      494      494     5      499     0
   86    11      505      505     5      510     0
   87    10      515      515     5      520     0
   88     7      522      522     5      527     0
   89     6      528      528     5      533     0
   90     2      530      533     5      538     3
   91     8      538      538     5      543     0
   92     9      547      547     5      552     0
   93     7      554      554     5      559     0
   94     3      557      559     5      564     2
   95     6      563      564     5      569     1
   96     1      564      569     5      574     5
   97     8      572      574     5      579     2
   98     9      581      581     5      586     0
   99    10      591      591     5      596     0
  100     8      599      599     5      604     0

課題13-2

教科書にあるサービス時間が3から7の一様乱数である時のプログラムにします。

k1301.c では 25: svjikan = 5; というところがあり、これがサービス時間が5分固定としています。

プログラム名 k1302.c

svjikan = 5; 
      ↓       rand().... を使って3から7の数値になるようにします
      ↓        変更はこの1行だけです
svjikan = rand()/????????????????????

ヒントは

/* 1からkankakumaxのとき */

kankaku = rand()/(RAND_MAX+1.0)*kankakumax+1;

kankaku = rand()/(RAND_MAX+1.0)*12+1; でうまくいく理由

int a = rand()/(RAND_MAX+1.0)*12+1 で a には 1から12までの整数の一様乱数(のひとつ)が入ります。この目的のためには 0以上1未満(つまり 0 ≦ x < 1 )の浮動小数点数の一様乱数が必要です。0以上1以下(つまり 0 ≦ x ≦ 1 )ではうまくいきません。

このために RAND_MAX よりちょっとだけ大きい数で割り算すればいいのですが、RAND_MAX は大きい数なので 1 は十分に小さいだろうと考えているようです。RAND_MAX が 2147483647 の時は 2×10-7程度がちょっとだけの最低の値ですがシステムにより異なるので 1 でも十分に小さいとしようということでしょう

1 でなく 1.0 というのは大切です。1.0 は浮動小数点数として計算しなさいという意味です。RAND_MAXはintで扱える整数の最大値でもありますから、整数のまま 1 を足すと計算の限界を越えてしまいます(オーバーフローといいます)。

値の範囲 値の種類 解説
rand() 0 ≦ a ≦ RAND_MAX 整数 RAND_MAXはシステムにより 32767 だったり 2147483647 だったりします
rand()/(RAND_MAX+1.0) 0 ≦ a < 1 浮動小数点数 まず 0 ≦ a < 1 の乱数aを作る
rand()/(RAND_MAX+1.0)*12 0 ≦ a < 12 浮動小数点数 1から12の12種類の数が必要なので12を掛ける
rand()/(RAND_MAX+1.0)*12+1 1 ≦ a < 13 浮動小数点数 1から12なので1を足す
int a = rand()/(RAND_MAX+1.0)*12+1 1 ≦ a ≦ 12 整数 intに代入で小数点以下が切り捨てられる。 1 ≦ a < 13 の整数と 1 ≦ a ≦ 12 の整数は同じ意味

実行結果 k1302.c

~/c$ ./k1302
    1     0        0        0     6        6     0
    2     1        1        6     5       11     5
    3    11       12       12     6       18     0
    4    10       22       22     5       27     0
    5     1       23       27     6       33     4
    6     8       31       33     5       38     2
    7     7       38       38     5       43     0
    8    12       50       50     7       57     0
    9    12       62       62     3       65     0
   10     1       63       65     4       69     2
   11    11       74       74     5       79     0
   12     3       77       79     4       83     2
   13     7       84       84     4       88     0
   14     8       92       92     3       95     0
   15     9      101      101     6      107     0
   16     9      110      110     3      113     0
   17     6      116      116     6      122     0
   18     7      123      123     4      127     0
   19     6      129      129     4      133     0
   20    10      139      139     5      144     0
   21     1      140      144     5      149     4
   22     2      142      149     6      155     7
   23    11      153      155     3      158     2
   24     7      160      160     7      167     0
   25     3      163      167     5      172     4
   26     1      164      172     3      175     8
   27     2      166      175     4      179     9
   28     5      171      179     6      185     8
   29     6      177      185     7      192     8
   30     9      186      192     3      195     6
   31     8      194      195     5      200     1
   32     3      197      200     3      203     3
   33     3      200      203     6      209     3
   34     5      205      209     6      215     4
   35     2      207      215     3      218     8
   36     4      211      218     3      221     7
   37     8      219      221     4      225     2
   38    10      229      229     5      234     0
   39     6      235      235     4      239     0
   40     5      240      240     6      246     0
   41    11      251      251     5      256     0
   42     9      260      260     7      267     0
   43     8      268      268     3      271     0
   44     8      276      276     3      279     0
   45     1      277      279     4      283     2
   46     4      281      283     6      289     2
   47    10      291      291     5      296     0
   48    10      301      301     7      308     0
   49     4      305      308     3      311     3
   50     9      314      314     4      318     0
   51     5      319      319     7      326     0
   52     8      327      327     3      330     0
   53     5      332      332     4      336     0
   54     7      339      339     7      346     0
   55     9      348      348     7      355     0
   56     6      354      355     5      360     1
   57     4      358      360     3      363     2
   58     7      365      365     7      372     0
   59     4      369      372     3      375     3
   60     1      370      375     4      379     5
   61     5      375      379     4      383     4
   62    12      387      387     3      390     0
   63    11      398      398     6      404     0
   64     2      400      404     3      407     4
   65    12      412      412     7      419     0
   66     7      419      419     4      423     0
   67    11      430      430     3      433     0
   68     5      435      435     4      439     0
   69     7      442      442     7      449     0
   70     1      443      449     4      453     6
   71    10      453      453     5      458     0
   72    10      463      463     3      466     0
   73     9      472      472     4      476     0
   74     1      473      476     7      483     3
   75     5      478      483     3      486     5
   76     3      481      486     6      492     5
   77     6      487      492     3      495     5
   78    11      498      498     4      502     0
   79    12      510      510     3      513     0
   80     6      516      516     7      523     0
   81    11      527      527     3      530     0
   82     3      530      530     6      536     0
   83     3      533      536     5      541     3
   84    12      545      545     6      551     0
   85     6      551      551     7      558     0
   86    11      562      562     3      565     0
   87     6      568      568     6      574     0
   88     4      572      574     3      577     2
   89    12      584      584     4      588     0
   90     1      585      588     4      592     3
   91     5      590      592     4      596     2
   92     1      591      596     7      603     5
   93     6      597      603     7      610     6
   94     2      599      610     4      614    11
   95    12      611      614     6      620     3
   96     4      615      620     7      627     5
   97     8      623      627     5      632     4
   98     8      631      632     7      639     1
   99     1      632      639     5      644     7
  100     7      639      644     5      649     5
聖愛中学高等学校
http://www.seiai.ed.jp/
Feb. 2012