お知らせ

ただいま、シンタックスハイライターの設定を見直しております。
プログラムが見にくくなっているページがありますが、ご容赦ください。

待ち行列で窓口の個数を可変にできるようにPythonで書いてみた

モデル化とシミュレーション

こんにちは。前回は待ち行列で窓口の個数を2個にしました。

せっかくプログラミング言語で書いているので,窓口の個数を可変にしてみます。

前回との変更点

実は,たいして変更しないで作れます。

前回のリンクを貼っておきます。

ここで変更する点は次になります。

end_time = [ 0, 0 ]
    counter_no = 0 if end_time[0] <= end_time[1] else 1

変更後は次になります。このとき,変数 counter には窓口の個数が代入されているものとします。

end_time = [ 0 ] * counter
    counter_no, mi = 0, end_time[0]
    for j, e in enumerate( end_time[1:], 1 ):
        if mi > e:
            counter_no, mi = j, e

変更されたプログラム

修正されたプログラム全体は次になります。

import random
import math

# パラメータを設定する
lam = 4
num = 20
counter = 3
menu = [ ('うどん',  0.15, 40 ),
         ('そば' ,  0.1 , 30 ),
         ('ラーメン', 0.2 , 50 ),
         ('カレー',  0.25, 20 ),
         ('定食',  0.3 , 60 ) ]

# 初期値を決める
arrival_time = 0
end_time = [ 0 ] * counter
print( '客No  到着 開始 窓口 注文  調理  受取 待ち' )

# お客さんごとにシミュレーションする
for i in range( 1, num + 1, 1 ):
    # お客さんが来る時刻を決める
    r = random.random()
    interval = -60 * math.log( 1 - r ) / lam
    arrival_time += interval
    # お客さんが並ぶ窓口を決める
    counter_no, mi = 0, end_time[0]
    for j, e in enumerate( end_time[1:], 1 ):
        if mi > e:
            counter_no, mi = j, e

    # お客さんが注文するものを決める
    r = random.random()
    probability = 0
    for item in menu:
        if probability > r:
            break
        probability += item[1]

    # 時間を計算する
    start_time = arrival_time if arrival_time > end_time[counter_no] else end_time[counter_no]
    end_time[counter_no] = start_time + item[2]
    wait_time = start_time - arrival_time
    # お客さんごとに表示する
    print( 'No{:>2d} {:>4.0f} {:>4.0f}    {} {:<5} {:>2d} {:>4.0f} {:>4.0f}'
        .format( i, arrival_time, start_time, counter_no+1, item[0], item[2], end_time[counter_no], wait_time ) )

実行結果

counter = 3 のときの実行結果は次になります。

客No  到着 開始 窓口 注文  調理  受取 待ち
No 1   37   37    1 定食    60   97    0
No 2   42   42    2 定食    60  102    0
No 3   42   42    3 定食    60  102    0
No 4   48   97    1 そば    30  127   50
No 5   72  102    2 定食    60  162   31
No 6   81  102    3 カレー   20  122   21
No 7   92  122    3 ラーメン  50  172   31
No 8   95  127    1 定食    60  187   32
No 9  137  162    2 定食    60  222   25
No10  155  172    3 カレー   20  192   18
No11  188  188    1 定食    60  248    0
No12  202  202    3 そば    30  232    0
No13  204  222    2 定食    60  282   18
No14  212  232    3 定食    60  292   20
No15  229  248    1 カレー   20  268   18
No16  242  268    1 定食    60  328   26
No17  275  282    2 定食    60  342    7
No18  299  299    3 カレー   20  319    0
No19  305  319    3 定食    60  379   14
No20  331  331    1 定食    60  391    0

counter = 1 にしてもちゃんと動きます。

客No  到着 開始 窓口 注文  調理  受取 待ち
No 1    2    2    1 定食    60   62    0
No 2   69   69    1 定食    60  129    0
No 3   80  129    1 定食    60  189   49
No 4   99  189    1 定食    60  249   90
No 5   99  249    1 定食    60  309  150
No 6  100  309    1 ラーメン  50  359  209
No 7  101  359    1 定食    60  419  258
No 8  107  419    1 定食    60  479  312
No 9  107  479    1 定食    60  539  371
No10  152  539    1 定食    60  599  387
No11  156  599    1 ラーメン  50  649  443
No12  220  649    1 そば    30  679  429
No13  233  679    1 定食    60  739  446
No14  238  739    1 ラーメン  50  789  501
No15  243  789    1 定食    60  849  545
No16  277  849    1 定食    60  909  572
No17  319  909    1 定食    60  969  590
No18  323  969    1 カレー   20  989  646
No19  333  989    1 ラーメン  50 1039  655
No20  354 1039    1 定食    60 1099  685

調子に乗って counter = 20 にしてみます。

客No  到着 開始 窓口 注文  調理  受取 待ち
No 1    9    9    1 定食    60   69    0
No 2   31   31    2 定食    60   91    0
No 3   35   35    3 定食    60   95    0
No 4   41   41    4 定食    60  101    0
No 5   53   53    5 そば    30   83    0
No 6   54   54    6 定食    60  114    0
No 7   57   57    7 そば    30   87    0
No 8   60   60    8 定食    60  120    0
No 9   82   82    9 定食    60  142    0
No10   85   85    10 定食    60  145    0
No11  106  106    11 そば    30  136    0
No12  168  168    12 そば    30  198    0
No13  181  181    13 定食    60  241    0
No14  196  196    14 定食    60  256    0
No15  201  201    15 ラーメン  50  251    0
No16  217  217    16 定食    60  277    0
No17  218  218    17 そば    30  248    0
No18  221  221    18 そば    30  251    0
No19  224  224    19 定食    60  284    0
No20  231  231    20 定食    60  291    0

今回はこれでおしまいにします。それではまた。

Posted by kasugai