5 つのアルゴリズムは次のとおりです。
1. 検索アルゴリズム (深さ優先検索や幅優先検索など): 検索アルゴリズムは、データ セット内のターゲット要素または特定の条件を満たす要素を見つけるために使用されます。これらは、グラフの走査、経路検索、迷路問題の解決などに広く使用されています。たとえば、深さ優先検索を使用して迷路の問題を解決できます。次に、深さ優先検索アルゴリズムを使用して迷路内のパスを見つける例を示します。
void DepthFirstSearch(int[][] maze, int startX, int startY, List<(int, int)> path)
{
// 检查是否到达终点
if (startX == maze.Length - 1 && startY == maze[0].Length - 1)
{
path.Add((startX, startY));
// 输出路径
foreach (var point in path)
{
Console.WriteLine($"({point.Item1}, {point.Item2})");
}
return;
}
// 检查当前位置是否有效
if (startX < 0 || startX >= maze.Length || startY < 0 || startY >= maze[0].Length || maze[startX][startY] == 1)
{
return;
}
// 标记当前位置已访问
maze[startX][startY] = 1;
path.Add((startX, startY));
// 递归探索四个方向
DepthFirstSearch(maze, startX + 1, startY, path); // 向下
DepthFirstSearch(maze, startX, startY + 1, path); // 向右
DepthFirstSearch(maze, startX - 1, startY, path); // 向上
DepthFirstSearch(maze, startX, startY - 1, path); // 向左
// 回溯,恢复当前位置为未访问状态
maze[startX][startY] = 0;
path.RemoveAt(path.Count - 1);
}
通常、検索アルゴリズムには深さ優先検索と幅優先検索の 2 種類があり、それぞれの具体的な概要を次に示します。
-
深さ優先検索 (DFS): 最初のノードから開始して、続行できなくなるまでパスに沿って終点まで進み、その後、前のノードに戻り、他のブランチの横断を続けます。DFS はすべての可能なパスを探索するために使用され、スペースの複雑さは小さいです。
-
幅優先検索 (BFS): 最初のノードから開始して、最初にそのノードに直接隣接するすべてのノードを訪問し、次にこれらのノードに隣接するノードを訪問し、ターゲット ノードが見つかるかグラフ全体が見つかるまでレイヤーごとに拡張します。横断しました。BFS は最短パスを見つけるために使用され、時間計算量は低くなります。
さらに、A* アルゴリズム、双方向検索、反復深化検索などの他の検索アルゴリズムもあります。それらはすべて独自の特性と適用可能なシナリオを持っています。
2. 並べ替えアルゴリズム (クイックソートやマージソートなど): 並べ替えアルゴリズムは、データ セット内の要素を特定の順序で再配置するために使用されます。データ分析、データベース操作、検索、並べ替えなどの分野で広く使用されています。クイック ソートは効率的なソート アルゴリズムです。以下は、クイック ソート アルゴリズムを使用して整数の配列をソートする例です。
void QuickSort(int[] array, int left, int right)
{
if (left < right)
{
int pivotIndex = Partition(array, left, right);
QuickSort(array, left, pivotIndex - 1);
QuickSort(array, pivotIndex + 1, right);
}
}
int Partition(int[] array, int left, int right)
{
int pivot = array[right];
int i = left - 1;
for (int j = left; j < right; j++)
{
if (array[j] < pivot)
{
i++;
Swap(array, i, j);
}
}
Swap(array, i + 1, right);
return i + 1;
}
void Swap(int[] array, int i, int j)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
ソート アルゴリズムは、コンピューター サイエンスにおけるアルゴリズムの一般的なクラスで、一連のデータを特定の順序で配置するために使用されます。一般的な並べ替えアルゴリズムには次のものがあります。
-
クイック ソート (クイック ソート): クイック ソートは、ピボット要素を通じてデータを 2 つのサブシーケンスに分割し、その後 2 つのサブシーケンスをそれぞれすばやく並べ替える分割統治型の並べ替えアルゴリズムです。このアルゴリズムの時間計算量は O(nlogn) ですが、最悪の場合の時間計算量は O(n^2) です。
-
マージ ソート (マージ ソート): マージ ソートは、分割統治型の並べ替えアルゴリズムでもあります。データを 2 つのサブシーケンスに分割することにより、それらは個別にマージおよび並べ替えられ、最後に 2 つの順序付けされたサブシーケンスが 1 つの順序付けされたシーケンスにマージされます。このアルゴリズムの時間計算量は O(nlogn) です。
-
ヒープ ソート (ヒープ ソート): ヒープ ソートは、ヒープの性質を使用してソートします。まず、データが大きなルート ヒープまたは小さなルート ヒープに構築され、次にヒープの先頭要素が最後の要素と交換され、その後ヒープのサイズが 1 つ減って、すべての要素が一致するまでヒープの並べ替えが続けられます。並べ替えました。このアルゴリズムの時間計算量は O(nlogn) です。
-
インサーション ソート (インサーション ソート): インサーション ソートは、ポーカーをプレイするときのカードの順序に似た、単純なソート アルゴリズムです。このアルゴリズムの時間計算量は O(n^2) ですが、小規模なデータの場合は、挿入ソートの方が効率的です。
-
シェル ソート (シェル ソート): シェル ソートは、挿入ソートの改良されたアルゴリズムであり、データをグループ化することによって挿入ソートを実行し、その後グループ化のサイズを徐々に減らし、最後に全体的な挿入ソートを実行します。このアルゴリズムの時間計算量は O(nlogn) です。
3. 動的プログラミング アルゴリズム: 動的プログラミング アルゴリズムは、問題を部分問題に分解することで複雑な最適化問題を解決します。グラフィックス処理、パス計画、文字列処理などの分野で広く使用されています。たとえば、最長共通部分列 (Longest Common Subsequence) 問題は古典的な動的計画法の問題です。次は、動的計画法アルゴリズムを使用して最長共通部分列問題を解決する例です。
int LongestCommonSubsequence(string s1, string s2)
{
int m = s1.Length;
int n = s2.Length;
int[,] dp = new int[m + 1, n + 1];
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
if (s1[i - 1] == s2[j - 1])
{
dp[i, j] = dp[i - 1, j - 1] + 1;
}
else
{
dp[i, j] = Math.Max(dp[i - 1, j], dp[i, j - 1]);
}
}
}
return dp[m, n];
}
4. グラフ アルゴリズム (最短パス アルゴリズムや最小スパニング ツリー アルゴリズムなど): グラフ アルゴリズムは、パス検索、ネットワーク最適化、ソーシャル ネットワーク分析など、グラフ関連の問題を解決するために使用されます。その中でも、ダイクストラ アルゴリズムは一般的に使用される最短経路アルゴリズムです。次は、重み付きグラフ内の 2 つのノード間の最短経路を見つけるためにダイクストラ アルゴリズムを使用する例です。
void DijkstraAlgorithm(Graph graph, int source)
{
int[] distance = new int[graph.Size];
bool[] visited = new bool[graph.Size];
int[] parent = new int[graph.Size];
for (int i = 0; i < graph.Size; i++)
{
distance[i] = int.MaxValue;
visited[i] = false;
parent[i] = -1;
}
distance[source] = 0;
for (int count = 0; count < graph.Size - 1; count++)
{
int u = GetMinimumDistanceVertex(distance, visited);
visited[u] = true;
foreach (var neighbor in graph.GetNeighbors(u))
{
int v = neighbor.Vertex;
int weight = neighbor.Weight;
int newDistance = distance[u] + weight;
if (!visited[v] && newDistance < distance[v])
{
distance[v] = newDistance;
parent[v] = u;
}
}
}
PrintShortestPaths(distance, parent);
}
int GetMinimumDistanceVertex(int[] distance, bool[] visited)
{
int minDistance = int.MaxValue;
int minIndex = -1;
for (int i = 0; i < distance.Length; i++)
{
if (!visited[i] && distance[i] < minDistance)
{
minDistance = distance[i];
minIndex = i;
}
}
return minIndex;
}
void PrintShortestPaths(int[] distance, int[] parent)
{
for (int i = 0; i < distance.Length; i++)
{
Console.Write($"Shortest path to vertex {i}: ");
PrintPath(i, parent);
Console.WriteLine($" (distance: {distance[i]})");
}
}
void PrintPath(int vertex, int[] parent)
{
if (vertex == -1)
{
return;
}
PrintPath(parent[vertex], parent);
Console.Write($"{vertex} ");
}
最短パス アルゴリズムは、重み付き有向グラフまたは無向グラフ内の 2 つのノード間の最短パスを見つけるためのアルゴリズムです。最も有名な最短パス アルゴリズムは、有向グラフ内のソース ノードから他のすべてのノードへの最短パスを見つけるダイクストラ アルゴリズムです。負の重み付けエッジを処理できる Bellman-Ford アルゴリズムや、最短パスを迅速に見つけるためのヒューリスティック検索アルゴリズムである A* アルゴリズムなどの他の最短パス アルゴリズムもあります。
最小スパニングツリーアルゴリズムは、無向重み付きグラフにおいて最小のエッジ重みを持つスパニングツリーを見つけるためのアルゴリズムです。最も有名な最小スパニング ツリー アルゴリズムは、Prim のアルゴリズムと Kruskal のアルゴリズムです。Prim のアルゴリズムは、ノードに基づいた貪欲なアルゴリズムであり、ノードから開始してスパニング ツリーを徐々に拡張します。Kruskal アルゴリズムはエッジに基づく貪欲なアルゴリズムであり、スパニング ツリーが完成するまでエッジの重みの昇順にエッジを追加します。
さらに、トポロジカルソート、強連結成分、オイラー回路など、他にも多くのグラフアルゴリズムがあります。これらのグラフ アルゴリズムは、ネットワーク ルーティング、交通、ソーシャル ネットワーク分析、画像処理などのコンピューター サイエンスで広く使用されています。
5. 深層学習アルゴリズム (ニューラル ネットワークや畳み込みニューラル ネットワークなど): 深層学習アルゴリズムは、人工ニューラル ネットワークに基づく機械学習アルゴリズムの一種であり、認識、分類、予測などの複雑なパターン認識問題を解決するために使用されます。たとえば、畳み込みニューラル ネットワーク (CNN) は、コンピューター ビジョン タスクで広く使用されている深層学習アルゴリズムです。CNN を使用した画像分類の例を次に示します。
var model = new Sequential();
model.Add(new Conv2D(32, (3, 3), activation: "relu", inputShape: (28, 28, 1)));
model.Add(new MaxPooling2D(poolSize: (2, 2)));
model.Add(new Flatten());
model.Add(new Dense(64, activation: "relu"));
model.Add(new Dense(10, activation: "softmax"));
model.Compile(optimizer: "adam", loss: "categorical_crossentropy", metrics: new[] { "accuracy" });
model.Fit(x_train, y_train, batch_size: 128, epochs: 10, validation_data: (x_test, y_test));
多層パーセプトロンは、完全に接続された一連の層を介して入力から出力へのマッピングを実現します。各層には複数のニューロンが含まれ、各ニューロンは前の層のすべてのニューロンに接続されます。これらのニューロンは、活性化関数を通じて入力信号を出力信号に変換し、それが次の層に渡されます。多層パーセプトロンは通常、画像、音声、テキストなどのデータの分類と予測に使用されます。
畳み込みニューラル ネットワークは、畳み込み演算を使用して画像、音声、ビデオなどのデータを処理します。その中核となるのは畳み込み層です。畳み込み層は、スライディング ウィンドウを介して入力データに対して畳み込み演算を実行し、特徴情報を抽出します。畳み込みニューラル ネットワークには、プーリング層と全結合層も含まれています。プーリング層は特徴マップのサイズを削減するために使用され、全結合層は要約された特徴を予測のために出力層に入力するために使用されます。畳み込みニューラル ネットワークは、通常、画像やビデオなどの大規模データの分類、オブジェクトの検出、画像のセグメンテーションなどのタスクに使用されます。
上記の 5 つの一般的に使用されるアルゴリズムの例を通して、それらがさまざまな分野で幅広い用途があることがわかります。開発者は、特定の問題やさまざまなパフォーマンスを達成するニーズに応じて、適切なアルゴリズムを選択できます。