動的計画法(どうてきけいかくほう、Dynamic Programming、略してDP)は、複雑な問題を解決するためのアルゴリズムの一種です。この方法は、問題をより小さなサブプロブレム(部分問題)に分割し、それらを解決して最終的な解を導き出すというアプローチを取ります。動的計画法の特徴は、各サブプロブレムの解を記憶して再利用する「メモ化」というテクニックを使用することです。
動的計画法の基本的な考え方
動的計画法の基本的な考え方は、「大きな問題を小さな問題に分割し、小さな問題を解いていくことで全体の解を得る」というものです。これは「分割統治法」と似ていますが、動的計画法では、分割した問題が重複する場合にその解をメモしておき、同じ問題を解く手間を省く点が異なります。
動的計画法の手順
- 問題の定式化:
問題を適切に数学的なモデルに落とし込みます。これには、問題の各要素をどのように表現するかを考える必要があります。 - サブプロブレムへの分割:
大きな問題を小さなサブプロブレムに分割します。このとき、サブプロブレムは互いに重複する可能性があります。 - 再帰的関係の特定:
サブプロブレム間の関係を見つけ、再帰的な式(漸化式)を立てます。この式は、より小さなサブプロブレムの解を用いて、大きなサブプロブレムの解を求めるためのものです。 - メモ化:
一度計算したサブプロブレムの解は、メモリ(通常は配列やハッシュテーブル)に記録します。同じサブプロブレムが再び出現したときは、メモリから解を取り出して計算を省略します。 - 解の構築:
最小のサブプロブレムから始めて、メモした解を利用しながら、最終的な解を段階的に構築していきます。
動的計画法の適用例
- ナップサック問題:
限られた容量のナップサックに、最大の価値を持つようにアイテムを詰める問題。 - フィボナッチ数列:
前の2つの数を足してできる数列で、再帰的に定義されるが、動的計画法を使うことで効率的に計算できる。 - 最長共通部分列問題(LCS問題):
2つの文字列が与えられたとき、両方に現れる最長の共通の部分列を見つける問題。 - 最短経路問題:
グラフ上で、あるノードから別のノードへの最短経路を見つける問題。ダイクストラ法などが知られていますが、動的計画法を用いたベルマン・フォード法もあります。
動的計画法の利点と欠点
- 利点:
– 計算効率が良い:メモ化により、同じ計算を繰り返さずに済むため、計算時間を大幅に削減できます。
– 理論的には、任意の問題に対して最適解を得ることができます。 - 欠点:
– メモリ使用量が多い:メモ化には多くのメモリが必要な場合があります。
– 問題によっては、サブプロブレムへの分割や再帰的関係の特定が難しいことがあります。
動的計画法は、計算機科学だけでなく、経済学や工学など、多くの分野で広く使われている重要なアルゴリズムです。問題を解決する際には、この手法が適しているかどうかを検討し、最適なアルゴリズムを選択することが重要です。