目次
アルゴリズム思考
深さ優先検索 (DFS) アルゴリズムの考え方は、グラフの特定の開始頂点から開始し、続行できなくなるまでパスをたどってグラフ内のすべての頂点をできるだけ深く訪問し、その後戻るというものです。そして他の道を模索してください。具体的には、DFS アルゴリズムはスタック データ構造を使用して実装されており、頂点を訪問した後、その未訪問の隣接頂点がスタックにプッシュされ、訪問済みとしてマークされます。次に、スタックから次の未訪問の頂点を取り出し、スタックが空になるまで上記のプロセスを繰り返します。
時間の複雑さと空間の複雑さ
深さ優先探索 (DFS) アルゴリズムの時間計算量は O(V+E) です。ここで、V は頂点の数、E はエッジの数です。これは、最悪の場合、トラバースを完了するにはすべての頂点とエッジを訪問する必要があるためです。
DFS アルゴリズムはスタック データ構造を使用して、訪問する頂点とその隣接頂点を格納するため、空間の複雑さはスタックに格納されている要素の数に依存します。最悪の場合、つまりグラフがチェーン構造の場合、DFS アルゴリズムが保存する必要がある要素の数が O(V) レベルに達するため、空間複雑度も O(V) になります。
実際のアプリケーションでは、再帰呼び出しの制限により、DFS アルゴリズムの空間の複雑さがさらに軽減される可能性があることに注意してください。たとえば、一部の特殊なケースでは、プルーニングによってストレージ スペースの占有量をさらに削減できます。
アルゴリズムの実装
以下は、基本的な C# 深さ優先検索アルゴリズムの実装です。
/// <summary>
/// 深度优先搜索算法
/// </summary>
public class DepthFirstSearch
{
private int V; // 图形中的顶点数
private List<int>[] adj; // 邻接表表示
public DepthFirstSearch(int v)
{
V = v;
adj = new List<int>[V];
for (int i = 0; i < V; ++i)
adj[i] = new List<int>();
}
public void AddEdge(int v, int w)
{
adj[v].Add(w); // 将 w 添加到 v 的邻接表中
}
// 深度优先遍历算法
private void DFSUtil(int v, bool[] visited)
{
visited[v] = true;
Console.Write(v + " ");
foreach (int i in adj[v])
{
if (!visited[i])
DFSUtil(i, visited);
}
}
// 从顶点 v 开始进行深度优先遍历
public void DFS(int v)
{
bool[] visited = new bool[V];
DFSUtil(v, visited);
}
}
static void Main(string[] args)
{
DepthFirstSearch g = new DepthFirstSearch(4);
g.AddEdge(0, 1);
g.AddEdge(0, 2);
g.AddEdge(1, 2);
g.AddEdge(2, 0);
g.AddEdge(2, 3);
g.AddEdge(3, 3);
Console.WriteLine("从顶点 2 开始的深度优先遍历:");
g.DFS(2);
}
この実装では、DepthFirstSearch
グラフを表すクラスを定義します。このクラスには、エッジと深さ優先トラバーサルを追加するための隣接リストとメソッドの配列が含まれています。このメソッドではDFSUtil
、ブール配列を使用してvisited
訪問した頂点を追跡し、DFSUtil
その未訪問の近傍を再帰的に呼び出すことによって走査します。このメソッドではDFS
、新しいvisited
配列を作成し、指定された開始頂点から呼び出しますDFSUtil
。最後に、メソッド内にMain
新しいインスタンスを作成し、頂点 2 から開始する深さ優先トラバーサルを実行するメソッドを呼び出します。 Graph
DFS
アルゴリズムの長所と短所
深さ優先検索アルゴリズムの利点:
- 実装が簡単: C# の深さ優先検索アルゴリズムは実装が比較的簡単で、初心者が学習して理解するのに適しています。
- 低い空間複雑さ: トラバーサルの深さがグラフの平均深さを超える場合、C# 深さ優先検索アルゴリズムの空間複雑さは幅優先検索アルゴリズムよりも低くなります。
- パスをより速く見つける: 深さ優先検索アルゴリズムの性質により、開始頂点からゴール頂点までのパスを見つける方が簡単です。
深さ優先検索アルゴリズムの欠点:
- 最短パスが見つからない場合がある: 深さ優先検索アルゴリズムの性質により、開始頂点からゴール頂点までの最短パスを必ずしも見つけられるとは限りません。ターゲットの頂点が浅いレベルにある場合、頂点に到達するために多数のノードをトラバースする必要があり、結果としてアルゴリズムの効率が低くなります。
- 無限ループに陥る可能性: グラフ内にサイクルがある場合、深さ優先検索アルゴリズムが無限ループに陥り、開始頂点から他の頂点へのパスを見つけられない可能性があります。したがって、深さ優先検索アルゴリズムを適用する前に、入力にサイクルがないことを確認する必要があります。
- フォークのあるグラフの効率が低下する: 多数の分岐があるグラフでは、深さ優先検索アルゴリズムによって多くのノードが削除される可能性があり、アルゴリズムの効率が低下します。
応用分野
深さ優先検索 (DFS) アルゴリズムは、基本的なグラフ走査アルゴリズムであり、多くの分野で広く使用できます。以下に、典型的なアプリケーション分野をいくつか示します。
-
グラフ トラバーサル: DFS アルゴリズムは、パス、接続、ループの検索などのグラフ トラバーサルに使用できます。
-
検索問題: バックトラッキング技術を使用することで、DFS アルゴリズムを迷路問題や数独問題などの検索問題に使用できます。
-
最小スパニング ツリー: すべてのエッジを重みでソートし、エッジを順番にスパニング ツリーに追加することにより、DFS アルゴリズムはプリムのアルゴリズムとクラスカルのアルゴリズムを実装して最小スパニング ツリーを構築できます。
-
有向非巡回グラフ: 有向非巡回グラフ (DAG) では、トポロジカル ソートや最長パスの計算などの問題に DFS アルゴリズムを使用できます。
-
人工知能: DFS アルゴリズムは、アルファベータ枝刈りアルゴリズム、ヒューリスティック検索などの人工知能の分野でも使用できます。
一言で言えば、DFS アルゴリズムは基本的なグラフ走査アルゴリズムとして、幅広い応用範囲があり、多くの分野のさまざまな問題を解決できます。