[制約プログラミング落穂拾い] あなたの作ったロジックはおいくら、、、?
これまで数回にわたって制約プログラミングの最大の特徴である「宣言性」に関連して実用システムの開発に用いる際の課題について書いてきました。今回もその続きを、と思ったのですが、ちょっと寄り道をして、制約プログラミングを用いたシステム開発の見積について書きたいと思います。
ソフトウェアの見積が困難なことや、見積手法として様々な方法が提案されていることはご存知のことと思います。制約プログラミングを用いたシステム開発の場合、見積をする上で何が変わってくるのでしょうか。
まず考えなくてはならないのは、制約プログラミング技術そのものに起因するというよりは、むしろ適用対象となる分野の方が備えている特性の寄与を考慮しなくてはならないということです。例えば要員や資源のスケジューリング分野を考えてみると、問題解決手法に何を用いようと要員や資源のスケジューリングシステムの開発をする場合に考慮すべき特性というのがあるでしょう。
もう一つ、見積作業には2つの側面があることも考えるべきかと思います。
すなわち、お客様に納得していただける積算根拠を提示するという側面と、予算の範囲内で必要な作業を完了させる見通しを得るという側面です。見積の方法が同一であればこの両者は一致することもあるでしょうが、そうでない場合もあるでしょう。
一般に見積の方法の妥当性は、開発手法と強い関係があります。過去のデータの蓄積に基づいた積算が信頼できる精度を持つのは、開発手法が標準化されており、具体的な運用の詳細に至るまで、概ね同じような条件で実施されている場合です。
もしあなたが、「自分達が持っていない技術を持っている」という点をお客様に評価していただいて見積をしようとしているのであれば、お客様の持っている積算手法とあなたのそれは一致しないことを覚悟すべきでしょう。そしてここではその「技術」が制約プログラミングであるわけです。
では、スケジューリングシステム開発の場合を具体的に見ていきましょう。
スケジューリングシステム開発の特性としてまず挙げられるのは、
- 外部仕様として「見える」部分に比較して、外部からは見えない問題解決ロジックの部分の工数およびプログラムのコード量の割合が極端に大きいこと
ではないでしょうか。
積算による見積を実施する場合には、雑駁な言い方をすれば画面、帳票、データベースのテーブル数や項目数、機能や画面の部品の数を数えてそれらを積み上げていくわけですが、そうしたやり方をスケジューリングシステムに適用すると、そのような外部から観察できる仕様の項目数に現れないロジックの複雑さが落ちてしまいます。
勿論、スケジューリングシステムは計画を作成するエンジンだけでできているわけではありません。生産システム、要員管理システム全体から見れば、スケジューラは一部品に過ぎず、トータルで見ればロジックの複雑さなど、誤差の範囲内になってしまうのでは、という意見もあるかも知れません。もっともな考え方だとは思いますが、ここでの問題設定からすればこれは単に問題を見えないようにしただけで、根本的な解決にはなっていません。幾らインタフェースができたところで、スケジューラがまともに動かなければ、スケジューリングシステム導入の意味はありません。(それゆえ、高度なスケジューラなしのシステムを開発するという発想は選択肢として有効ですが、ここではその選択肢は考えないことにします。)
更に具体的な開発プロセスに添って考えていくと、別の問題も見つかります。スケジューリングシステムの開発を行なうに際して、スケジューラのロジックをどうすれば良いのか、予めわかっていることはほとんどないのではないかと思います。
(もしわかっていれば、後は普通のソフトウェアと同じように開発すれば良いわけですが。)
現実の課題を把握して、解くべき問題を定義し、大枠で決まった予算と期間の範囲内で解決方法を考え出す。そしてそれを実装して検証し、実用的になる水準にまでもっていく。こう書くと如何にも成り行き任せに見えるかも知れませんが、実際にやっていることは、あまり遠く離れてはいないと思います。否、これすらできずに動かないプログラムを作ってしまう例が、スケジューリングシステムの場合、何と多いことでしょう。
スケジューリング結果の質についての明確な基準がないことも、上記のようなやり方になる大きな理由でしょう。現実の課題に即した目的関数が予め明確に定義できているケースほとんどありませんし、現実の課題から乖離したモデルを押し付けて要求されていない問題を解けたところで、学術的な意義はあったとしても実用上の意義は限定的でしょう。
そして、上記のようなプロセスでいつも問題になるのは、
- ロジックを開発するに際しての試行錯誤の部分
- 最後の品質向上のための作業の部分をどのように評価するか
だと思います。少なくとも予め、そうしたファクターを織り込まずに見積をしたり開発計画を作るのは、無謀といっても誇張でないほど危険なことだと思います。
このようなことから、スケジューリングシステムの開発には、ウォーター・フォール型の開発プロセスは適さず、プロトタイピング手法を用いるべきだと考えられます。実際、これまでやってきた開発においても大抵の場合には、開発プロセスについては予め説明をし、納得していただいた上でプロトタイピング・本開発・チューニングといったフェーズを踏んで開発を進めてきました。特にチューニング・フェーズを設けることは、出来上がったスケジューラが出す解の品質についてお客様に納得していただくためには欠かせないと感じています。
ただし、その場合でも、特に開発初期のロジックを固める際に生じる試行錯誤を見積にどのように反映させるかの問題は残ってしまいます。最終成果物には生かされない、捨ててしまう部分は、通常のソフトウェアでは設計ミスとして扱われ、開発者が負担することになるのでしょうし、ある程度は経験の蓄積によってロスを減らすことが可能でしょうが、そうした試行錯誤をゼロにできるかどうかについては、率直に言って私は懐疑的です。場合によっては、複数案を並行して試作して評価するようなやり方だって考えられなくはない。
ところで、スケジューリングシステム以外の開発で類似したシチュエーションがないかといえば、決してそうではないように思えます。アーキテクチャとか方式の設計にあたって、そのような評価プロセスを踏むことは、特に大規模なシステムの場合、しばしばあるのではないでしょうか。ですが、その場合、評価プロセス自体の工数見積はどのようにして行なうべきでしょうか。評価用に作成するプログラムの行数を積算するのでしょうか。
そもそも最終成果物となるプログラムのコード量に行き着くような積算の場合には、制約プログラミング技術のような生産性の高い手法はかえって不利になるといった皮肉な結果にもなりかねません。色々な戦略を作ってみて、評価しては捨て、だんだんと洗練させていくというやり方は、いわば「最終成果物主義」的とでもいうべき積算手法には馴染まないのではないでしょうか。
あなたのお客様が、ごく一般的な積算の方法論しか持ち合わせていない場合に、あなたはお客様に納得していただく積算根拠を示すのに何をしなければならないでしょうか。
それに加えて、ここでは「制約プログラミング」を用いるという条件が更に加わります。喩えて言えば、お客様にとっては未知の新しい工法での工事を提案しているようなものです。
否、お客様への説明以前に、例えば新しい開発メンバーが加わったら、あなたがそれまで使っていた「勘と経験」はそれまでと同様に役立ち、リスクへの対処が充分にできるでしょうか。「誰々さんがやるからこれくらいの手間でこれくらいのレベルのもの」という属人的な発想を離れた積算の手がかりはないものでしょうか。一般のソフトウェアと同等まではいかなくても、少しでもそれに近づくような積算の方法論を考えることができないでしょうか。
もちろん、ここでそれに対する完全な答えが提示できるとは思っていませんが、手がかりのようなものは幾つかあるように感じています。
だらだらと書き続けてきましたが、ブログだからということでご勘弁いただくこととして、今回はこれくらいで打ち切ることとして、今後、この場で少しずつではありますが、それらを検討していければと思います。
その途上で、私の知りえた狭い範囲ではありますが、関連する研究や話題についても触れていければと考えています。