テックツリーとDAG — 依存関係の正体
ゲームの「クラフトツリー」はCS(=コンピュータサイエンス)の用語で正確にはDAG(有向非循環グラフ)と呼ばれる構造である。npm install や make、CI(=継続的インテグレーション。コードの変更を自動でビルド・テストする仕組み)のジョブ順序付けも、すべて同じ仕組みで動いている。
テックツリーとは何か
テックツリーとは「Bを作るにはAが先に必要」という関係を矢印でつないだ図である。例として、Dr.STONE の硫黄から硫酸を経てサルファ剤に至る流れ、Minecraft のレシピ、Civilization のテックツリーが挙げられる。いずれも素材から中間生成物を経て最終成果物に至る流れを、有向の矢印でつなぐという共通パターンを持つ。
DAGを3語で理解する
DAG(Directed Acyclic Graph、有向非循環グラフ)は3つの性質で説明できる。グラフ(Graph)とはノード(点)をエッジ(線)でつないだ構造である。有向(Directed)とは矢印に向きがあることを指し、「AはBの材料である」という関係を表す。非循環(Acyclic)とはループが存在しないことを指し、「CはDが必要、DはCが必要」というような循環依存があると、実行順序を決定できなくなる。
トポロジカルソート(位相的整列)
トポロジカルソートとは、DAGのノードを依存関係を満たす順に一列に並べる操作である。代表的なアルゴリズムには、入次数(=そのノードに向かう矢印の数)が0のノードから順にキューへ入れていくカーンのアルゴリズムと、DFS(深さ優先探索)の結果を逆順にたどる方法がある。この操作は make、npm install、CIパイプライン、タスクスケジューラの内部で実際に使われている。
描画ライブラリの選び方
DAGを図として描くライブラリにはいくつかの選択肢がある。Mermaid(マーメイド)はテキスト記法でドキュメントやREADMEに向いており、flowchart LRという書き方でDAGを表現できる。React Flow はWebアプリへの組み込みに向いており、ノードをドラッグできるインタラクティブな表示ができる。D3 / d3-dag は完全にカスタムできる分、自由度が最大である一方、実装コストも最大になる。
依存関係のグラフは必ずDAGになる。トポロジカルソートを使えば、ビルドやインストールの正しい実行順序が自動で決まる。