マンガで読む
Month 4 07:30 第二小学校・体育館
朝の体育館で、吐く息が白くなった。
黒板には、チョークの字がびっしり並んでいる。断熱、薪、ストーブ、保存食、水タンク、蓄電池。誰かが書き足し、誰かが線を引き、また別の誰かが丸で囲む。黒板の前では、三つの声がぶつかっていた。
「まずストーブだ。凍えたら何もできねえ」とゲンが言う。
「食べ物が先です。収穫が遅れたら、冬の途中で尽きます」とハルが返す。
「その前に、体育館の壁がスカスカなんだって。断熱しないと、薪がいくらあっても足りないよ」と、港地区から手伝いに来た若い大工が言う。
三人とも正しい。だから終わらない。
ナギは黒板の写真を撮るかわりに、アカリの画面に一行ずつ打ち込んだ。作業の名前と、かかりそうな日数と、「これをやる前に何が終わっていなきゃいけないか」。全部で十一個。
ありがとうございます。計画を立てる前に、確認させてください。 初雪の見込みは40日後。使える人手は、2チームですね。 結論から言います。今のままでは、2日足りません。確信度:中。根拠:あなたが入力した日数と依存関係。日数そのものが外れれば、結論も変わります。
体育館が静かになった。
「……二日? どの作業が悪いんだ」とゲン。
どれも悪くありません。悪いのは順番と人手の組み合わせです。そして、どこに人を足しても同じように効くわけではありません。
その晩、ナギはアカリの保存フォルダの奥に、レイの書いたメモを見つけた。日付は崩壊の二年前。
計画は外れる。 外れないように祈るより、外れ方を設計せよ。 どこが遅れたら全体が遅れるのか。どこは遅れても平気なのか。 それを毎朝、計算し直せる道具であれ。
計画とは「依存関係」を整理すること
黒板の前の口論は、実は答えの出せる問題です。必要なのは、作業ごとの日数 と、作業同士の前後関係 だけ。これを図にすると、第1章で崩壊の連鎖を読んだときと同じ依存グラフ になります。
点(ノード)が作業、矢印が「左が終わらないと右を始められない」という関係です。第5章の技術ツリーが「何を作れるようになるか」の地図だったとすれば、こちらは「今月、誰が何をするか」の地図です。
flowchart TD
S[断熱調査 3日] --> M[断熱材の回収 8日]
M --> I[断熱工事 10日]
S --> ST[ストーブ設置 6日]
ST --> CO[CO警報器 2日]
S --> P[水タンク凍結対策 7日]
S --> B[蓄電池の保温箱 4日]
H[収穫 14日] --> F[保存食 10日]
W[薪集め 12日] --> MV[冬季居住区へ移動 3日]
I --> MV
CO --> MV
F --> MV
P --> MV
B --> MV
図9-1 冬支度の依存グラフ(日数は作中の想定)。矢印は「左が終わってから右に着手できる」を表す。
このグラフには大事な性質があります。矢印をどうたどっても、元の場所に戻ってこない。こういうグラフを有向非巡回グラフ(DAG) と呼びます。DAGであれば、必ず「前提を守った順番」が少なくとも一つ存在します。
順番を決める:トポロジカルソート
前提を守った並べ方を求める操作をトポロジカルソート といいます。代表的な方法のひとつが、1962年にアーサー・カーン(Arthur B. Kahn)が学術誌 Communications of the ACM に発表したアルゴリズムです。考え方は、黒板の前でも実行できるほど単純です。
各作業について「まだ終わっていない前提の数」を数える。
前提の数がゼロの作業(すぐ着手できる作業)を「着手可能リスト」に入れる。
リストから一つ取り出して順番に加え、それを前提にしていた作業の数を1減らす。ゼロになったらリストに入れる。
リストが空になるまで繰り返す。
未完了の前提数 = 各作業の前提の数
着手可能 = [前提数が0の作業]
順番 = []
while 着手可能が空でない:
a = 着手可能から1つ取り出す
順番に a を加える
for b in (a を前提にしている作業):
b の前提数 -= 1
if b の前提数 == 0: 着手可能に b を加える
if 順番の長さ < 作業の数:
循環依存がある(どこかで堂々巡りしている)
計算量は作業の数と矢印の数の合計に比例します(O(V+E))。数千の作業でも、アカリのような小さな計算機で一瞬です。
最後の2行に注目してください。もし「AにはBが先、BにはAが先」という循環依存 があると、どちらも前提数がゼロにならず、リストが途中で空になります。つまりこのアルゴリズムは、計画が論理的に不可能なことも検出してくれる のです。
どこが遅れると全体が遅れるか:クリティカルパス
順番がわかっても、「何日で終わるか」はまだわかりません。人手が無限にあって、着手できる作業をすべて同時に進められるとしましょう。それでも全体は、依存の連なりの中で日数の合計がいちばん長い道筋 より早くは終わりません。この道筋をクリティカルパス と呼びます。
図9-1では、収穫(14日)→ 保存食(10日)→ 移動(3日)の27日がクリティカルパスです。断熱の道筋(調査3+回収8+工事10+移動3=24日)は、3日の余裕(フロート )を持っています。
クリティカルパス上の作業が1日遅れれば、全体が1日遅れる。
フロートのある作業は、その日数までは遅れても全体に影響しない。
この考え方は、1950年代後半にデュポン社のモーガン・ウォーカーとレミントン・ランド社のジェームズ・ケリーが開発したクリティカルパス法(CPM) として体系化されました。ほぼ同じ時期に、米海軍とブーズ・アレン・ハミルトンがPERT という手法を作っており、二つは今もよく組み合わせて使われます。
ゲンたち三人がそれぞれ正しかった理由 ストーブ派、食料派、断熱派。三人の主張は、それぞれ別の道筋を守ろうとしていました。クリティカルパスを計算すると、今いちばん危ないのは「食料」の道筋だとわかります。正しさを比べるのではなく、遅れたときの影響 を比べれば、議論は終わります。
人手が足りないとき:優先度つきの割り当て
現実には人手に限りがあります。2チームしかいなければ、着手可能な作業が4つあっても、同時に進められるのは2つだけです。このとき、どの作業から手をつけるかで、終わる日が変わります。
アカリが使っているのは、リスト・スケジューリング と呼ばれる単純な方法です。着手可能な作業のうち、「そこから最後までの残りの道のりがいちばん長いもの」を優先して、空いたチームに割り当てます。クリティカルパスに近い作業ほど先に始める、という発想です。必ず最適な答えを出す方法ではありませんが、速くて、なぜその順番なのかを人に説明できます。
表の最後の2行を見比べてください。3チームから6チームへ人手を倍にしても、2日しか縮みません。27日というクリティカルパスの壁より早くは、何人いても終われないからです。人を足すなら、クリティカルパスが詰まっている間だけ 。これが、限られた人手で計画を立てるときのいちばん大事な直感です。
外れ方を設計する:再計画
レイのノートの「計画は外れる」は、悲観ではなく工学的な前提です。雨が降れば断熱材の回収は遅れるし、収穫は天気しだいです。プランナーで試すと、3チームの場合でも次のように変わります。
雨で断熱材の回収が6日延びる → 全体は31日目に。断熱の道筋がクリティカルパスに入れ替わる。
収穫が5日遅れる → 全体は32日目に。食料の道筋がさらに伸びる。
大事なのは、遅れが起きたときにクリティカルパスが入れ替わる ことです。昨日まで余裕のあった作業が、今日から最優先になるかもしれない。だから計画は一度立てて終わりではなく、次のループで回します。
毎朝、各作業の進み具合と残り日数を更新する。
依存グラフで計算し直し、クリティカルパスと各作業の余裕を出す。
クリティカルパスが変わったら、人手の配置を変える。
締め切りを越えそうなら、早めに知らせる。作業を削る、外から人を借りる、締め切りそのものを疑う。
人間の頭でこれを毎朝やるのは大変ですが、計算機には得意な仕事です。アカリの役目は計画を当てる ことではなく、外れたときにすぐ計算し直して、どこに手を打てばいいかを示す ことです。
循環依存が見つかったら
プランナーで「循環依存を入れる」を押すと、「ストーブ設置には断熱工事が先」「断熱工事には(作業場を暖める)ストーブが先」という二つの条件が同時に入ります。Kahnのアルゴリズムは途中で止まり、どの作業も始められなくなります。
こうなったら、計算では解決できません。人間がどちらかの依存を切る 必要があります。たとえば「仮設の暖房で断熱工事を先に進める」。循環は、計画の間違いというより前提の思い込み であることが多く、それを見つけてくれるだけでも計算には価値があります。
Month 4 18:00 体育館
三つめのチームは、思いがけないところから来た。
体育館の隅で毎日編み物をしていた年配の女性たちが、「重いものは持てないけど、箱くらいは作れるよ」と手を挙げたのだ。蓄電池の保温箱と、水タンクの凍結対策。どちらも余裕のある作業だ。若いチームは、収穫と断熱に回れる。
再計算しました。3チームで29日目に完了見込みです。初雪まで11日の余裕があります。 ただし、最も遅れに弱いのは収穫と保存食の道筋です。毎朝、ここの進み具合を教えてください。
ゲンは黒板の前で腕を組んだまま、しばらく黙っていた。
「段取りってのはな、昔は親方の頭の中にあったんだ。誰も口出しできねえ」
チョークを取り、黒板の「収穫」に太い丸をつける。
「こうやって全員に見えるなら、文句も言えるし、手も貸せる。……悪くねえ」
翌朝から、体育館の黒板の右端には、毎日書き換えられる一行が加わった。 「今日のクリティカルパス:収穫(残り9日)」
この章で学んだこと
計画の正体は依存グラフ(DAG)。作業の日数と前後関係があれば、議論でなく計算で順番を決められる。
Kahnのアルゴリズム(1962年)は、前提のない作業から順に取り出してトポロジカルソートを行い、循環依存も検出できる。
全体の最短日数はクリティカルパスで決まる。クリティカルパス上の遅れは全体の遅れになり、フロートのある作業は少し遅れても平気。
人手が限られるときは、残りの道のりが長い作業を優先して割り当てる。人を足して効くのは、クリティカルパスが詰まっている間だけ。
計画は外れる前提で、毎日計算し直す。遅れによってクリティカルパスが入れ替わることに気づけるのが、計算機の価値。
← 前の章 第8章 AIはどう判断するのか 次の章 → 第10章 RAGと知識管理