Skip to content

Commit 3823932

Browse files
committed
Первый вариант обходов в ширину в терминах линейной алгебры готов.
1 parent 8a72c93 commit 3823932

File tree

1 file changed

+93
-8
lines changed

1 file changed

+93
-8
lines changed

tex/GraphTheoryIntro.tex

Lines changed: 93 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,25 @@ \section{Обход графа в ширину}
473473
\end{pmatrix}.
474474
\end{align*}
475475

476-
Состояние графа после первой итерации показано на рисунке~\ref{fig:bfs_step_1}.
476+
Состояние графа после первой итерации показано на рисунке~\ref{fig:bfs_step_1}: вершина \circled{2} --- изначальное состояние фронта, а вершины \circled{1} и \circled{3} достижимы из него за один шаг.
477477

478478
На втором шаге из текущего фронта мы можем попасть в вершины \circled{1} и \circled{2}.
479+
Сначала обновим информацию о посещённых вершинах.
480+
481+
\begin{align*}
482+
\emph{visited} & =
483+
\begin{pmatrix}
484+
0 & 0 & 1 & 0
485+
\end{pmatrix}\oplus^\BbbB
486+
\begin{pmatrix}
487+
1 & 0 & 0 & 1
488+
\end{pmatrix} &=
489+
\begin{pmatrix}
490+
1 & 0 & 1 & 1
491+
\end{pmatrix}
492+
\end{align*}
493+
494+
Затем вычислим новый фронт.
479495

480496
\begin{align*}
481497
\emph{new\_front} & =
@@ -501,7 +517,7 @@ \section{Обход графа в ширину}
501517
0 & 1 & 1 & 0
502518
\end{pmatrix} \oplus^\BbbM
503519
\begin{pmatrix}
504-
0 & 0 & 1 & 0
520+
1 & 0 & 1 & 1
505521
\end{pmatrix} \\ &=
506522
\begin{pmatrix}
507523
0 & 1 & 0 & 0
@@ -562,7 +578,8 @@ \section{Обход графа в ширину}
562578
Идея его такая же, как у рассмотренного выше, однако фронт~--- это уже не вектор, а матрица размера $k \times |V|$, где $k$~--- количество стартовых вершин, каждая строка которой является фронтом для одной из стартовых вершин\sidenote{
563579
Такакя конструкция действительно является лишь естественным для алгоритмов, выреженных в терминах операций линейной алгебры, способом запустить несколько независимых обходов параллельно.
564580
}.
565-
581+
Псевдокод такой вариации представлен на листинге~\ref{algo:MS-BFS_linal}.
582+
Можно заметить, что алгоритм отличается от обхода с одной стартовой вершиной только инициализацией данных.
566583

567584
\begin{algorithm}
568585
\SetAlgoLined
@@ -571,7 +588,7 @@ \section{Обход графа в ширину}
571588
\KwResult{Матрица, $i$-я строка которой указывает, какие вершины достижимы из $K[i]$}
572589
$\emph{current\_front} \leftarrow \Bbbzero^{k \times n}$\;
573590
$\emph{visited} \leftarrow \Bbbzero^{k \times n}$\;
574-
$\emph{current\_front}[k] \leftarrow 1$\;
591+
\For{$i \in 0\ldots |K|-1$}{$\emph{current\_front}[i,K[i]] \leftarrow 1$\;}
575592
\While{\emph{current\_front} $\neq \ \overline{0}$}{
576593
$\emph{visited} \leftarrow \emph{visited} \oplus^\BbbB \emph{current\_front}$ \tcp*{Записываем вершины из фронта в посещённые}
577594
$\emph{new\_front} \leftarrow \emph{current\_front} \mmult{\BbbB} M$ \tcp*{Вычисляем вершины, достижимые за один шаг из текущего фронта}
@@ -584,12 +601,13 @@ \section{Обход графа в ширину}
584601

585602
\begin{example}
586603
Рассмотрим обход в ширину графа из примера~\ref{example:diGraph} начиная с вершин \circled{1} и \circled{3}.
604+
Будем использовать ту же цветовую схему, что и в предыдущем примере.
587605

588-
В данном случае вспомогательные структуры инициализируются матрицами.
606+
В данном случае вспомогательные структуры инициализируются следующими матрицами.
589607
\begin{align*}
590608
\emph{current\_front} & =
591609
\begin{pmatrix}
592-
1 & 0 & 0 & 0 \\
610+
0 & 1 & 0 & 0 \\
593611
0 & 0 & 0 & 1
594612
\end{pmatrix}
595613
\\
@@ -600,6 +618,28 @@ \section{Обход графа в ширину}
600618
\end{pmatrix}.
601619
\end{align*}
602620

621+
Далее будут выполняться известные уже шаги.
622+
Проследим изменения фронта.
623+
624+
\begin{align*}
625+
\emph{new\_front} & = \emph{current\_front} \mmult{\BbbB} M \\
626+
&=
627+
\begin{pmatrix}
628+
0 & 1 & 0 & 0 \\
629+
0 & 0 & 0 & 1
630+
\end{pmatrix} \mmult{\BbbB}
631+
\begin{pmatrix}
632+
0 & 1 & 0 & 0 \\
633+
0 & 0 & 1 & 0 \\
634+
1 & 0 & 0 & 1 \\
635+
0 & 0 & 1 & 0
636+
\end{pmatrix} \\ &=
637+
\begin{pmatrix}
638+
0 & 0 & 1 & 0 \\
639+
0 & 0 & 1 & 0
640+
\end{pmatrix}.
641+
\end{align*}
642+
603643
\begin{marginfigure}
604644
\begin{center}
605645
\resizebox{\marginparwidth}{!}{\input{figures/graph/graph_MS-BFS_1.tex}}
@@ -608,7 +648,8 @@ \section{Обход графа в ширину}
608648
\label{fig:ms_bfs_step_1}
609649
\end{marginfigure}
610650

611-
Шаг 1~\ref{fig:ms_bfs_step_1}
651+
Первый шаг представлен на изображении~\ref{fig:ms_bfs_step_1}: из двух стартовых вершин мы можем попасть в вершину \circled{2}.
652+
Можно заметить, что фронт хранит информацию о том, что \circled{2} достижима и из вершины \circled{1}, и из вершины \circled{1}.
612653

613654
\begin{marginfigure}
614655
\begin{center}
@@ -618,10 +659,54 @@ \section{Обход графа в ширину}
618659
\label{fig:ms_bfs_step_2}
619660
\end{marginfigure}
620661

621-
Шаг 2~\ref{fig:ms_bfs_step_2}
662+
Проделаем ещё один шаг.
663+
Он будет последим содержательным шагом: на следующем шаге мы всего лишь узнаем, что все вершины посещены.
664+
\begin{align*}
665+
\emph{new\_front} & = \emph{current\_front} \mmult{\BbbB} M \\
666+
& =
667+
\begin{pmatrix}
668+
0 & 0 & 1 & 0 \\
669+
0 & 0 & 1 & 0
670+
\end{pmatrix} \mmult{\BbbB}
671+
\begin{pmatrix}
672+
0 & 1 & 0 & 0 \\
673+
0 & 0 & 1 & 0 \\
674+
1 & 0 & 0 & 1 \\
675+
0 & 0 & 1 & 0
676+
\end{pmatrix} \\ &=
677+
\begin{pmatrix}
678+
1 & 0 & 0 & 1 \\
679+
1 & 0 & 0 & 1
680+
\end{pmatrix}.
681+
\end{align*}
682+
683+
684+
685+
Результат шага представлен на рисунке~\ref{fig:ms_bfs_step_2}.
686+
Здесь важно обратить внимание на вершину \circled{3}: она буде повторно посещённой для стартовой вершины \circled{3}, но для вершины \circled{1} мы пришли в неё впервые.
687+
Потому фронт для следующей итерации будет выглядеть следующим образом.
688+
689+
\begin{align*}
690+
\emph{current\_front} & = \emph{new\_front} \oplus^\BbbM \emph{visited} \\
691+
&=
692+
\begin{pmatrix}
693+
1 & 0 & 0 & 1 \\
694+
1 & 0 & 0 & 1
695+
\end{pmatrix} \oplus^\BbbM
696+
\begin{pmatrix}
697+
0 & 1 & 1 & 0 \\
698+
0 & 0 & 1 & 1
699+
\end{pmatrix} \\ &=
700+
\begin{pmatrix}
701+
1 & 0 & 0 & 1 \\
702+
1 & 0 & 0 & 0
703+
\end{pmatrix}.
704+
\end{align*}
622705

623706
\end{example}
624707

708+
Идеи, заложенные в описанных выше алгоритмах, будут использоваться нами далее, при решении других задач.
709+
625710
\section{Задачи поиска путей}
626711

627712
Одна из классических задач анализа графов~--- это задача поиска путей между вершинами с различными ограничениями.

0 commit comments

Comments
 (0)