なぜ、ソフトウェアプロジェクトは人数を増やしても上手くいかないのか


# はじめに
ソフトウェアプロジェクトには不思議な性質があります。現状のスケジュールに課題を感じて、短くするために人員を投下しても、なかなか思い通りに短くならない。それどころか悪化してしまうことがあります。場合によってはプロジェクト自体が破綻して失敗してしまうことすらあります。

今回は、このようなソフトウェアプロジェクトに潜む直感に反する性質を数理的なモデルを介して理解していく試みです。ある種の思考実験としてお楽しみください。
# 宣伝
Qiitaさんとコラボ企画でアドベントカレンダーをつくりました。
DXをめちゃくちゃ改善した話を募集しています。
https://qiita.com/advent-calendar/2021/dx-improvement

#10人の妊婦がいても1ヶ月で一人の子供は生まれない
これは誰かの技術力やプロジェクトマネジメント力に欠陥があるのではなく、「人月の神話」で有名な「ブルックスの法則」でこのことは古くから経験則として知られています。


> 遅れているソフトウェアプロジェクトへの要員追加は、プロジェクトをさらに遅らせるだけである
> *ブルックスの法則*

ブルックスの法則は、ソフトウェアエンジニアとしては経験的に理解できるものの、門外漢のステークホルダーからはなかなか理解しにくいものです。そのため、「10人の妊婦がいても1ヶ月で一人の子供は生まれない」というように喩えられたりします。

でも、例え話は例え話です。なぜソフトウェアプロジェクトがそのようになるかの説明にはあまりなっていません。

たとえば、１００人月と見積もられたプロジェクトに１０人を動員したときに最短であれば１０ヶ月前後でできるであろうと想像するのは自然な発想ではないでしょうか。

実際にはリソースの制約やクリティカルパスなどによってそれ以上伸びてしまいます。むしろ小さなチームで継続的に開発していく方が時間はかかるもののコストパフォーマンスよくシステム開発が進むことが経験的に知られています。

これらは、１つ１つさまざまな理由があってそうなっています。これは現場の感覚としては理解できるのですが、門外漢からはなかなか直感的ではありません。そのため、発注者や経営者などから見ると理由がよくわからない、説明されても腹落ちしにくいとなりプロジェクトリスクになってしまうのです。

今回は、クリティカルパスや設計と実装のバランスなどといったこれらが起こるミクロな理由の積み重ねではなく、マクロなメカニズムについて直観的な理解をするための考察していきます。

これによってこれまでブラックボックスになりがちであったソフトウェアプロジェクトに潜む”法則”について、解き明かしていきましょう。

# ソフトウェアプロジェクトの工期は工数の三乗根に比例する
多数のソフトウェアプロジェクトの統計的な性質を調べたJUASの調査によると、ソフトウェアプロジェクトの工期と工数の関係は工数の三乗根に2.7をかけた数字に比例するとされています。この2.7という定数は、毎年の調査ごとに少しずつ違ってきますが、概ね３乗根に比例するという性質は変わっていません。また、類似した調査結果も複数存在します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35671/c0e69816-dbf2-bd9e-72cb-de54fd9cb38d.png)

（引用：ソフトウェアメトリックス調査2020 システム開発・保守調査/一般社団法人日本システムユーザー協会,https://juas.or.jp/cms/media/2020/05/20swm_pr.pdf ）


これらの関係を数式にすると以下のようになります。Lは工期、Eはそのプロジェクトの工数です。
$$ L = 2.7 \sqrt[3]{E}$$

たとえば、100人月のプロジェクトであれば、標準的な工期は12.5ヶ月かかると計算できます。このような関係は大変便利で、ある規模のプロジェクトに取りかかる際に、一般的に考えられる工期が得られます。これはあくまで大雑把な推論ではあるものの経営的な意思決定に役立ちます。

経験的にはこのような標準的な工期から、さらに２割程度の納期を削減しようとすると非常に苦労します。半分の納期ともなれば、成功率はほぼ無いといってもいいでしょう。半分の納期を目指すのであればそもそものスコープを分解して整理すべきだと言えるでしょう。

さて、このように大変便利な工期と工数の関係ですが、何故三乗根になるのか、それは一体どういう意味なのかはあまり知られていないし考えられたことも少ないのではないでしょうか。この謎から解いていきましょう。

## リソースヒストグラム
ここでリソースヒストグラムという補助線を提供します。リソースヒストグラムとは、山積み表などとも呼ばれ、プロジェクトの各時期にどのような工数がかかっているかを図式化したものです。

コストのかかり方などを分析したり、どの時期に稼働が発生するかを予想するなどに用います。ソフトウェア開発では、プロジェクトの進め方にもよりますが、最初期から全員がフル稼働という訳にはいきません。段階的に関わる人が増えていき、結合試験などのタイミングでは徐々に稼働が減っていくことになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35671/dacba4a9-f94a-5170-bf2d-df3708e57e7d.png)

このリソースヒストグラムを関数だと見なすとプロジェクトの開始日と終了日にそれぞれ0になる時間軸に対して上に凸な関数になります。

これを今回、簡単化のために次のような放物線の関数 R(t)で近似してみましょう。
$$ R{\left(t \right)} = a \left(L t - t^{2}\right) $$
`Ｒ(t)= 時刻tの工数` `a = プロジェクトの動員係数` `L=プロジェクトの工期`

t = 0のときプロジェクトの開始日で、Lがプロジェクトの終了時刻です。つまり工期になります。t=0のときとt=Lのときに0になるというところで、リソースヒストグラムの要件を満たしています。

aはリソースの動員の仕方を表すプロジェクトの形式を決める変数だと思ってください。

aが大きいほど、スピーディーにたくさんの人数を動員するプロジェクトで、小さいほど少人数でゆっくりと関わる人数が増えていくプロジェクトになります。aの違いによってリソースヒストグラムは次のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35671/6a6f03e0-650a-16cc-64ce-5fcd792003be.png)

さて、このようにリソースヒストグラムの式を定義したとき、全体工数はどうなるか考えてみましょう。リソースヒストグラムをすべて足し合わせたものが、全体工数になります。つまり、R(t)を[0,L]で定積分したものが全体工数です。計算してみると全体工数(E)は次のようになります。
$$ E = \int\limits_{0}^{L} R{\left(t \right)}\, dt = \frac{L^{3} a}{6}$$

（Lの二次関数を積分したので当然ですが）Lの3乗が登場しました。これをLについて解くと、三乗根が登場します。これが、工数と工期の関係式です。
$$ L=\sqrt[3]{\frac{6E}{a}} $$ 

この関係式とJUASの例における関係式を解いてみるとaの値が求まります。それはおよそ`0.3`になります。これが日本における標準的なプロジェクトのリソースヒストグラムの形状だとみなして良いでしょう。

実際のプロジェクトにおけるリソースヒストグラムと比較しても、誤差はもちろんありますが、一般だといえるのではないでしょうか。

このことによってプロジェクトのピーク時の人員数に対してもセオリーを与えることができます。t = L/2のときに放物線のピークを迎えますから、ピーク時人員数はこのようになります。
$$ R_{peak} = \frac{L^{2} a}{4}$$
この数式を用いて、全体の工数規模から適切な工期、工数、人員計画などを概算することで、非現実的なプロジェクトを見極め、現実的なプロジェクトの計画を導くことがしやすくなるでしょう。

## コミュニケーションコストを考慮に入れる
ソフトウェアプロジェクトの工数と工期の関係がわかりました。しかし、プロジェクトの工期を短くしようとしての人員追加はなぜうまくいかないことが多いのでしょうか。そのことについて考察するために、第二の補助線を導入してみましょう。

それはコミュニケーションコストです。ソフトウェアプロジェクトでは、綿密なコミュニケーションを行う必要があります。人数が増えるごとに対話やドキュメント、その他の手段によって認識を統一していく必要がでてきます。これを数式化してみましょう。

以下の図のように人数が増えるごとに、認識をそろえるべきコミュニケーションのパターンは増えていきます。これは、$n(n-1)/2$のペースで増えていきます。つまり、$O(n^2)$でコミュニケーションコストは増大します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35671/842ac546-2b64-803f-ab42-660d93a96509.png)


このことを表現するために、プロジェクトの工数からコミュニケーションに費やされた工数を取り除いた有効工数(S)を考えてみます。コミュニケーションコストは、ある時刻の人数の二乗に比例すると仮定すると以下のように定式化できます。
$$
 S{\left(t \right)} =  R{\left(t \right)} - c R^{2}{\left(t \right)} 
$$
`c = コミュニケーションコスト`
`S(t)= 時刻tの有効工数`

これを先ほどと同じように[0,L]の区間で定積分します。すると、有効工数(S)は次のようになります。
$$ S=\int\limits_{0}^{L} S{\left(t \right)}\, dt = - \frac{L^{3} a \left(L^{2} a c - 5\right)}{30} $$
`S= トータルの有効工数`

また、こちらをグラフとして表すと次のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35671/effe2321-1320-3112-8944-c72148de65e8.png)


急速な拡大が必要なプロジェクト(a=0.5)では、有効工数40程度のところで、飽和してしまい拡大すればするほどコミュニケーションコストのほうが効いてしまって生産性が悪化しています。なだらかに人員を増加させるプロジェクト(a=0.1)では長期にわたっても有効工数が増え続けています。

*補足：今回、このコミュニケーションコストcは0.03という値を用います。10名のプロジェクトであればおよそ3割の時間がコミュニケーションに費やしているイメージです。*
 
**人数規模を拡大するにつれて、コミュニケーションコストの方が人数を追加するメリットよりも大きくなってしまうため、プロジェクトの拡大には上限があることがわかります。**

## 納期はどれだけ短縮できるのか
では、ここで人員の追加に伴う納期の短縮可能性について検討してみましょう。

有効工数Sが変わらない状態でプロジェクトの動員の仕方(a)を変形させていき、プロジェクトの期間が80%,60%になるようにシミュレーションしたものが以下になります。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35671/6f21b21b-ba36-03b9-1f93-b195d3903c88.png)
グラフの塗りつぶしてある部分が、コミュニケーションコストを除いた有効工数です。３つのプロジェクトの有効工数は同一です。同じ規模のソフトウェアを実現することができるプロジェクトを短縮していくほど、有効工数のグラフは実工数のグラフに対して上から押しつぶしたような形状になっていきます。つまり納期を短くすればするほど、１人月あたりのコストパフォーマンスは悪化していくということになります。

コストパフォーマンスとプロジェクトの最大人員規模をプロットしたグラフは次のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35671/2c4bc11e-5cad-065f-0789-169bff2ef36b.png)

大型のプロジェクトのほど、コストパフォーマンスは低下します。また、１パスあたりのコミュニケーションコストを下げれば下げるほど、プロジェクトを拡大できることもわかります。**これがマイクロサービスなど、ソフトウェア自体の疎結合性が重要視される理由でもあります。大型プロジェクトをコミュニケーションコストの小さい少人数のプロジェクトに分割できるほどコストパフォーマンスが良くなるからです。**

## 納期がそれ以上短縮できなくなるポイントが存在する
このようなモデルにおいては、納期がそれ以上短縮できなくなるポイントが存在することがわかります。
人数追加によって生産性向上が望めなくなるためです。同一の有効工数で動員の仕方(a)を変えていった場合に短縮可能割合は次のように算出できます。

$$短縮可能割合 = \frac{4 L^{2} a c \left(L^{2} a c - 5\right)}{25} + 1$$

たとえば、元がa=0.3 で工期が12ヶ月のプロジェクトであれば、人員を追加方法を変えても最大で23%までしか納期を短縮することができないというように計算できます。

コミュニケーションコストによって意味のある人員追加には上限があるため、大人数・大規模のプロジェクトほど削減余地が少なくなるのです。（もちろん、スコープそのものを変えるなどの余地は存在します。）

また、納期短縮のためのコストも安いわけではありません。人員追加によってコストパフォーマンスが悪化することを予期しながらも拡大する必要があるため、時間の値段は徐々に高くなってしまうのです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35671/a6deb75c-f2c5-9135-9086-5f4bda8a4419.png)
上記の図のように10ヶ月(L=10)のプロジェクトを6ヶ月(L=6)で実施するために計算上およそ1.5倍の全体工数が必要だと計算できます。また、この計算はあくまで実稼働ですので、契約期間や人材の単価、リソース調達などの取引コストによってまるまるコスト1.5倍ですむとは限りません。同じ計算でもヘッドカウント換算では、2.5倍近い人員をピーク時には動員する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35671/aebbba5c-b3b8-9454-d8c3-1e52b4d7437b.png)

このようにソフトウェアプロジェクトでは、コミュニケーションコストが問題になっていくタイミングで、これ以上プロジェクトを拡大しても生産性が上がらないポイントが生まれてしまいます。これが、**プロジェクトにおける納期短縮の値段が極めて高くつくことの理論的な説明です。**

# 組織でエンジニアリングする理由
これまで見てきたように、ソフトウェアプロジェクトではスケールメリットが必要になれば、如何にコミュニケーションコストの低い組織とプロダクトを実現するかが重要になります。これはマイクロサービスアーキテクチャやDevOps、そして組織マネジメントがなぜ必要なのかを示唆してくれます。

また、効率的なコストパフォーマンスを得たいのであれば、大人数の大型プロジェクトではなく、如何に小さなプロジェクトに分解しながら進めていくことが重要であることが見て取れました。そのため、ソフトウェアプロダクトを開発する組織は、内製化によって安定的な人員調達を実現した上で、アジャイルプロセスなどのリソースを固定した状態でパフォーマンスを出すための開発手法が近年では重視されるようになったのだと考えられます。


# あわせて読みたい

+ [「もったいない」マインドが逆に効率を悪くする。フロー効率とリソース効率から考えるチームで仕事をする理由](https://qiita.com/hirokidaichi/items/f59e611772c02f2e74ee)

+ [「いつ終わる？」から「何パーセントで終わる？」でコミュニケーションするアジャイルプロジェクトマネジメント](https://qiita.com/hirokidaichi/items/51bfd7fa9e7a4a096d8b)