動的プログラミングアルゴリズムのルーチンをマスターするにはどうすればいいですか?

動的プログラミングアルゴリズムのルーチンをマスターするにはどうすればいいですか?

[[358211]]

DP と呼ばれる動的プログラミングは、非常に洗練された複雑なアルゴリズムという印象を与えます。多くの学生はこの名前を見ると落胆し、面接で動的プログラミングについて質問されることを非常に恐れます。実際、それは明確なアルゴリズムではなく、問題を最適な方法で解決するためのアイデアまたは方法です。これは、アメリカの数学者ベルマンが多段階の意思決定プロセスの最適化問題を研究していたときに提案されました。ただし、線形計画法、非線形計画法など、時間に依存しない静的な計画法もいくつかあります。オペレーションズリサーチにおいて、動的計画法は非常に重要な内容であり、さまざまな業界で広く使用されています。動的プログラミングをどのように理解すればよいでしょうか?

問題の最適解がそのサブ問題の最適解から導き出せる場合、まずそのサブ問題の最適解を見つけ、次にサブ問題の解に基づいて元の問題の最適解を得ることができます。サブ問題が繰り返し出現する場合、繰り返し計算を減らして時間計算量を減らすために、最終的なサブ問題から元の問題まで下から上に向かって段階的に解決し、サブ問題を先に保管することができます。大きなサブ問題を解決するときは、テーブルからサブ問題の解を直接照会することができます。これが動的プログラミングの基本的な考え方です。

簡単に言えば、大きな問題がいくつかのサブ問題に簡略化されてテーブルに保存され、データ テーブル内のサブ問題の解決策に基づいて大きな問題の解決策が見つかります。このアルゴリズムは見覚えがありますか? 実際、動的プログラミングは分割統治アルゴリズムに似ており、分割統治アルゴリズムと比較されることがよくあります。これらすべてをいくつかのサブ問題に分解し、サブ問題を解決する必要があります。違いは、分割統治アルゴリズムが各サブ問題を上から下へ解決し、サブ問題の解決策をマージして元の問題の解決策を取得するのに対し、動的プログラミングはサブ問題を分解し、サブ問題の解決策を下から上へ解決し、結果を保存することです。大きなサブ問題を解決するときは、サブ問題の解決策を直接照会できるため、アルゴリズムの効率が大幅に向上します。

理論的な説明は堅苦しくてつまらないので、例を見てみましょう。

フィボナッチ数列

フィボナッチ数列

フィボナッチ数列は非常に不思議な数列です。イタリアの数学者レオナルド・フィボナッチによって提唱されました。その特徴は、数列内の特定の項目の値が、前の 2 つの項目の合計であることです。黄金比数列とも呼ばれます。

[[358213]]

レオナルド・フィボナッチ

フィボナッチ数列は次の一般式で表すことができます。

フィボナッチ数列の式から、数列のn番目(n>2)の項の値f(n)はf(n)+f(n-1)に等しいことがわかります。f(n)の値を取得するには、まずf(n-1)とf(n-2)の値を見つける必要があります。分析のため、n=6と仮定します。下の図に従って、段階的に小さな値に分解できます。

フィボナッチ

上の図を見た後、誰もがプログラムの実装のアイデアを頭の中に持っていると思います。再帰メソッドを直接使用して、n 個のアイテムの値を検索できます。以下に示すように、プログラムは非常に簡単です。

  1. int fib( int n)
  2. {
  3. n==1 || n==2の場合、 1を返します
  4. fib(n-1) + fib(n-2) を返します
  5. }

しかし、このアルゴリズムは O(2^n) という指数関数的な時間計算量を持ち、n が増加すると計算量も指数関数的に増加します。n が一定のサイズに達すると、非常に長い時間がかかります。明らかに、これは最適なアルゴリズムではありません。しかし、上図の分解項目をよく見ると、図には繰り返されるサブ項目が多数あることがわかります。これが、上記の再帰アルゴリズムの複雑性が比較的高い理由です。では、最適化はまだ可能でしょうか? 答えは「はい」です。

上記のアルゴリズムは、動的プログラミングの考え方によって最適化できます。 多数の繰り返し計算を回避するために、最下位レベルのサブ問題から始めて、これらのサブ問題の値をテーブルに保存することができます。 この値に再び遭遇したときに、再計算する必要はありません。

次のプログラムに示すように、最小のサブ問題 n=1,2 から計算を開始し、計算されたサブ問題の値を格納するベクトル コンテナーを定義します。次に大きな問題を計算するときに、コンテナー内の値を直接呼び出すことができます。

  1. int fib( int n)
  2. {
  3. ベクトル< int > dp(n, 0);
  4.  
  5. dp[0] = dp[1] = 1;
  6. ( int i = 2; i < n; i++)の場合
  7. {
  8. dp[i] = dp[i - 1] + dp[i - 2];
  9. }
  10.  
  11. dp[n-1]を返します
  12. }

明らかに、上記のアルゴリズムはアルゴリズムの時間計算量を大幅に削減し、時間計算量は O(n) になりました。ただし、時間の複雑さは軽減されますが、スペースを犠牲にして実現されます。実は、さらに最適化することができます。式から、特定の項目の値を見つけるには、まず最初の 2 つのサブ問題の値を見つける必要があることがわかります。サブ問題を下から上に解くと、連続する 2 つのサブ問題の値を直接保存できます。

  1. int fib( int n)
  2. {
  3. 整数dp[2]={1,1};
  4.  
  5. ( int i = 2; i < n; i++)の場合
  6. {
  7. tmp = dp[0];
  8. dp[0] = dp[1];
  9. dp[1] = dp[1] + tmp;
  10. }
  11.  
  12. dp[1]を返す
  13. }

最長増加部分列

厳密に言えば、上記のフィボナッチ数列は完全に動的計画法の問題ではありません。動的計画法の定義によれば、動的計画法の問題は一般に次の 3 つの特性を満たします。

  • 最適化の原理: 元の問題の最適解によって分解されたサブ問題の解も最適である場合、その問題は最適なサブ構造を持ち、サブ問題の最適解から元の問題の最適解を導き出すことができるといえます。
  • 後遺症なし: ある段階の状態が決定されると、その状態が将来の決定に与える影響は現在の状態のみに関連します。
  • 重複するサブ問題があります: サブ問題は、意思決定の次の段階で繰り返し使用される可能性があります。

動的計画法の問題のこれら 3 つの特性に基づいて、別の例である、非常に古典的な動的計画法の問題である最長増加部分列問題 (LIS と略記) を見てみましょう。

長さ n のシーケンス a0、a1、...、a(n-1) があります。このシーケンス内の最長の増加部分シーケンスの長さを求めます。いわゆる昇順部分列とは、任意のi

まず、次の表に示すように、元の問題を順にサブ問題に分解します。

後続

コードは次のように実装できます。dp配列を使用して、nums[i]で終わる最長サブシーケンスの長さを保存し、maxに最長サブシーケンスの長さを格納します。

  1. int maxLIS(std::vector< int >& 数値)
  2. {
  3. 整数 最大値= 1;
  4. std::vector< int > dp(nums.size ( ), 1);
  5.  
  6. ( int i = 1; i< nums.size ( ) ); i++)の場合
  7. {
  8. ( int j=0; j<i; j++)の場合
  9. {
  10. 数値[i]>数値[j]の場合
  11. {
  12. dp[i] = dp[j] + 1;
  13. }
  14. std:: max、 dp[i] とstd ::max のです。
  15. }
  16. }
  17.  
  18. 戻る 最大;
  19. }

上記の 2 つの例から十分に理解できましたか? ナップサック問題、コインの両替、最短経路など、動的プログラミングを使用して解決できる一般的な問題はたくさんあります。動的プログラミングは固定されたアルゴリズムではなく、対応する問題も多様ですが、基本的な考え方を習得すれば、対応する問題を簡単に解決できます。今すぐ試してみましょう。

この記事はWeChat公式アカウント「Will's Canteen」から転載したものです。下のQRコードからフォローできます。この記事を転載する場合は、Will’s Dashitang パブリックアカウントにご連絡ください。

<<:  7つの機械学習アルゴリズムの7つの重要なポイント

>>:  サッカーボールとハゲ頭の区別がつかないAIがプレミアリーグのファンにまたもや嫌われる

ブログ    
ブログ    
ブログ    
ブログ    
ブログ    

推薦する

...

...

脳コンピューターインターフェースの新発見!眠りに落ちた後、脳は起きている時の経験を再生する

この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...

...

AIビッグモデルデータ注釈「出稼ぎ労働者」の月収は5000元以下、単価は50セントから4セントに下落

10月9日のニュースによると、AIビッグモデルは近年、人工知能の分野で話題になっており、リアルなテ...

顔認識禁止が迫る:テクノロジー企業はどこへ向かうべきか?

この記事は公開アカウント「Reading Core Technique」(ID: AI_Discov...

AIテスト:自動運転車のテストに関するケーススタディ

編集者注:最近、清華大学自動化学部システム工学研究所の李立准教授を筆頭著者として、林一倫、鄭南寧、王...

TensorFlow Lattice: 柔軟で制御可能、説明可能な機械学習

この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...

どこにでも「ゴミ」がある: 人工知能には高品質のデータが不足しています!

この記事は、公開アカウント「Reading the Core」(ID: AI_Discovery)か...

自動運転トラックの普及が加速しているが、実用化にはどれくらいの時間がかかるのだろうか。

iResearch Instituteが発表したレポートによると、2021年の中国の幹線物流大型ト...

...

自然言語処理にディープラーニングを使用するにはどうすればよいでしょうか?練習チェックリストはこちら

[[198324]]導入この記事は、自然言語処理 (NLP) にニューラル ネットワークを使用する方...

合成データは AI をより良くすることができるでしょうか?

人工知能 (AI) は指数関数的な成長によりさらに進歩していますが、この最新技術には依然として限界が...

自動運転テストが重要なのはなぜですか?米国と比較して、中国には4つの大きな利点がある

交通・自動車業界の変革の主流として、自動運転技術の開発は初期の成熟段階に入り、多くの企業が大規模なテ...

IBM TRIRIGA統合ワークプレイス管理システムに新機能が追加

IBMは、人工知能とほぼリアルタイムの洞察を活用して組織が安全で効率的かつ生産性の高い職場を構築でき...