mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-20 18:46:06 +00:00
build
This commit is contained in:
@@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 9.1 グラフ
|
||||
|
||||
<u>グラフ</u>は非線形データ構造の一種で、<u>頂点</u>と<u>辺</u>で構成されます。グラフ$G$は、頂点の集合$V$と辺の集合$E$の組み合わせとして抽象的に表現できます。以下の例は、5つの頂点と7つの辺を含むグラフを示しています。
|
||||
<u>グラフ(graph)</u>は、<u>頂点(vertex)</u>と<u>辺(edge)</u>から構成される非線形データ構造です。グラフ $G$ は、頂点集合 $V$ と辺集合 $E$ からなる集合として抽象的に表せます。以下の例は、5 個の頂点と 7 本の辺を含むグラフを示しています。
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
@@ -14,7 +14,7 @@ G & = \{ V, E \} \newline
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
頂点をノード、辺をノードを接続する参照(ポインタ)と見なすと、グラフは連結リストから拡張されたデータ構造として見ることができます。下図に示すように、**線形関係(連結リスト)や分割統治関係(木)と比較して、ネットワーク関係(グラフ)は自由度が高いため、より複雑です**。
|
||||
頂点をノード、辺を各ノードをつなぐ参照(ポインタ)とみなせば、グラフは連結リストを拡張したデータ構造の一種と捉えられます。次の図に示すように、**線形関係(連結リスト)や分治関係(木)と比べて、ネットワーク関係(グラフ)は自由度が高く**、そのぶん複雑です。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
@@ -22,82 +22,82 @@ $$
|
||||
|
||||
## 9.1.1 グラフの一般的な種類と用語
|
||||
|
||||
グラフは、辺に方向があるかどうかによって<u>無向グラフ</u>と<u>有向グラフ</u>に分けることができます(下図参照)。
|
||||
辺が方向性を持つかどうかに応じて、<u>無向グラフ(undirected graph)</u>と<u>有向グラフ(directed graph)</u>に分けられます。次の図のとおりです。
|
||||
|
||||
- 無向グラフでは、辺は2つの頂点間の「双方向」接続を表します。例えば、Facebookの「友達」関係です。
|
||||
- 有向グラフでは、辺に方向性があります。つまり、辺$A \rightarrow B$と$A \leftarrow B$は互いに独立しています。例えば、InstagramやTikTokの「フォロー」と「フォロワー」の関係です。
|
||||
- 無向グラフでは、辺は 2 つの頂点間の「双方向」の接続関係を表します。例えば WeChat や QQ における「友だち関係」です。
|
||||
- 有向グラフでは、辺は方向性を持ち、すなわち $A \rightarrow B$ と $A \leftarrow B$ の 2 方向の辺は互いに独立です。例えば Weibo や Douyin における「フォロー」と「フォロワー」の関係です。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 図 9-2 有向グラフと無向グラフ </p>
|
||||
|
||||
すべての頂点が接続されているかどうかによって、グラフは<u>連結グラフ</u>と<u>非連結グラフ</u>に分けることができます(下図参照)。
|
||||
すべての頂点が連結しているかどうかに応じて、<u>連結グラフ(connected graph)</u>と<u>非連結グラフ(disconnected graph)</u>に分けられます。次の図のとおりです。
|
||||
|
||||
- 連結グラフでは、任意の頂点から開始して他の任意の頂点に到達することが可能です。
|
||||
- 非連結グラフでは、任意の開始頂点から到達できない頂点が少なくとも1つ存在します。
|
||||
- 連結グラフでは、ある頂点から出発すると、ほかの任意の頂点に到達できます。
|
||||
- 非連結グラフでは、ある頂点から出発すると、少なくとも 1 つの頂点には到達できません。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 図 9-3 連結グラフと非連結グラフ </p>
|
||||
|
||||
辺に重み変数を追加することもでき、その結果として<u>重み付きグラフ</u>が生まれます(下図参照)。例えば、Instagramでは、システムがあなたと他のユーザーとの間の相互作用レベル(いいね、閲覧、コメントなど)によってフォロワーとフォロー中のリストをソートします。このような相互作用ネットワークは重み付きグラフで表現できます。
|
||||
辺に「重み」の変数を追加すると、次の図に示すような<u>重み付きグラフ(weighted graph)</u>が得られます。例えば『Honor of Kings』のようなモバイルゲームでは、システムが共にプレイした時間に基づいてプレイヤー間の「親密度」を計算します。この親密度ネットワークは重み付きグラフで表せます。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 図 9-4 重み付きグラフと重みなしグラフ </p>
|
||||
|
||||
グラフデータ構造には、以下のような一般的に使用される用語があります。
|
||||
グラフというデータ構造には、次のような基本用語があります。
|
||||
|
||||
- <u>隣接</u>:2つの頂点を接続する辺がある場合、これら2つの頂点は「隣接」していると言われます。上図では、頂点1の隣接頂点は頂点2、3、5です。
|
||||
- <u>パス</u>:頂点Aから頂点Bまでに通過する辺のシーケンスを、AからBへのパスと呼びます。上図では、辺のシーケンス1-5-2-4は頂点1から頂点4へのパスです。
|
||||
- <u>次数</u>:頂点が持つ辺の数です。有向グラフの場合、<u>入次数</u>はその頂点を指す辺の数、<u>出次数</u>はその頂点から出る辺の数を指します。
|
||||
- <u>隣接(adjacency)</u>:2 つの頂点の間に辺が存在するとき、この 2 つの頂点は「隣接している」といいます。上図では、頂点 1 に隣接する頂点は 2、3、5 です。
|
||||
- <u>経路(path)</u>:頂点 A から頂点 B までに通過する辺で構成された列を、A から B への「経路」と呼びます。上図では、辺の列 1-5-2-4 は頂点 1 から頂点 4 への 1 本の経路です。
|
||||
- <u>次数(degree)</u>:ある頂点が持つ辺の本数です。有向グラフでは、<u>入次数(in-degree)</u>はその頂点に向かう辺の本数を表し、<u>出次数(out-degree)</u>はその頂点から出る辺の本数を表します。
|
||||
|
||||
## 9.1.2 グラフの表現
|
||||
|
||||
グラフの一般的な表現には「隣接行列」と「隣接リスト」があります。以下の例では無向グラフを使用します。
|
||||
グラフの一般的な表現方法には「隣接行列」と「隣接リスト」があります。以下では無向グラフを例に説明します。
|
||||
|
||||
### 1. 隣接行列
|
||||
|
||||
グラフの頂点数を$n$とすると、<u>隣接行列</u>は$n \times n$の行列を使用してグラフを表現します。各行(列)は頂点を表し、行列要素は辺を表し、2つの頂点間に辺があるかどうかを$1$または$0$で示します。
|
||||
グラフの頂点数を $n$ とすると、<u>隣接行列(adjacency matrix)</u>は $n \times n$ の行列を用いてグラフを表します。各行(列)は 1 つの頂点を表し、行列要素は辺を表します。$1$ または $0$ を用いて、2 つの頂点の間に辺があるかどうかを示します。
|
||||
|
||||
下図に示すように、隣接行列を$M$、頂点のリストを$V$とすると、行列要素$M[i, j] = 1$は頂点$V[i]$と頂点$V[j]$の間に辺があることを示し、逆に$M[i, j] = 0$は2つの頂点間に辺がないことを示します。
|
||||
次の図のように、隣接行列を $M$、頂点リストを $V$ とすると、行列要素 $M[i, j] = 1$ は頂点 $V[i]$ から頂点 $V[j]$ への辺が存在することを表し、逆に $M[i, j] = 0$ は 2 つの頂点の間に辺がないことを表します。
|
||||
|
||||
{ class="animation-figure" }
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 図 9-5 隣接行列によるグラフの表現 </p>
|
||||
<p align="center"> 図 9-5 グラフの隣接行列による表現 </p>
|
||||
|
||||
隣接行列には以下の特性があります。
|
||||
隣接行列には次の特徴があります。
|
||||
|
||||
- 頂点は自分自身に接続することはできないため、隣接行列の主対角線上の要素は意味がありません。
|
||||
- 無向グラフの場合、両方向の辺は等価であるため、隣接行列は主対角線に関して対称です。
|
||||
- 隣接行列の要素を$1$と$0$から重みに置き換えることで、重み付きグラフを表現できます。
|
||||
- 単純グラフでは、頂点は自分自身とは接続できないため、このとき隣接行列の主対角線上の要素には意味がありません。
|
||||
- 無向グラフでは、2 方向の辺は等価であるため、このとき隣接行列は主対角線に関して対称です。
|
||||
- 隣接行列の要素を $1$ と $0$ から重みに置き換えると、重み付きグラフを表せます。
|
||||
|
||||
隣接行列でグラフを表現する場合、行列要素に直接アクセスして辺を取得できるため、追加、削除、検索、変更の操作が効率的で、すべて時間計算量$O(1)$です。ただし、行列の空間計算量は$O(n^2)$で、より多くのメモリを消費します。
|
||||
隣接行列でグラフを表す場合、行列要素に直接アクセスして辺を取得できるため、追加・削除・検索・更新の操作効率は高く、時間計算量はいずれも $O(1)$ です。しかし、行列の空間計算量は $O(n^2)$ であり、メモリ使用量は多くなります。
|
||||
|
||||
### 2. 隣接リスト
|
||||
|
||||
<u>隣接リスト</u>は$n$個の連結リストを使用してグラフを表現し、各連結リストノードは頂点を表します。$i$番目の連結リストは頂点$i$に対応し、すべての隣接頂点(その頂点に接続された頂点)を含みます。下図は隣接リストを使用して格納されたグラフの例を示しています。
|
||||
<u>隣接リスト(adjacency list)</u>は、$n$ 本の連結リストを使ってグラフを表します。連結リストのノードは頂点を表します。第 $i$ 本の連結リストは頂点 $i$ に対応し、その頂点に隣接するすべての頂点(その頂点と接続された頂点)を格納します。次の図は、隣接リストで保存したグラフの例です。
|
||||
|
||||
{ class="animation-figure" }
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> 図 9-6 隣接リストによるグラフの表現 </p>
|
||||
<p align="center"> 図 9-6 グラフの隣接リストによる表現 </p>
|
||||
|
||||
隣接リストは実際の辺のみを格納し、辺の総数は$n^2$よりもはるかに少ないことが多く、より空間効率的です。ただし、隣接リストで辺を見つけるには連結リストを走査する必要があるため、その時間効率は隣接行列ほど良くありません。
|
||||
隣接リストは実際に存在する辺だけを格納し、辺の総数は通常 $n^2$ よりはるかに小さいため、より省スペースです。しかし、隣接リストでは辺を見つけるために連結リストを走査する必要があるため、時間効率は隣接行列に及びません。
|
||||
|
||||
上図を観察すると、**隣接リストの構造はハッシュテーブルの「チェイン法」と非常に似ているため、同様の方法を使用して効率を最適化できます**。例えば、連結リストが長い場合、それをAVL木や赤黒木に変換して、時間効率を$O(n)$から$O(\log n)$に最適化できます。連結リストをハッシュテーブルに変換することで、時間計算量を$O(1)$に削減することもできます。
|
||||
上図を見ると、**隣接リストの構造はハッシュテーブルにおける「連鎖アドレス法」と非常によく似ているため、同様の方法で効率を最適化できます**。例えば、連結リストが長い場合は AVL 木や赤黒木に変換して時間効率を $O(n)$ から $O(\log n)$ に改善できます。さらに、連結リストをハッシュテーブルに変換すれば、時間計算量を $O(1)$ まで下げられます。
|
||||
|
||||
## 9.1.3 グラフの一般的な応用
|
||||
|
||||
下表に示すように、多くの現実世界のシステムはグラフでモデル化でき、対応する問題はグラフ計算問題に削減できます。
|
||||
次の表のように、多くの現実のシステムはグラフでモデル化でき、対応する問題もグラフ計算の問題に帰着できます。
|
||||
|
||||
<p align="center"> 表 9-1 現実生活の一般的なグラフ </p>
|
||||
<p align="center"> 表 9-1 現実世界でよく見られるグラフ </p>
|
||||
|
||||
<div class="center-table" markdown>
|
||||
|
||||
| | 頂点 | 辺 | グラフ計算問題 |
|
||||
| -------------- | -------------- | -------------------------------- | --------------------------- |
|
||||
| ソーシャルネットワーク | ユーザー | フォロー / フォロワー関係 | 潜在的フォロー推薦 |
|
||||
| 地下鉄路線 | 駅 | 駅間の接続性 | 最短ルート推薦 |
|
||||
| 太陽系 | 天体 | 天体間の重力 | 惑星軌道計算 |
|
||||
| | 頂点 | 辺 | グラフ計算問題 |
|
||||
| -------- | ---- | -------------------- | ------------ |
|
||||
| ソーシャルネットワーク | ユーザー | 友だち関係 | 潜在的な友だちの推薦 |
|
||||
| 地下鉄路線 | 駅 | 駅間の接続性 | 最短経路の推薦 |
|
||||
| 太陽系 | 天体 | 天体間の万有引力作用 | 惑星軌道の計算 |
|
||||
|
||||
</div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -9,9 +9,9 @@ icon: material/graphql
|
||||
|
||||
!!! abstract
|
||||
|
||||
人生の旅路において、私たちの一人一人はノードであり、無数の見えない辺で結ばれています。
|
||||
|
||||
一つ一つの出会いと別れが、この広大な人生のグラフに独特の印を残していきます。
|
||||
人生の旅路において、私たちはそれぞれ一つひとつのノードのようなものであり、無数の見えない辺によって結ばれています。
|
||||
|
||||
出会いと別れのたびに、この巨大なネットワークグラフの中に固有の足跡が刻まれます。
|
||||
|
||||
## 章の内容
|
||||
|
||||
|
||||
@@ -4,32 +4,32 @@ comments: true
|
||||
|
||||
# 9.4 まとめ
|
||||
|
||||
### 1. 重要な復習
|
||||
### 1. 重要なポイントの振り返り
|
||||
|
||||
- グラフは頂点と辺で構成されます。頂点の集合と辺の集合として記述できます。
|
||||
- 線形関係(連結リストなど)や階層関係(木など)と比較して、ネットワーク関係(グラフ)はより大きな柔軟性を提供し、より複雑になります。
|
||||
- 有向グラフでは、辺に方向があります。連結グラフでは、任意の頂点から他の任意の頂点に到達できます。重み付きグラフでは、各辺に関連する重み変数があります。
|
||||
- 隣接行列は、行列(2次元配列)を使用してグラフを表現する方法です。行と列は頂点を表します。行列要素の値は、2つの頂点間に辺があるかどうかを示し、辺がある場合は$1$、ない場合は$0$を使用します。隣接行列は辺の追加、削除、チェックなどの操作に非常に効率的ですが、より多くのスペースが必要です。
|
||||
- 隣接リストは、連結リストの集合を使用してグラフを表現するもう一つの一般的な方法です。グラフ内の各頂点には、その隣接するすべての頂点を含むリストがあります。$i$番目のリストは頂点$i$を表します。隣接リストは隣接行列と比較してより少ないスペースを使用します。ただし、辺を見つけるためにリストを走査する必要があるため、時間効率は低くなります。
|
||||
- 隣接リストの連結リストが十分に長くなったとき、ルックアップ効率を向上させるために赤黒木やハッシュテーブルに変換できます。
|
||||
- アルゴリズム設計の観点から、隣接行列は「空間と時間のトレードオフ」の概念を反映し、隣接リストは「時間と空間のトレードオフ」を反映します。
|
||||
- グラフは、ソーシャルネットワークや地下鉄路線など、さまざまな現実世界のシステムをモデル化するために使用できます。
|
||||
- 木はグラフの特別なケースであり、木の走査もグラフ走査の特別なケースです。
|
||||
- グラフの幅優先走査は、近くから遠くへと層ごとに拡張する探索方法で、通常キューを使用します。
|
||||
- グラフの深さ優先走査は、それ以上のパスがない場合にバックトラックする前に、まず終端に到達することを優先する探索方法です。しばしば再帰を使用して実装されます。
|
||||
- グラフは頂点と辺から構成され、一組の頂点と一組の辺からなる集合として表せます。
|
||||
- 線形関係(連結リスト)や分治関係(木)と比べて、ネットワーク関係(グラフ)は自由度が高く、そのぶん複雑です。
|
||||
- 有向グラフの辺は方向性を持ち、連結グラフでは任意の頂点に到達でき、重み付きグラフの各辺は重み変数を含みます。
|
||||
- 隣接行列は行列を用いてグラフを表し、各行(列)が 1 つの頂点を表し、行列要素が辺を表します。$1$ または $0$ を用いて、2 つの頂点の間に辺があるかないかを示します。隣接行列は追加・削除・検索・更新の操作効率が高い一方で、より多くの空間を消費します。
|
||||
- 隣接リストは複数の連結リストを使ってグラフを表し、第 $i$ 個の連結リストが頂点 $i$ に対応し、その頂点に隣接するすべての頂点を格納します。隣接リストは隣接行列よりも省スペースですが、辺を探すために連結リストを走査する必要があるため、時間効率は低くなります。
|
||||
- 隣接リスト内の連結リストが長くなりすぎた場合は、赤黒木やハッシュテーブルに変換することで、検索効率を高められます。
|
||||
- アルゴリズムの考え方という観点では、隣接行列は「空間を時間と引き換えにする」ことを体現し、隣接リストは「時間を空間と引き換えにする」ことを体現します。
|
||||
- グラフは、ソーシャルネットワークや地下鉄路線など、さまざまな現実のシステムをモデル化するために使えます。
|
||||
- 木はグラフの特殊な一例であり、木の走査もグラフ走査の特殊な一例です。
|
||||
- グラフの幅優先探索は、近いところから遠いところへ、層ごとに広がっていく探索方法であり、通常はキューを使って実装します。
|
||||
- グラフの深さ優先探索は、まず行けるところまで進み、進めなくなったらバックトラックする探索方法であり、通常は再帰に基づいて実装します。
|
||||
|
||||
### 2. Q & A
|
||||
|
||||
**Q**: パスは頂点のシーケンスとして定義されますか、それとも辺のシーケンスとして定義されますか?
|
||||
**Q**:経路の定義は頂点列ですか、それとも辺列ですか?
|
||||
|
||||
グラフ理論では、グラフ内のパスは頂点のシーケンスを結ぶ有限または無限の辺のシーケンスです。
|
||||
Wikipedia では言語版ごとに定義が一致していません。英語版では「経路は辺の列」であり、中国語版では「経路は頂点の列」です。以下は英語版の原文です:In graph theory, a path in a graph is a finite or infinite sequence of edges which joins a sequence of vertices.
|
||||
|
||||
この文書では、パスは頂点のシーケンスではなく、辺のシーケンスと考えられます。これは、2つの頂点を結ぶ複数の辺がある可能性があり、その場合各辺がパスに対応するためです。
|
||||
本書では、経路を頂点列ではなく辺列とみなします。これは、2 つの頂点の間に複数の辺が存在する可能性があり、その場合は各辺がそれぞれ 1 本の経路に対応するためです。
|
||||
|
||||
**Q**: 非連結グラフでは、走査できない点がありますか?
|
||||
**Q**:非連結グラフには到達できない頂点がありますか?
|
||||
|
||||
非連結グラフでは、特定の点から到達できない頂点が少なくとも1つあります。非連結グラフを走査するには、グラフのすべての連結成分を走査するために複数の開始点を設定する必要があります。
|
||||
非連結グラフでは、ある頂点から出発すると、少なくとも 1 つの頂点には到達できません。非連結グラフ全体を走査するには、グラフ内のすべての連結成分をたどれるように複数の始点を設定する必要があります。
|
||||
|
||||
**Q**: 隣接リストで、「その頂点に接続されたすべての頂点」の順序は重要ですか?
|
||||
**Q**:隣接リストにおいて、「その頂点に接続されたすべての頂点」の順序に決まりはありますか?
|
||||
|
||||
任意の順序で構いません。ただし、実際のアプリケーションでは、頂点が追加された順序や頂点値の順序など、特定のルールに従ってそれらをソートする必要がある場合があります。これにより、特定の極値を持つ頂点を素早く見つけることができます。
|
||||
順序は任意でかまいません。ただし実際の応用では、頂点を追加した順序や頂点値の大小順など、特定の規則に従って並べ替える必要がある場合があります。そうすることで、「ある種の極値を持つ」頂点をすばやく見つけやすくなります。
|
||||
|
||||
Reference in New Issue
Block a user