\documentclass[bachelor, och, coursework]{SCWorks} % параметр - тип обучения - одно из значений: % spec - специальность % bachelor - бакалавриат (по умолчанию) % master - магистратура % параметр - форма обучения - одно из значений: % och - очное (по умолчанию) % zaoch - заочное % параметр - тип работы - одно из значений: % referat - реферат % coursework - курсовая работа (по умолчанию) % diploma - дипломная работа % pract - отчет по практике % pract - отчет о научно-исследовательской работе % autoref - автореферат выпускной работы % assignment - задание на выпускную квалификационную работу % review - отзыв руководителя % critique - рецензия на выпускную работу % параметр - включение шрифта % times - включение шрифта Times New Roman (если установлен) % по умолчанию выключен \usepackage[T2A]{fontenc} \usepackage[cp1251]{inputenc} \usepackage{graphicx} \usepackage{minted} \usepackage{float} \usepackage[sort,compress]{cite} \usepackage{amsmath} \usepackage{amssymb} \usepackage{amsthm} \usepackage{fancyvrb} \usepackage{longtable} \usepackage{array} \usepackage[english,russian]{babel} \usepackage[colorlinks=true]{hyperref} \newcommand{\eqdef}{\stackrel {\rm def}{=}} \newtheorem{lem}{Лемма} \begin{document} % Кафедра (в родительном падеже) \chair{математической кибернетики и компьютерных наук} % Тема работы \title{Создание приложения для отрисовки графов и алгоритмов для работы с ними} % Курс \course{2} % Группа \group{211} % Факультет (в родительном падеже) (по умолчанию "факультета КНиИТ") %\department{факультета КНиИТ} % Специальность/направление код - наименование \napravlenie{02.03.02 "--- Фундаментальная информатика и информационные технологии} %\napravlenie{02.03.01 "--- Математическое обеспечение и администрирование информационных систем} %\napravlenie{09.03.01 "--- Информатика и вычислительная техника} %\napravlenie{09.03.04 "--- Программная инженерия} %\napravlenie{10.05.01 "--- Компьютерная безопасность} % Для студентки. Для работы студента следующая команда не нужна. %\studenttitle{Студентки} % Фамилия, имя, отчество в родительном падеже \author{Морозова Андрея Денисовича} % Заведующий кафедрой \chtitle{к.\,ф.-м.\,н., доцент} % степень, звание \chname{А.\,С.\,Иванов} %Научный руководитель (для реферата преподаватель проверяющий работу) \satitle{ст. преподаватель} %должность, степень, звание \saname{М.\,И.\,Сафрончик} % Семестр (только для практики, для остальных % типов работ не используется) \term{2} % Год выполнения отчета \date{2021} \maketitle % Включение нумерации рисунков, формул и таблиц по разделам % (по умолчанию - нумерация сквозная) % (допускается оба вида нумерации) %\secNumbering \tableofcontents % Раздел "Обозначения и сокращения". Может отсутствовать в работе %\abbreviations %\begin{description} % \item SQL "--- англ. structured query language — «язык структурированных запросов; % \item $\det B$ "--- определитель матрицы $B$; % \item ИНС "--- Искусственная нейронная сеть; % \item FANN "--- Feedforward Artifitial Neural Network %\end{description} % Раздел "Определения". Может отсутствовать в работе %\definitions % Раздел "Определения, обозначения и сокращения". Может отсутствовать в работе. % Если присутствует, то заменяет собой разделы "Обозначения и сокращения" и "Определения" %\defabbr % Раздел "Введение" \intro Целью настоящей работы является изучение работы фреймворка для кроссплатформенной разработки ''Flutter'' и разработка приложения для создания графов и взаимодействия с ними. Поставлены задачи: \begin{itemize} \item разбор алгоритмов на графах \item разбор работы с Flutter \item построение приложения \end{itemize} \section{Введение} \subsection{Графы} Граф --- математический объект, состоящий из двух множеств. Одно из них --- любое конечное множество, его элементы называются \textit{вершинами} графа. Другое множество состоит из пар вершин, эти пары называются \textit{ребрами} графа.~\cite{IITMMM_2017} \subsection{Основные определения} \textbf{Ориентированный граф} определяется как пара \textit{(V, E)}, где \textit{V} --- конечное множество, а \textit{E} --- бинарное отношение на \textit{V}, т.~е. подмножество множества ${V \times V}$. Ориентированный граф для краткости называют \textbf{орграфом}. Множество $V$ называют \textbf{множеством вершин графа}, а его элемент называют \textbf{вершиной} графа. Множество $E$ называют \textbf{множеством рёбер}, а его элементы называют \textbf{рёбрами}. Граф может содержать \textbf{рёбра-циклы}, соединяющие вершину с собой. На рисунке~\ref{fig:orgrapf_example} изображен ориентированный граф с множеством вершин \{0, 1, 2, 3, 4\}.~\citenum{Algo_2013} \begin{figure}[!ht] \centering \includegraphics[width=9cm]{./pic/orgraph.png} \caption{\label{fig:orgrapf_example} Пример орграфа} \end{figure} В \textbf{неориентированном} графе $G = (V, E)$ множество ребер состоит из \textbf{неупорядоченных} пар вершин: парами являются множества $\{u, v\}$, где $u, v \in V$ и $u \neq v$. Для неориентированного графа $\{u, v\}$ и $\{v, u\}$ обозначают одно и то же ребро. Неориентированный граф не может содержать рёбер-циклов, и каждое ребро состоит из двух различных вершин. На рисунке~\ref{fig:grapf_example} изображен неориентированный граф с множеством вершин \{0, 1, 2, 2, 4\} \begin{figure}[!ht] \centering \includegraphics[width=9cm]{./pic/graph.png} \caption{\label{fig:grapf_example} Пример неориентированного графа} \end{figure} Вершина \textit{v} \textbf{смежна} с вершиной \textit{u}, если в графе имеется ребро $\{u, v\}$. Для неориентированных графов отношение смежности является симметричным, но для ориентированных графов это не обязательно. \textbf{Степенью} вершины в неориентированном графе называется число инцидентных ей рёбер. Для ориентированного графа различают исходящую степень, определяемую как число выходящих из неё рёбер, и входящую степень, определяемую как число входящих в неё рёбер. Сумма исходящей и входящей степеней называется степенью вершины. \textbf{Маршрутом} в графе называется конечная чередующаяся последовательность смежных вершин и ребер, соединяющих эти вершины. Маршрут называется открытым, если его начальная и конечная вершины различны, в противном случае он называется замкнутым. Маршрут называется \textbf{цепью}, если все его ребра различны. Открытая цепь называется \textbf{путем}, если все ее вершины различны. Замкнутая цепь называется \textbf{циклом}, если различны все ее вершины, за исключением концевых. Граф называется \textbf{связным}, если для любой пары вершин существует соединяющий их путь.~\cite{intuit} \subsection{Представление графа} Граф можно описать несколькими способами. \begin{enumerate} \item Перечисление элементов:~\ref{ref:list}. \item Матрица смежности:~\ref{ref:smej}. \item Матрица инцидентности:~\ref{ref:incident}. \item Список смежности:~\ref{ref:spisok}. \end{enumerate} Рассмотрим на примере графа на рисунке~\ref{fig:graph_prim1}. \begin{figure} \centering \includegraphics[width=9cm]{./pic/prim1.png} \caption{\label{fig:graph_prim1} Рассматриваемый граф} \end{figure} \subsubsection{Перечисление элементов}\label{ref:list} Исходя из определения, для того, чтобы задать граф, достаточно перечислить его вершины и ребра (т.е. пары вершин). Пример: $$ V = \{a, b, c, d, e\} $$ $$ E = \{(a, b), (a, c), (a, e), (b, c), (b, d), (c, e), (d, e)\}$$ \subsubsection{Матрица смежности}\label{ref:smej} Пусть $G$ --- граф с $n$ вершинами, пронумерованными числами от 1 до $n$. \textbf{Матрица смежности} --- это таблица с $n$ строками и $n$ столбцами, в которой элемент, стоящий на пересечении строки с номером $i$ и столбца с номером $j$, равен 1, если вершины с номерами $i$ и $j$ смежны, и 0 в противоположном случае. \begin{table}[!ht] %\centering \caption{Пример матрицы смежности} \begin{tabular}{|l|c|c|c|c|} \hline 0 & 1 & 1 & 0 & 1\\ \hline 1 & 0 & 1 & 1 & 0\\ \hline 1 & 1 & 0 & 0 & 1\\ \hline 0 & 1 & 0 & 0 & 1\\ \hline 1 & 0 & 1 & 1 & 0\\ \hline \end{tabular} \end{table} \subsubsection{Матрица инцидентности}\label{ref:incident} Пусть $G$ --- граф с вершинами, пронумерованными числами от 1 до $n$, и ребрами, пронумерованными от 1 до $m$. В матрице инцидентности строки соответствуют вершинам, а столбцы рёбрам. На пересечении строки с номером $i$ и столбца с номером $j$ стоит 1, если вершина с номером $i$ инцидентна ребру с номером $j$, и 0 в противном случае. \begin{table}[!ht] %\centering \caption{Пример матрицы инцидентности} \begin{tabular}{|c|c|c|c|c|c|c|} \hline 1 & 1 & 1 & 0 & 0 & 0 & 0\\ \hline 1 & 0 & 0 & 1 & 1 & 0 & 0\\ \hline 0 & 1 & 0 & 1 & 0 & 1 & 0\\ \hline 0 & 0 & 0 & 0 & 1 & 0 & 1\\ \hline 0 & 0 & 1 & 0 & 0 & 1 & 1\\ \hline \end{tabular} \end{table} \subsubsection{Списки смежности}\label{ref:spisok} Списки смежности часто используются для компьютерного представления графов. Для каждой вершины задается список всех смежных с ней вершин. В структурах данных, применяемых в программировании, списки смежности могут быть реализованы как массив линейных списков. Пример: \begin{itemize} \item[1] : 2, 3, 5 \item[2] : 1, 3, 4 \item[3] : 1, 2, 5 \item[4] : 2, 5 \item[5] : 1, 3, 4 \end{itemize} \subsection{Алгоритмы} \subsubsection{Обход в ширину} Поиск в ширину (обход в ширину, breadth-first search) --- один из основных алгоритмов на графах. Пусть задан граф $G = (V, E)$ и выделена исходная вершина $s$. Алгоритм поиска в ширину систематически обходит все ребра $G$ для «открытия» всех вершин, достижимых из $s$, вычисляя минимальное количество рёбер от $s$ s до каждой достижимой из $s$ вершины. Поиск в ширину имеет такое название потому, что в процессе обхода мы идём вширь, то есть перед тем как приступить к поиску вершин на расстоянии $k + 1$, выполняется обход вершин на расстоянии $k$~\cite{Algo_2013}. Приведенная ниже процедура поиска в ширину BFS предполагает, что входной граф $G = (V, E)$ представлен при помощи списков смежности. Псевдокод: \inputminted[fontsize=\footnotesize, linenos]{python}{./dart/pseudoBFS.txt} Воспользуемся групповым анализом. Операции внесения в очередь и удаление из нее требует $O(1)$ времени. Следовательно на очередь потребуется $O(V)$ времени. Т.к. максимальная длина списков смежности $\theta(E)$, то время, необходимое для сканирования списков, равно $O(E)$. Расходы на инициализацию: $O(V)$. Таким образом, общее время работы алгоритма: $O(V + E)$. Время поиска в ширину линейно зависит от размера представления графа. \subsubsection{Обход в глубину} \inputminted[fontsize=\footnotesize, linenos]{python}{./dart/pseudoDFS.txt} \section{Инструменты} Рассмотрим используемый язык и библиотеку для отрисовки. \subsection{Dart} В качестве основы используется язык \textbf{Dart}, разработанный компанией Google, и широко используемый для кросс-платформенной разработки~\cite{dart_web}. Dart позиционируется в качестве замены/альтернативы JavaScript. Один из разработчиков языка Марк Миллер (Mark S. Miller) написал, что JavaScript «имеет фундаментальные изъяны»\cite{futureOfJavascript} («Javascript has fundamental flaws…»), которые невозможно исправить. Версия 1.0 вышла в 14 ноября 2013 года. Вторая версия была выпущена в августе 2018 года. В языке появилась надежная система типов, т.~е. во время выполнении программы все переменные будут гарантированно указанному типу~\cite{dart_sound}. Пример HelloWorld на Dart: \inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/helloWorld.dart} Dart поддерживает сокращенную запись. Код примера HelloWorld можно записать так: \inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/hW.dart} Концепты языка~\cite{dart_tour}: \begin{itemize} \item Все, что можно поместить в переменную, является объектом, а каждый объект является частью класса; \item Dart -- язык со строгой типизацией, но объявления типов опциональны, т.к. поддерживается определение типа при компиляции; \item В версии языка 2.12 появилась Null безопасность. Каждый объект не может быть Null, если не указано обратное; \item поддерживаются дженерики; \item для объявления локальных функций и переменных необходимо начать имя со знака ''\_'' \end{itemize} . \subsection{Flutter} Для отрисовки информации используется фреймворк c открытым исходным кодом ''Flutter'', разработанный компанией Google. Flutter не использует нативные компоненты для отрисовки интерфейса. В его основе лежит графический движок ''Skia'', написанный преимущественно на С++. Skia --- библиотека для работы с 2D графикой с открытым исходным кодом, поддерживающая работу на большом количестве платформ~\cite{skia_docs} Первая версия выпущена в 2015 году под названием ''Sky'', работала только для Android-приложений. Основная заявленная особенность --- высокая графическая производительность (возможность отображения 120 кадров в секунду). Полная поддержка создания веб-приложений появилась в версии 2.0 (март 2021 года), также разрабатывается поддержка создания настольных приложений для Windows, macOS и Linux и Google Fuchsia. Простейший пример приложения с использованием Flutter: \inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/flutter.dart} \begin{figure}[!ht] \centering \includegraphics[width=11cm]{./pic/flutter0.png} \caption{\label{fig:flutter_example} Простейшее приложение на Flutter} \end{figure} \section{Реализация} \subsection{Графы} \subsubsection{Класс для вершины} \subsubsection{Класс для графа} \subsubsection{Алгоритмы} \subsubsection{Кнопки} \subsubsection{Отрисовка графа} \section{Таблица} \subsection{Текст с таблицей} \begin{table}[!ht] \small \caption{Результат сокращения словарей неисправностей при помощи масок} \label{table-1} \begin{tabular}{|l|c|c|c|c|r|r|r|} \hline 1 & 2& 3& 4& 5& 6& 7& 8\\ \hline S298 & 177 & 1932 & 341964 & 61 & 10797 & 3,16\% & 0,61\\ \hline S344 & 240 & 1397 & 335280 & 59 & 14160 & 4,22\% & 0,53\\ \hline S349 & 243 & 1474 & 358182 & 62 & 15066 & 4,21\% & 0,60\\ \hline S382 & 190 & 12444 & 2364360 & 55 & 10450 & 0,44\% & 3,78\\ \hline S386 & 274 & 2002 & 548548 & 91 & 24934 & 4,55\% & 1,40\\ \hline S400 & 194 & 13284 & 2577096 & 58 & 11252 & 0,44\% & 4,28\\ \hline S444 & 191 & 13440 & 2567040 & 60 & 11460 & 0,45\% & 4,26\\ \hline S510 & 446 & 700 & 312200 & 70 & 31220 & 10,00\% & 0,63\\ \hline S526 & 138 & 13548 & 1869624 & 38 & 5244 & 0,28\% & 2,41\\ \hline S641 & 345 & 5016 & 1730520 & 132 & 45540 & 2,63\% & 7,06\\ \hline S713 & 343 & 3979 & 1364797 & 131 & 44933 & 3,29\% & 5,61\\ \hline S820 & 712 & 21185 & 15083720 & 244 & 173728 & 1,15\% & 126,99\\ \hline S832 & 719 & 21603 & 15532557 & 253 & 181907 & 1,17\% & 135,18\\ \hline S953 & 326 & 322 & 104972 & 91 & 29666 & 28,26\% & 0,27\\ \hline S1423 & 293 & 750 & 219750 & 93 & 27249 & 12,40\% & 0,57\\ \hline S1488 & 1359 & 22230 & 30210570 & 384 & 521856 & 1,73\% & 541,69\\ \hline \end{tabular} \end{table} % Раздел "Заключение" \conclusion Было разработано простое приложение для создания и работы с графами с использованием Dart и Flutter. В приложении возможно: \begin{itemize} \item создать пустой граф; \item добавить вершину; \item удалить вершину; \item добавить/изменить путь; \item удалить путь; \item сохранить граф; \item загрузить граф; \item построить минимальное остовное дерево с помощью алгоритма Крускала; \item найти минимальный путь из выбранной вершины в другие с помощью алгоритма Дейкстры; \item проверить доступность вершин с помощью обхода в глубину; \item построить путь из одной вершины в другую с помощью обхода в ширину. \end{itemize} %Библиографический список, составленный вручную, без использования BibTeX % %\begin{thebibliography}{99} % \bibitem{Ione} Источник 1. % \bibitem{Itwo} Источник 2 %\end{thebibliography} %Библиографический список, составленный с помощью BibTeX % \bibliographystyle{gost780uv} \bibliography{thesis} % Окончание основного документа и начало приложений % Каждая последующая секция документа будет являться приложением \appendix \section{Код main.dart}\label{mainD} Точка входа в программу. \inputminted[fontsize=\footnotesize, linenos]{dart}{./lib/main.dart} \section{Код страницы отрисовки}\label{buttons} Описание интерфейса и базовые функции для взаимодействия с информацией. \inputminted[fontsize=\footnotesize, linenos]{dart}{./lib/pages/drawing_page.dart} \section{Код отрисовки графа}\label{painter} Вывод на экран информации из графа. \inputminted[fontsize=\footnotesize, linenos]{dart}{./lib/src/curve_painter.dart} \section{Код класса для работы с графом}\label{graph} Основной класс для хранения и взаимодействия с информацией. \inputminted[fontsize=\footnotesize, linenos]{dart}{./lib/src/graph.dart} \noindent \end{document}