オペレーションズ・リサーチ

運動会の受付窓口は何個必要か(指数サービス以外の場合)

オペレーションズ・リサーチ

[PR]当サイトはアフィリエイト広告を利用しています。

前回は運動会の受付窓口は何個必要かというテーマを待ち行列理論で考えました。

この話の前提として、サービス時間は指数サービスに従うという仮定を置きました。

しかし指数サービスだと、サービス時間が0に近いほど起こる確率が高いという状態となり、サービス時間が0分という人が最も多いという仮定でした。

一般に出席者を識別する以上何らかの手間は発生するため、サービス時間が0分という仮定は少しおかしいです。

そこで今回はサービス時間が指数サービスではない一般のサービスM/G/sモデルで平均待ち時間Wqと待っている出席者の平均数Lqをいくつかの場合で求めます。

参考にしたのは以下。

加藤豊、加藤理(2018)『例題でよくわかる はじめてのオペレーションズ・リサーチ』森北出版株式会社.

前回の問題に以下の条件を加えます。

ケース①サービス時間は1分から5分の間で一様分布している。

ケース②サービス時間は1分でのサービスが起きる確率が5分で起きる確率の5倍で線形分布。

ここでサービス時間の長さをSとし、Sの確率密度関数をg(t)とおく。

g(t)は以下のグラフとなる。

ケース①

ケース②

以下計算していきます。

ケース①

g(t)は

1/4,1<=t<=5

0,その他 である。

1/4というのは確率密度関数をすべての区間で積分した合計はすべての場合の確率の合計である1になるというところから求めている。

また平均サービス時間mは3分である。

これはサービス時間が一様分布なので、中間はサービス時間の中間に等しいから1分から5分の中間を平均としている。

このとき分散は

よって標準偏差σは

c=σ/m=2/(3√3)

λ=2人/分

μ=1/m=1/3人/分

a=λ/μ=6

よって窓口数sは7以上必要。

このときWqは

Wq=(1/2)(1+c^2)Wq(M/M/s)

また

Lq=λWq

計算すると

Wq≒1.06

Lq≒2.11

前回の指数サービスのときは

Wq=4/9分

Lq= 8/9人

だったので一様サービスのときはさらに時間がかかるし窓口も3個から7個に増設する必要があるという見通しです。

これはサービスに時間がかかる人が圧倒的に増えたからですね。

指数サービスでは5分かかるような人はほとんどいない、1分以下の人がとても多いという仮定ですから、一様サービスなら時間とマンパワーが必要になるのは当たり前です。

ケース②

g(t)は

(-1/12)t+1/2,1<=t<=5 0,その他 g(t)の求め方は g(t)=at+bと置いて g(1)=5g(5) (g(1)+g(5)*(5-1)/2)=1 から求めています。 二番目の式は確率密度関数の積分は1になるという性質から作成しています。台形公式ですね。 サービス時間の平均をm、分散をσ^2、標準偏差をσとして

ここから計算すると

Wq≒1.06

Lq≒2.12

窓口は6個必要です。

一様分布での窓口数は7個だったのでケース②のほうが必要窓口が減っています。

時間がかかる人が減ったので窓口も減るんですね。しかしケース②の窓口数はM/M/sモデルの2倍となっています。

条件次第でかなり変動しますね。

Wq(M/M/s)や積分計算の代入部分などは手計算ではミスが増えるのでプログラムにしてみました。

プログラミングブログですからこういうのもやっていきます。

Wq(M/M/s)を求める。

import math
def calcLqWq(lam,mu,s):
    a = lam / mu
    rho = a / s
    p1 = 0
    for i in range(s):
        p1 += (a**i) /  math.factorial(i)
    p2 = (a**s) / ((math.factorial(s-1))*(s-a))
    P0 = 1 / (p1 + p2)
    l1 = a**(s+1)
    l2 = (math.factorial(s-1))*(s-a)*(s-a)
    Lq = P0 * l1 / l2
    Wq = Lq / lam
    return Lq, Wq

ケース①

lam = 2
mu = 1/3
s = 7
Lq, Wq = calcLqWq(lam,mu,s)
print("Lq"," ","Wq")
print(Lq,Wq)
c = 2/(3*math.sqrt(3))
Wq2 = 0.5*(1+(c**2))*Wq
Lq2 = lam * Wq2
print("Lq2"," ","Wq2")
print(Lq2,Wq2)

ケース②

lam = 2
m = -(5**3)/36+(5**2)/4-(-1/36+1/4)
def calcTemp(x,m):
    temp = -(x**4)/48+(x**3)*(2*m/12+6/12)/3+(x**2)*(-m*m/12-m)/2+m*m*x/2
    return temp
v = calcTemp(5,m)-calcTemp(1,m)
st = math.sqrt(v)
c = st / m
mu = 1 / m
a = lam / mu
print('st:',st)
print('m',m)
print('mu',mu)
print('a:',a)
c = st / m
s = 6
Lq, Wq = calcLqWq(lam,mu,s)
print("Lq"," ","Wq")
print(Lq,Wq)
Wq2 = 0.5*(1+(c**2))*Wq
Lq2 = lam * Wq2
print("Lq2"," ","Wq2")
print(Lq2,Wq2)

待ち行列は条件次第で窓口数がかなり変動するので、前回のデータをよく活用するのが大事ですね。