Lambdaカクテル

京都在住Webエンジニアの日記です

『計画の科学』を読んでPERT図について学んだ / PERT図を出せるツールを作成した

id:hitode909におすすめされてはいたものの読んでなかったので、休日を使って読むことにしたのが『計画の科学』である。技術と読書の贅沢二本立て。

成果物

成果物1

あたまがよくなりました

成果物2

PERT図(をGraphVizで出力するためのDOTドキュメント)を出力するScalaのプログラムを書きました。

github.com

CSVから直接指定はまだできません(直にコードを書く必要があります)が、工程を短縮したい場合にどこから短縮すればよいかを表示する機能があります。実際の図は記事の下らへんにあります。

計画の科学

1965年と比較的古い本でありながら、依存関係を含んでいる複雑なタスクをいかに科学的に処理していくかについて、アメリカで開発されたPERTと呼ばれる技法を紹介して説明していく本。

あまり分量も多くなく、物理本も新書サイズでKindle版もあるのですぐ読み終わる。

ただKindle版は印刷されたものをそのままPDF化したような体裁だったのでハイライティングなどが行えないのが玉に瑕。

動機

僕はちょうどあるプロジェクトに携わっていて、自分でやるタスク集合の分解や進捗管理を行わなければならない。 これまでは同僚に頼りきりだったしタスク管理は苦手という意識があったが、この本を読んでタスク管理の手法を身に付けることにした。 古典的な本だし、内容は枯れているので安心して?読むことができた。ちょっとは自分でタスク管理できるようになっただろうか?

PERTとは何か

PERTは、実行のためにコストと依存関係が必要なタスクの集合に対してタスクスケジューリングを行うための手法である。 詳しくは↑の本を読むか、Wikipediaのページを読んでくれ。

PERTは、どの工程をまず行えばよいのか、どの工程が最優先なのか、期日に間に合わせるためにはどこの工程を短縮すればよいか、等の問いに対して、科学的な枠組みを与える。

と言われてもわからんので、書中の図にもとづいて今回作成したPERT図を示す。

f:id:Windymelt:20200301220100p:plain
PERT図

この図には以下のような情報が表現されている。

  • 「やること」をアクティビティと呼ぶ。
    • 例えば「砂を現場に10トン運んでくる」「この本を読む」「APIクライアントを実装する」といった過程である。
    • アクティビティは矢印で表現する。
  • アクティビティは、イベントからイベントへの結線として表現する。
    • 例えば「アクティビティ1-2」と表現する。これはイベント1からイベント2への矢印を指す。
    • イベント自体は一種の「状態」を表現しているとも考えられる。
  • アクティビティには依存関係がある。
    • 例えば図では「アクティビティ4-7」に着手するためにアクティビティ2-4、3-4が完了していなければならない。
  • アクティビティには工数が必要である。
    • 例えば図ではアクティビティ4-7の工数は「12.0」である。
  • アクティビティにはゆとりがある。
    • 他の工程を待つためのゆとりがあるアクティビティがある。
    • 工程全体で共有されているゆとりをトータルフロートと呼ぶ。
    • その工程で使っても後続のゆとりに影響しないゆとりをフリーフロートと呼ぶ。
  • トータルフロートのないアクティビティは遅延できない。
    • 遅延すると全ての工程が遅延する。
    • これをつなげたものをクリティカルパスと呼び、全体の日程はここに依存する。
    • クリティカルパスは太線で表現している。
  • 依存関係を表現するためだけのアクティビティがある。
    • こういったアクティビティの工数は0とみなし、ダミー[アクティビティ]と呼ぶ。
    • ダミーは破線で表現する。

スーパーハカーになる例

より具体的な例をリポジトリから持ってきた。

f:id:Windymelt:20200301224111p:plain
スーパーハカーになる工程

この図はスーパーハカーになる工程を表現している。『オブジェクト指向入門』を読み、『リーダブルコード』を読み、『ハッカーと画家』を読み、MacBookを買うことでスーパーハカーになることを表現している。

ただしこれらの作業は並行実行できるものとする。全て順調にいけば8日でスーパーハカーになることができ、日程を間に合わせるためには『オブジェクト指向入門』の日程を守る必要があることが表現されているのだ。

ツール書いた

再掲。

github.com

コレクションメソッドが充実していてサッと書けるScalaで書いた。あまり困ることはなかった。入力はCSVで、以下のフォーマットに従う。ヘッダ必須。

from,to,cost,name
1,2,3,"foobar"
...

sbtで実行できるようにしているが、コードからも使えるようにしている。

$ sbt run hoge.csv
=> hoge.csv.dotが出力される
  val network = Network(
    Set(
      (1, 2, 5),
      (1, 3, 15),
      (2, 5, 10),
      (2, 4, 2),
      (3, 11, 7),
      (4, 5, 0),
      (4, 6, 4),
      (5, 6, 10),
      (5, 7, 12),
      (6, 8, 6),
      (6, 9, 2),
      (7, 8, 7),
      (8, 10, 12),
      (9, 10, 10),
      (10, 12, 2),
      (11, 12, 19)
    ),
    None // => Some(41)とかだとこちらから「この工数に収めたい」を指示できる
  )
  network.dot // => DOT言語がもらえる

CSV上ではまだできないが、コードから使う場合はNoneを渡している箇所にSome(合計工数)を与えることで日程短縮を行わせることができる。

f:id:Windymelt:20200301233336p:plain
赤は「間に合わない工程」

すると間に合わない(短縮しなければならない)工程を赤く表示できる。いちばん間に合ってない工程は太く白抜きの赤線として表示される。 間に合わない工程ではトータルフロート(図ではT:数字として表示されている箇所)がマイナスになっているので、どこをどのくらい削減すればよいかの検討をつけることができる。

結構便利なので仕事でも使えないかなと思っている。