393 lines
16 KiB
TeX
393 lines
16 KiB
TeX
\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}
|