13  作業時間の不確実性

13.1 学習目標

  • 3 点見積もりにより,作業時間の平均と分散を推定できる.
  • パスの所要時間の平均と分散を求めることができる.
  • 指定された期日までにプロジェクトが完了する確率を求めることができる.

13.2 3 点見積もり

チャプター 12 で述べた方法は,作業の所要時間が確定していることを前提としている.しかし,実際には,所要時間を正確に見積もることは難しい場合が多い.そこで,作業の所要時間を確率変数として扱い,3 点見積もり(Three-Point Estimation)という方法でその平均と分散を推定する.

3 点見積もりでは,次の 3 つの所要時間が事前に与えられているとする.

  • 楽観値(Optimistic Time, a):予想される最短の所要時間.
  • 最頻値(Most Likely Time, m):最も可能性が高い所要時間.
  • 悲観値(Pessimistic Time, b):予想される最長の所要時間.

一般に,a \leq m \leq b である.

この a,m,b に基づいて,所要時間の平均 \mu と分散 \sigma^2 を次のように推定する.

\hat{\mu} = \frac{a + 4m + b}{6}, \quad \hat{\sigma}^2 = \left(\frac{b - a}{6}\right)^2 \tag{13.1}

これらは,PERT で広く用いられる平均と分散の近似式である.これらの式の理論的背景に興味のある読者は,Pleguezuelo ほか (2003年) を参照されたい.

以下では,作業点 v の楽観値,最頻値,悲観値をそれぞれ a(v),m(v),b(v) とし,所要時間の平均と分散の推定値をそれぞれ \hat{\mu}(v),\hat{\sigma}^2(v) とする.すべての作業点 v \in V に対して,

\hat{\mu}(v) = \frac{a(v) + 4m(v) + b(v)}{6}, \quad \hat{\sigma}^2(v) = \left(\frac{b(v) - a(v)}{6}\right)^2

を用いて \hat{\mu}(v) と \hat{\sigma}^2(v) を計算する.

例 13.1 例 12.2 のプロジェクト・ネットワークにおいて,各作業点の楽観値 a,最頻値 m,悲観値 b が 表 13.1 のように与えられたとする.先行作業の集合 \mathcal{P}(v) は 例 12.2 と同じである.このとき,平均 \hat{\mu} と分散 \hat{\sigma}^2 を求めると,同表の右 2 列のようになる.

表 13.1: 各作業点の先行作業,3 点見積もり,所要時間の平均・分散
v \mathcal{P}(v) a m b \hat{\mu} \hat{\sigma}^2
s - 0 0 0 0 0
A s 0.5 2 3.5 2 0.25
B s 1.5 3 4.5 3 0.25
C A 2.5 4 5.5 4 0.25
D A 0.5 2 3.5 2 0.25
E B 1 5.5 7 5 1
F C, D, E 5 8 17 9 4
G E 0.5 2 3.5 2 0.25
t F, G 0 0 0 0 0

例えば,作業 F の平均と分散は,

\hat{\mu}(\mathrm{F}) = \frac{5 + 4 \times 8 + 17}{6} = 9, \quad \hat{\sigma}^2(\mathrm{F}) = \left(\frac{17 - 5}{6}\right)^2 = 4

である.

13.3 プロジェクトの完了確率

3 点見積もりを用いて,各作業点 v \in V の所要時間の平均 \hat{\mu}(v) と分散 \hat{\sigma}^2(v) を求めたとする.このとき,与えられた期日までにプロジェクトが完了する確率を求めたい.例えば,「プロジェクトが 20 日以内に完了する確率はどれくらいか?」という問いである.

各作業の所要時間は互いに独立であると仮定する.このとき,プロジェクト・ネットワークにおけるパス P = (s, v_{i_1}, v_{i_2}, \ldots, v_{i_k}, t) の所要時間の平均と分散は,それぞれ次の \hat{\mu}(P) と \hat{\sigma}^2(P) で推定できる.

\hat{\mu}(P) = \sum_{v \in P} \hat{\mu}(v), \quad \hat{\sigma}^2(P) = \sum_{v \in P} \hat{\sigma}^2(v)

パス P の所要時間の標準偏差 \hat{\sigma}(P) は,

\hat{\sigma}(P) = \sqrt{\hat{\sigma}^2(P)}

で与えられる.始点 s から終点 t までのパスのうち,所要時間の平均 \hat{\mu}(P) が最大のものをクリティカルパス P^* とする.P^* は,セクション 12.5 で述べた方法において,作業時間 \tau(v) を \hat{\mu}(v) に置き換えれば求めることができる.

クリティカルパス P^* の所要時間を X とし,期日 d までにプロジェクトが完了する確率を \mathbb{P}(X \leq d) と表す.

\mathbb{P}(X \leq d) = \Phi\left(\frac{d - \hat{\mu}(P^*)}{\hat{\sigma}(P^*)}\right)

ここで,\Phi(z) は標準正規分布の累積分布関数である.z は次のように計算し,標準正規分布表を用いて \Phi(z) を調べる.

z = \frac{d - \hat{\mu}(P^*)}{\hat{\sigma}(P^*)}

例 13.2 例 13.1 のプロジェクトが,期日 d = 20 日までに完了する確率を求めよ.

表 13.1 の平均 \hat{\mu}(v) は,表 12.2 の作業時間 \tau(v) と一致する.したがって,クリティカルパスは セクション 12.5 で求めた P^* = (s, \mathrm{B}, \mathrm{E}, \mathrm{F}, t) であり,このパスの所要時間の平均,分散,標準偏差は次のように計算できる.

\hat{\mu}(P^*) = 3 + 5 + 9 = 17

\hat{\sigma}^2(P^*) = 0.25 + 1 + 4 = 5.25

\hat{\sigma}(P^*) = \sqrt{5.25} \approx 2.29

次に,z を計算すると,次のようになる.

z = \frac{20 - 17}{2.29} \approx 1.31

標準正規分布表より,\Phi(1.31) \approx 0.9049 である.したがって,期日 d = 20 日までにプロジェクトが完了する確率は約 90.49% である.

以上の方法では,計算を簡単にするために,クリティカルパスが所要時間の最も長いパスであると仮定している.しかし,実際には,平均値から求めたクリティカルパスが,所要時間の最も長いパスであるとは限らない.そのため,クリティカルパスを用いて計算した確率は,実際の確率を過大評価する可能性がある.

13.4 モンテカルロ・シミュレーション(発展)

実務では,各作業の所要時間を乱数で生成し,プロジェクトの所要時間を何度も計算するモンテカルロ・シミュレーションがよく用いられる.

例 13.2 のプロジェクトが期日 d = 20 日までに完了する確率を,シミュレーションで求める.ここでは,各作業の所要時間は互いに独立に正規分布 N(\hat{\mu}(v), \hat{\sigma}^2(v)) に従うとする.作業時間を乱数で生成し,セクション 12.5 と同様にトポロジカルオーダーに従って最早終了時刻を計算すると,終点の最早終了時刻 EF(t) がプロジェクトの所要時間 T となる.これを 10 万回繰り返し,T \leq 20 となった割合を確率の推定値とする.また,クリティカルパスの所要時間 X も計算し,X = T,すなわちクリティカルパスが最も時間がかかるパスとなった割合も調べる.Python では,以下のように計算できる.

import networkx as nx
import numpy as np
from scipy.stats import norm

# 各作業の 3 点見積もり(a, m, b)
three_point = {
    "s": (0, 0, 0),
    "A": (0.5, 2, 3.5),
    "B": (1.5, 3, 4.5),
    "C": (2.5, 4, 5.5),
    "D": (0.5, 2, 3.5),
    "E": (1, 5.5, 7),
    "F": (5, 8, 17),
    "G": (0.5, 2, 3.5),
    "t": (0, 0, 0),
}
mu = {v: (a + 4 * m + b) / 6 for v, (a, m, b) in three_point.items()}
sigma = {v: (b - a) / 6 for v, (a, m, b) in three_point.items()}

# プロジェクト・ネットワーク
G = nx.DiGraph()
edges = [
    ("s", "A"),
    ("s", "B"),
    ("A", "C"),
    ("A", "D"),
    ("C", "F"),
    ("D", "F"),
    ("B", "E"),
    ("E", "G"),
    ("E", "F"),
    ("G", "t"),
    ("F", "t"),
]
G.add_edges_from(edges)

rng = np.random.default_rng(0)
n = 100_000  # 試行回数
d = 20  # 期日

# 各作業の所要時間を n 回分生成する
tau = {v: rng.normal(mu[v], sigma[v], size=n) for v in G}

# トポロジカルオーダーに従って最早終了時刻を計算する
EF = {}
for v in nx.topological_sort(G):
    predecessors = list(G.predecessors(v))
    if predecessors:
        ES = np.max([EF[u] for u in predecessors], axis=0)
    else:
        ES = np.zeros(n)  # 始点 s
    EF[v] = ES + tau[v]
T = EF["t"]  # プロジェクトの所要時間

# クリティカルパスの所要時間と,その正規分布による近似
critical_path = ["s", "B", "E", "F", "t"]
X = sum(tau[v] for v in critical_path)
mu_P = sum(mu[v] for v in critical_path)
sigma_P = np.sqrt(sum(sigma[v] ** 2 for v in critical_path))

print(f"Critical path: {norm.cdf((d - mu_P) / sigma_P):.3f}")
print(f"Simulation:    {np.mean(T <= d):.3f}")
print(f"P(X = T):      {np.mean(np.isclose(X, T)):.3f}")
Critical path: 0.905
Simulation:    0.904
P(X = T):      0.933

クリティカルパスによる近似(Critical path)は約 0.905,シミュレーション(Simulation)は約 0.904 であり,両者はほぼ一致する. クリティカルパスの所要時間が最も長くなった試行の割合は約 93% であり,残りの試行では,ほかのパスのほうが時間がかかった.

図 13.1 は,シミュレーションで得られた T のヒストグラムと,正規分布 N(17, 5.25) の確率密度関数を示す.点線より左側の面積が,期日 d = 20 日までに完了する確率に相当する.この例では,両者はほぼ重なっている.

コード
import matplotlib.pyplot as plt

x = np.linspace(8, 28, 400)
fig, ax = plt.subplots()
ax.hist(
    T,
    bins=80,
    range=(8, 28),
    density=True,
    color="0.8",
    edgecolor="white",
    linewidth=0.5,
    label="Simulation",
)
ax.plot(x, norm.pdf(x, mu_P, sigma_P), color="black", linewidth=1, label="Critical path")
ax.axvline(d, color="black", linestyle=":", linewidth=1)
ax.text(d, 0.97, f" $d = {d}$", va="top", transform=ax.get_xaxis_transform())
ax.set_xticks(range(8, 29, 4))
ax.set_xlabel("Project duration (days)")
ax.set_ylabel("Density")
ax.legend(frameon=False, loc="upper left")
fig.tight_layout()
plt.show()
横軸はプロジェクトの所要時間(日),縦軸は確率密度である.灰色のヒストグラムはシミュレーションで得られた所要時間の分布で,17 日付近を頂点とするほぼ左右対称な山形をしている.黒い曲線は正規分布 N(17, 5.25) の確率密度関数で,ヒストグラムとほぼ重なっている.20 日の位置に縦の点線がある.
図 13.1: プロジェクトの所要時間 T のヒストグラムと正規分布 N(17, 5.25) の確率密度関数

13.5 まとめ

  • 3 点見積もりでは,楽観値 a,最頻値 m,悲観値 b から,\hat{\mu} = (a + 4m + b)/6,\hat{\sigma}^2 = ((b - a)/6)^2 と推定する.
  • 各作業の所要時間が互いに独立であるとき,パス P の所要時間の平均と分散は,パス上の作業の平均と分散の和 \hat{\mu}(P) = \sum_{v \in P} \hat{\mu}(v),\hat{\sigma}^2(P) = \sum_{v \in P} \hat{\sigma}^2(v) で推定できる.
  • 平均 \hat{\mu}(P) が最大のパスをクリティカルパス P^* とし,z = (d - \hat{\mu}(P^*))/\hat{\sigma}(P^*) に対する \Phi(z) を標準正規分布表で調べることで,期日 d までに完了する確率を求める.
  • 平均から求めたクリティカルパスが最も時間のかかるパスであるとは限らないため,この方法で求めた確率は過大評価になりうる.

13.6 練習問題

練習 13.1 表 13.2 は,練習 12.1 のプロジェクトの各作業について,3 点見積もりを与えたものである.以下の問いに答えよ.

表 13.2: 作業 A〜H の先行作業と 3 点見積もり(単位:日)
作業 先行作業 a m b
A - 2 5 8
B - 1.5 3 4.5
C A 5 6.5 11
D A 2 5 14
E B 3 6 15
F D, E 1 2.5 7
G E 7 10 13
H C, F 6.5 8 9.5
  1. 各作業の所要時間の平均と分散を求めよ.
  2. 所要時間の平均を用いて,クリティカルパスを求めよ.また,クリティカルパスの所要時間の平均,分散,標準偏差を求めよ.
  3. プロジェクトが 25 日以内に完了する確率を求めよ.
  4. 実際にプロジェクトが 25 日以内に完了する確率と比べて,3. で求めた確率は過大評価と過小評価のどちらになりうるか.クリティカルパス以外のパスに着目して,理由とともに答えよ.

練習 13.2 (プログラミング) 本文のシミュレーションのコードを参考に,練習 13.1 のプロジェクトについて,以下の問いに答えよ.ただし,各作業の所要時間は互いに独立に正規分布 N(\hat{\mu}(v), \hat{\sigma}^2(v)) に従うとし,試行回数は 10 万回とする.

  1. プロジェクトが 25 日以内に完了する確率をシミュレーションで求め,練習 13.1 の 3. で求めた確率と比較せよ.
  2. 始点 s から終点 t までの各パスについて,そのパスの所要時間が最も長くなった試行の割合を求めよ.
  3. 期日 d を 20 日から 30 日まで 1 日ずつ変えて,クリティカルパスによる確率とシミュレーションによる確率を求め,グラフに描いて比較せよ.