アルゴリズムの簡単な説明 - 文字列と文字列のマッチング、ソート、深さ/幅優先検索、動的プログラミング、分割統治、貪欲、バックトラッキング、分岐限定

目次

アルゴリズムの簡単な説明

基本的な

代表的なアルゴリズム一覧

文字列間のマッチング

選別

深さ/幅優先検索

動的プログラミング

分割統治

よく深い

バックトレース

枝と束縛


アルゴリズムの簡単な説明

基本的な

へーん... アルゴリズムに関しては、私たちは CS の学生ではありません。アルゴリズムとは、モデル化された問題を解決するための特定の方法と手法であるとだけ言っておきます。アルゴリズムは、プログラミングのための成熟した/形成された完了問題を学習するものです。計算ルーチンとアイデア。

代表的なアルゴリズム一覧

文字列間のマッチング

基本的な

文字列は、0 個以上の文字の限定されたシーケンスであり、文字列とも呼ばれます。文字列内の連続する文字で構成される部分シーケンス (drool) は、文字列の部分文字列です。文字列のエンコード方式はASCIIエンコードやUnicodeエンコードなどの文字エンコードです。

文字列内の要素はすべて文字です。文字列操作は、個々の要素ではなく、主に文字列操作に関連しています。そのほとんどは、部分文字列の位置の検索、指定された位置の部分文字列の取得、部分文字列の置換などの操作です。以下に続きます:

アセット/文字列操作.jpg

もちろん、string.h などの標準ライブラリには基本的な文字列操作 API が用意されていますが、C 標準ライブラリの詳しい使い方については、記事「 C & MCU 記述仕様など」の「7 C 標準ライブラリの使い方」を参照してください。 。

文字列マッチング アルゴリズム (文字列パターン マッチングとも呼ばれます)

文字列マッチングの例: パターン文字列 P = "ABCDABD" と同じサブ文字列の位置をメイン文字列 S = "BBC ABCCDAB ABCDADCDABDE" から検索します。

文字列パターン マッチング アルゴリズム - BF アルゴリズム (またはブルート フォース アルゴリズム)

i = 0 の位置から始まるメイン文字列 S と、j = 0 の位置から始まるパターン文字列 P は 1 文字ずつ同じですか? 同一であれば、i と j を 1 ずつインクリメントして、一致するかどうかを判定します。一致していれば、i はここに戻り、同時に j はマッチング開始位置の最初の位置に戻り、順番にマッチングを続けます。画像で次のように説明されています。

引用元: 21 文字列パターン マッチング アルゴリズム (BF アルゴリズム) - Zhihu (zhihu.com)

アセット/BF アルゴリズム (またはブルート フォース アルゴリズム).jpg

文字列の高速パターン マッチング アルゴリズム - KMP アルゴリズム

主なアイデアは、BF アルゴリズムと比較して、マッチングを高速化するために、いくつかのルールを見つけることです。マッチングが失敗した場合、j は毎回 P の先頭に戻る必要はありませんが、(注意、そうでない場合は)理解できない場合は、以下のチュートリアル記事を読むことをお勧めします。理解した後の概要は次のとおりです) パターン文字列内の各文字列の各プレフィックスとサフィックスのサブストリングの最大共通要素長は、次の配列を構築するために使用されます。 j によって毎回移動される桁数は、次に従って調整されます。

選別

深さ/幅優先検索

グラフの走査は通常、深さ優先検索 (DFS) と幅優先検索 (BFS) を使用して実行されます。「ツリーを特別な種類のグラフと考えると、DFS は事前順序トラバーサルです。」

動的プログラミング

一部の人々は、「動的プログラミング」の考え方 (最適化目標と状態遷移方程式 (または再帰的関係) を記述する) を使用して問題を理解し、モデル化することで、考えられるすべての解決策をたどることなく問題に対する最適な解決策を見つけることができると理解しています。 (時間を節約するために分岐をカットする、または最適解ではない計算を削除する、または重複する部分問題を削除する); 一般的な実装方法は、繰り返しの計算を減らすためにキャッシュを使用してデータを保存することです (網羅的な計算プロセスをツリーに拡張します) 、繰り返し計算されている部分を見つけ出し、以前に繰り返し計算された結果のコピーをキャッシュを使用して保持し、繰り返し計算を減らす)など、多くのテクニックや方法があります。

分割統治

引用元: Five Commonly Used Algorithms - Detailed Preparation and Classic Examples of the Divide and Conquer Algorithm_ Stop Thinking of Better Ways Blog - CSDN Blog_ Classic Examples of the Divide and Conquer Algorithm

分割統治法の設計思想は、直接解決するのが難しい大きな問題を多数の小さな同一の問題に分割し、それらを個別に解決して分割統治できるようにすることです。

分割統治戦略は次のとおりです: サイズ n の問題の場合、問題が簡単に解決できる場合 (たとえば、サイズ n が小さい場合)、問題を直接解決します。そうでない場合は、問題をより小さいスケールの k 個の部分に分解します。これらのサブ問題は独立して元の問題と同じ形式で再帰的に解決され、各サブ問題の解が結合されて元の問題の解が得られます。 。このアルゴリズム設計戦略は分割統治と呼ばれます。

元の問題が k 個のサブ問題 (1<k≤n) に分割でき、これらのサブ問題をすべて解決でき、これらのサブ問題の解を使用して元の問題の解を見つけることができる場合、次のようになります。分割統治法も可能です。分割統治法によって生成される部分問題は、多くの場合、元の問題のより小さなモデルであるため、再帰的手法の使用が容易になります。この場合、分割統治法を繰り返し適用すると、部分問題を元の問題タイプと一致させることができますが、その規模は継続的に縮小され、最終的に部分問題は直接問題を解決するのが容易な点まで縮小されます。その解決策を見つけてください。これは当然、再帰的なプロセスにつながります。分割統治と再帰は双子の兄弟のようなもので、アルゴリズム設計で同時に使用されることが多く、多くの効率的なアルゴリズムが生成されます。

分割統治法を使用して解決できるいくつかの古典的な問題:

  • (1) 二分探索
  • (2) 大整数の乗算
  • (3) ストラッセン行列の乗算
  • (4)チェスボードカバレッジ
  • (5) マージソート
  • (6) クイックソート
  • (7) リニア時間選択
  • (8) 最近接点ペア問題
  • (9) 総当たりのスケジュール
  • (10) ハノイの塔

分割統治アルゴリズムの核心は、部分問題のサイズが近いかどうかにあり、それらが近い場合、アルゴリズムはより効率的になります。

分割統治アルゴリズムと動的プログラミングはどちらも部分問題を解決し、その解をマージしますが、分割統治アルゴリズムは元の問題よりもはるかに小さい部分問題を探します (それでも非常に高速であるため)。ガバナンスアルゴリズムの効率は必ずしも良いとは限らず、動的計画法の効率は部分問題の数に依存します。サブ問題の総数よりも多くのサブ問題が存在する場合 (つまり、反復されるサブ問題が多数ある場合)、アルゴリズムは非常に効率的になります。

よく深い

引用元: Five Commonly Used Algorithms - Detailed Preparation and Classic Examples of Greedy Algorithm_ Stop Thinking of Better Ways Blog - CSDN Blog_ Greedy Algorithm

貪欲アルゴリズム (貪欲アルゴリズムとも呼ばれる) とは、問題を解決する際に、常に現時点で最善の選択を行うことを意味します。つまり、彼が作ったのは全体最適解を考慮せず、ある意味局所最適解に過ぎなかったのである。貪欲アルゴリズムは、すべての問題に対して全体最適解を取得することはできませんが、広範囲の問題に対して全体最適解、または全体最適解の近似解を生成することができます。

基本的な考え方

  1. 問題を説明する数学モデルを構築します。

  2. 解決すべき問題をいくつかの下位問題に分割します。

  3. 各部分問題を解決し、部分問題の局所最適解を取得します。

  4. 部分問題の局所最適解は、元の問題の解に合成されます。

アルゴリズムの実装プロセス

  1. 問題に対する最初の解決策から始めます。

  2. 一方、与えられた全体的な目標に向かって一歩前進することができます。

  3. 実現可能な解決策の解決要素を見つけます。

  4. 問題に対する実現可能な解決策は、すべての解決策の要素で構成されます。

このアルゴリズムには問題があります

  1. 得られた最終ソリューションが最良であるという保証はありません。
  2. 最大または最小の解問題を見つけるために使用することはできません。
  3. 特定の制約を満たす実行可能なソリューションの範囲のみを見つけることができます。

引用元:動的プログラミングとは何ですか? 動的計画法とはどういう意味ですか? - Zhihu (zhihu.com) は、 貪欲なアルゴリズムの欠点について次のように説明しています。 

まず、私たちが人生でよく遭遇するものを見てみましょう。あなたは裕福で、1、5、10、20、50、100 元の紙幣を十分に持っているとします。ここでの目標は、できるだけ少ない紙幣を使用して、一定の金額を収集することです。

人生経験に基づいて、私たちは明らかに次の戦略を採用できます。100 を使用できる場合は 100 を使用してみ、そうでない場合は 50 を使用してみてください...など。この戦略では、666=6×100+1×50+1×10+1×5+1×1、合計10枚の紙幣が使用されました。

この戦略は「貪欲」と呼ばれます。私たちが直面している状況が「埋め合わせなければならないw」であると仮定すると、貪欲戦略は「まだ埋め合わせなければならない部分」をできるだけ早く小さくしますw を 100 減らすことができる場合は、100 減らすようにしてください。このようにして、次に直面する状況は、w-100 を補うことです。長期的な人生経験は、貪欲な戦略が正しいことを示しています。

ただし、紙幣セットの額面を変更する場合、貪欲な戦略は機能しない可能性があります。見知らぬ国の紙幣の種類が 1、5、11 である場合、15 を思いついたときに、私たちの貪欲な戦略は失敗します。

15=1×11+4×1 (貪欲戦略では紙幣を 5 枚使用します)

15=3×5 (正しい戦略、紙幣は 3 枚のみ使用)

なぜそうなるのでしょうか? 貪欲な戦略の何が問題なのでしょうか?

近視眼的。

先ほども言いましたが、貪欲戦略のプログラムは「次に直面するwを小さくしようとする」です。このように、欲張り戦略では、w=15 の場合に 11 を使用して w を 4 に減らすことが優先されますが、この問題では 4 を取得するコストが非常に高いため、4×1 を使用する必要があります。5 を使用すると、w は 10 になります。4 ほど小さくはありませんが、10 を構成するには 5 元が 2 つ必要です。

ここで、貪欲とは目先の状況だけを考慮した戦略であることがわかります

バックトレース

引用元: leetcode バックトラッキング アルゴリズム (バックトラッキング) _wonner_ のブログ - CSDN blog_leetcode バックトラッキング の概要

バックトラッキングアルゴリズムはヒューリスティック法とも呼ばれ、問題の解決策を体系的に探索する手法です。バックトラッキング アルゴリズムの基本的な考え方は、1 つのパスから前進し、可能であれば前進し、不可能であれば後戻りし、別のパスを再試行するというものです。

枝と束縛

引用元: Five Commonly Used Algorithms - Detailed Preparation and Classic Examples of Branch and Bound Algorithm_ Stop Thinking of Better Ways Blog - CSDN Blog_Detailed Preparation of Branch and Bound Algorithm Examples

比較バックトラッキング

  • バックトラッキング法の解の目標は、制約条件を満たす解空間内のすべての解を見つけることですが、分岐限定法の解の目標は、おそらく、制約条件を満たす解を見つけること、または解を見つけることです。制約条件を満たす解のうち、ある目的関数の値が最大または最小の解に到達する、これが、ある意味での最適解である。
  • もう 1 つの大きな違いは、バックトラッキング法は深さ優先で解空間を検索するのに対し、分枝限定法は幅優先または最小コスト優先で解空間を検索することです。

おすすめ

転載: blog.csdn.net/Staokgo/article/details/132922554