Skip to content

Commit c89f954

Browse files
committed
[WIP] Пример BFS в терминах линейной алгебры.
1 parent d722304 commit c89f954

File tree

5 files changed

+124
-50
lines changed

5 files changed

+124
-50
lines changed

tex/GraphTheoryIntro.tex

Lines changed: 84 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,10 @@ \section{Обход графа в ширину}
189189
Пример.
190190

191191
Алгоритм обхода в ширину может быть переформулирован в терминах матрично-векторных операций следующим образом\footnote{
192-
Стоит отметить, что ситуация со не менее известным обходом в глубину (Depth-First Search, DFS) более сложная:
192+
Стоит отметить, что ситуация с не менее известным обходом в глубину (Depth-First Search, DFS) более сложная:
193193
на момент написания текста не известно естественного выражения данного обхода в терминах линейной алгебры.
194194
Доказательство невозможности такого построения также не предъявлены.
195-
При этом, решения для частных случаев (деревья, ориентированные графы без циклов) предложены, например, в работе~\cite{10.1145/3315454.3329962}}.
195+
При этом, решения для частных случаев (деревья, ориентированные графы без циклов) предложены, например, в работе~\cite{10.1145/3315454.3329962}.}.
196196
Пусть фронт --- вектор размера $n$, а сам граф представлен матрицей смежности.
197197
Тогда один шаг --- получение нового фронта --- это умножение текущего фронта на матрицу смежности.
198198
Для того, чтобы отслеживать посещённые вершины нужна маска.
@@ -201,68 +201,91 @@ \section{Обход графа в ширину}
201201

202202
\begin{example}
203203

204-
В качестве примера рассмотрим обход в ширину графа из примера~\ref{example:diGraph} начиная с вершины 2.
205-
Для обозначения текущего фронта будем использовать зелёный цвет, а для достижимых из него за один шаг --- жёлтый.
204+
Рассмотрим обход в ширину графа из примера~\ref{example:diGraph} начиная с вершины 2.
205+
Для обозначения текущего фронта будем использовать зелёный цвет, а для достижимых из него за один шаг --- жёлтый, обведём вершину красным, если она посешается повторно.
206206

207-
\begin{tabular}[t]{c | c }
208-
\input{figures/graph/graph_BFS_1.tex}
207+
\begin{tabular}[t]{c | c}
208+
\begin{minipage}[c]{0.35\textwidth}
209+
\input{figures/graph/graph_BFS_1.tex}
210+
\end{minipage}
209211
&
210212
\begin{minipage}{0.7\textwidth}
211-
$
212-
\text{visited} =
213-
\begin{pmatrix}
214-
0 & 0 & 0 & 0
215-
\end{pmatrix}
216-
$
213+
$\begin{aligned}
214+
\textit{current\_front} & =
215+
\begin{pmatrix}
216+
0 & 0 & 1 & 0
217+
\end{pmatrix}
217218
\\
218-
$
219-
\begin{pmatrix}
220-
0 & 0 & 1 & 0
221-
\end{pmatrix}
222-
\begin{pmatrix}
223-
0 & 1 & 0 & 0 \\
224-
0 & 0 & 1 & 0 \\
225-
1 & 0 & 0 & 1 \\
226-
0 & 0 & 1 & 0
227-
\end{pmatrix} =
228-
\begin{pmatrix}
229-
1 & 0 & 0 & 1
230-
\end{pmatrix}
231-
$
232-
\\
233-
$
234-
\text{new\_front} =
235-
\begin{pmatrix}
236-
1 & 0 & 0 & 1
237-
\end{pmatrix}
238-
\begin{pmatrix}
239-
0 & 0 & 0 & 0
240-
\end{pmatrix}
241-
=
242-
\begin{pmatrix}
243-
1 & 0 & 0 & 1
244-
\end{pmatrix}
245-
$
246-
\end{minipage}
219+
\textit{visited} & =
220+
\begin{pmatrix}
221+
0 & 0 & 0 & 0
222+
\end{pmatrix}
223+
\\
224+
\textit{new\_front} & =
225+
\textit{current\_front} \cdot M
226+
\\
227+
& =
228+
\begin{pmatrix}
229+
0 & 0 & 1 & 0
230+
\end{pmatrix}
231+
\begin{pmatrix}
232+
0 & 1 & 0 & 0 \\
233+
0 & 0 & 1 & 0 \\
234+
1 & 0 & 0 & 1 \\
235+
0 & 0 & 1 & 0
236+
\end{pmatrix} \\
237+
& =
238+
\begin{pmatrix}
239+
1 & 0 & 0 & 1
240+
\end{pmatrix}
241+
\\
242+
\textit{visited} & = \textit{visited} \textit{new\_front} \\
243+
&=
244+
\begin{pmatrix}
245+
0 & 0 & 0 & 0
246+
\end{pmatrix}
247+
\begin{pmatrix}
248+
0 & 0 & 1 & 0
249+
\end{pmatrix}
250+
\\
251+
\textit{current\_front} & = \textit{visited} \textit{new\_front}
252+
\\
253+
& =
254+
\begin{pmatrix}
255+
1 & 0 & 0 & 1
256+
\end{pmatrix}
257+
\begin{pmatrix}
258+
0 & 0 & 1 & 0
259+
\end{pmatrix} \\
260+
& =
261+
\begin{pmatrix}
262+
1 & 0 & 0 & 1
263+
\end{pmatrix} \\
264+
\end{aligned}$
265+
\end{minipage}
247266
\\ \hline
248-
\input{figures/graph/graph_BFS_2.tex}
267+
\begin{minipage}[c]{0.35\textwidth}
268+
\input{figures/graph/graph_BFS_2.tex}
269+
\end{minipage}
249270
&
250-
$
251-
\begin{pmatrix}
271+
$\begin{aligned}
272+
& \begin{pmatrix}
252273
1 & 0 & 0 & 1
253274
\end{pmatrix}
254275
\begin{pmatrix}
255276
0 & 1 & 0 & 0 \\
256277
0 & 0 & 1 & 0 \\
257278
1 & 0 & 0 & 1 \\
258279
0 & 0 & 1 & 0
259-
\end{pmatrix} =
280+
\end{pmatrix} \\ &=
260281
\begin{pmatrix}
261282
0 & 1 & 1 & 0
262283
\end{pmatrix}
263-
$
284+
\end{aligned}$
264285
\\ \hline
265-
\input{figures/graph/graph_BFS_3.tex}
286+
\begin{minipage}[c]{0.35\textwidth}
287+
\input{figures/graph/graph_BFS_3.tex}
288+
\end{minipage}
266289
&
267290
$
268291
\begin{pmatrix}
@@ -289,6 +312,19 @@ \section{Обход графа в ширину}
289312

290313
Пример.
291314

315+
\begin{minipage}[c]{0.35\textwidth}
316+
\input{figures/graph/graph_MS-BFS_1.tex}
317+
\end{minipage}
318+
\begin{minipage}{0.7\textwidth}
319+
\end{minipage}
320+
321+
322+
\begin{minipage}[c]{0.35\textwidth}
323+
\input{figures/graph/graph_MS-BFS_2.tex}
324+
\end{minipage}
325+
\begin{minipage}{0.7\textwidth}
326+
\end{minipage}
327+
292328

293329
\section{Задачи поиска путей}
294330

@@ -351,7 +387,7 @@ \section{Алгоритм Флойда-Уоршелла}
351387
\item $\mathbb{0} \otimes \mathbb{0} = \mathbb{0}$ : если не существует пути $i \pi j$ и не существует пути $j \pi k$, то не существует и пути $i \pi k$.
352388
\end{itemize}
353389

354-
Новую операцию добавим к моноиду и получим новую алгебраическую структуру $\mathbb{G}' = (S, \oplus,\otimes)$. Данная структура является коммутативным моноидом по сложению (по построению) с нейтральным элементом $\mathbb{0}$. Из построения $\otimes$ видно, что $\mathbb{0}$ является аннигилятором. Ничего более про операцию $\otimes$, а значит и про $\mathbb{G}'$ мы сказать, исходя из построения, не можем. Классический фреймворк для решения algebraic path problem подразумевает, что $\mathbb{G}'$ является полукольцом, однако далее мы увидим, что существуют задачи, в которых $\otimes$, например, не является ассоциативной\footnote{Такой будет рассматриваемая в данной работе задача достижимости с ограничениями в терминах формальных языков. Другие примеры можно найти в уже упоминавшейся работе~\cite{Baras2010PathPI}}. А значит, согласно нашему определению, $\mathbb{G}'$ полукольцом не является.
390+
Новую операцию добавим к моноиду и получим новую алгебраическую структуру $\mathbb{G}' = (S, \oplus,\otimes)$. Данная структура является коммутативным моноидом по сложению (по построению) с нейтральным элементом $\mathbb{0}$. Из построения $\otimes$ видно, что $\mathbb{0}$ является аннигилятором. Ничего более про операцию $\otimes$, а значит и про $\mathbb{G}'$ мы сказать, исходя из построения, не можем. Классический фреймворк для решения algebraic path problem подразумевает, что $\mathbb{G}'$ является полукольцом, однако далее мы увидим, что существуют задачи, в которых $\otimes$, например, не является ассоциативной\footnote{Такой будет рассматриваемая в данной работе задача достижимости с ограничениями в терминах формальных языков. Другие примеры можно найти в уже упоминавшейся работе~\cite{Baras2010PathPI}.}. А значит, согласно нашему определению, $\mathbb{G}'$ полукольцом не является.
355391

356392
Теперь, когда построена алгебраическая структура, обеспечивающая вычисление формулы~
357393
\ref{eq:algPathProblem}, мы можем предложить алгоритм вычисления этой формулы и данным алгоритмом в интересующих нас частных случаях будет являться алгоритм Флойда-Уоршелла~\cite{Floyd1962, Bernard1959, Warshall1962}. Псевдокод алгоритма представлен на листинге~\ref{lst:algoFloydWarxhall}, а его сложность $O(n^3)$. Он практически дословно основан на описанной выше идее сборки путей из двух подпутей: тройной вложенный цикл перебирает все возможные разбиения пути на две части, а в строке 7 как раз и происходит вычисление формулы~

tex/figures/graph/graph_BFS_2.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
\node[state,fill=green] (q_0) at (T60.right corner) {$0$};
1010
\node[state,fill=yellow] (q_1) at (T60.left corner) {$1$};
11-
\node[state,fill=yellow, draw=red] (q_2) at (T60.apex) {$2$};
11+
\node[state,fill=yellow, draw=red, line width=0.45mm] (q_2) at (T60.apex) {$2$};
1212
\node[state,fill=green] (q_3) [right=1.5cm of q_2] {$3$};
1313
\path[->]
1414
(q_0) edge (q_1)

tex/figures/graph/graph_BFS_3.tex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
\node[state] (q_0) at (T60.right corner) {$0$};
1010
\node[state,fill=green] (q_1) at (T60.left corner) {$1$};
11-
\node[state,fill=yellow, draw=red] (q_2) at (T60.apex) {$2$};
11+
\node[state,fill=yellow, draw=red, line width=0.45mm] (q_2) at (T60.apex) {$2$};
1212
\node[state] (q_3) [right=1.5cm of q_2] {$3$};
1313
\path[->]
1414
(q_0) edge (q_1)

tex/figures/graph/graph_MS-BFS_1.tex

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
\begin{tikzpicture}[]
2+
% Apex angle 60 degrees
3+
\node[isosceles triangle,
4+
isosceles triangle apex angle=60,
5+
draw=none,fill=none,
6+
minimum size=2cm] (T60) at (3,0){};
7+
8+
9+
\node[state] (q_0) at (T60.right corner) {$0$};
10+
\node[state,fill=green] (q_1) at (T60.left corner) {$1$};
11+
\node[state,fill=yellow] (q_2) at (T60.apex) {$2$};
12+
\node[state,fill=green] (q_3) [right=1.5cm of q_2] {$3$};
13+
\path[->]
14+
(q_0) edge (q_1)
15+
(q_1) edge (q_2)
16+
(q_2) edge (q_0)
17+
(q_2) edge [bend left] (q_3)
18+
(q_3) edge [bend left] (q_2);
19+
\end{tikzpicture}

tex/figures/graph/graph_MS-BFS_2.tex

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
\begin{tikzpicture}[]
2+
% Apex angle 60 degrees
3+
\node[isosceles triangle,
4+
isosceles triangle apex angle=60,
5+
draw=none,fill=none,
6+
minimum size=2cm] (T60) at (3,0){};
7+
8+
9+
\node[state,fill=yellow] (q_0) at (T60.right corner) {$0$};
10+
\node[state] (q_1) at (T60.left corner) {$1$};
11+
\node[state,fill=green] (q_2) at (T60.apex) {$2$};
12+
\node[state,fill=yellow, draw=red, line width=0.45mm] (q_3) [right=1.5cm of q_2] {$3$};
13+
\path[->]
14+
(q_0) edge (q_1)
15+
(q_1) edge (q_2)
16+
(q_2) edge (q_0)
17+
(q_2) edge [bend left] (q_3)
18+
(q_3) edge [bend left] (q_2);
19+
\end{tikzpicture}

0 commit comments

Comments
 (0)