final1
This commit is contained in:
parent
682c4df7bd
commit
5175d15194
|
@ -0,0 +1,52 @@
|
|||
List<int>? bfsPath(int startDot, int goalDot) {
|
||||
if (startDot == goalDot) return [startDot];
|
||||
startDot--;
|
||||
goalDot--;
|
||||
List<List<int>>? graph = getLenTable();
|
||||
List<bool> used = <bool>[];
|
||||
List<int> dst = <int>[];
|
||||
List<int> pr = <int>[];
|
||||
|
||||
for (int i = 0; i < _amount; i++) {
|
||||
dst.add(-1);
|
||||
used.add(false);
|
||||
pr.add(0);
|
||||
}
|
||||
|
||||
List<int> q = <int>[];
|
||||
q.add(startDot);
|
||||
used[startDot] = true;
|
||||
dst[startDot] = 0;
|
||||
pr[startDot] = -1; //ó âåðøèíû íåò ïðåäûäóùåé.
|
||||
|
||||
while (q.isNotEmpty) {
|
||||
int cur = q.removeAt(0);
|
||||
int x = 0;
|
||||
for (int neighbor in graph![cur]) {
|
||||
if (neighbor != -1) {
|
||||
if (!used[x]) {
|
||||
q.add(x);
|
||||
used[x] = true;
|
||||
dst[x] = dst[cur] + 1;
|
||||
pr[x] = cur; //ñîõðàíåíèå ïðåäûäóùåé âåðøèíû
|
||||
}
|
||||
}
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
//Âîññòàíîâëåíèå êðàò÷àéøèåãî ïóòüè
|
||||
List<int> path = <int>[];
|
||||
int cur = goalDot;
|
||||
path.add(cur + 1);
|
||||
while (pr[cur] != -1) {
|
||||
cur = pr[cur];
|
||||
path.add(cur + 1);
|
||||
}
|
||||
|
||||
path = path.reversed.toList();
|
||||
if (path[0] == (startDot + 1) &&
|
||||
path[1] == (goalDot + 1) &&
|
||||
!_dots[startDot].hasConnection(goalDot + 1)) return null;
|
||||
return path;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
List<bool>? dfsIterative(int v) {
|
||||
v--;
|
||||
List<bool> label = <bool>[];
|
||||
for (int i = 0; i < _amount; i++) {
|
||||
label.add(false);
|
||||
}
|
||||
List<int> stack = <int>[];
|
||||
stack.add(v);
|
||||
while (stack.isNotEmpty) {
|
||||
v = stack.removeLast();
|
||||
if (!label[v]) {
|
||||
label[v] = true;
|
||||
for (int i in _dots[v].getL().keys) {
|
||||
stack.add(i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return label;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
List<int?> dijkstra(int from) {
|
||||
List<int?> d = List<int?>.filled(_amount, intMax);
|
||||
List<int> p = List<int>.filled(_amount, -1);
|
||||
|
||||
d[from - 1] = 0;
|
||||
List<bool> u = List<bool>.filled(_amount, false);
|
||||
for (int i = 0; i < _amount; ++i) {
|
||||
int v = -1;
|
||||
for (int j = 0; j < _amount; ++j) {
|
||||
if (!u[j] && (v == -1 || d[j]! < d[v]!)) {
|
||||
v = j;
|
||||
}
|
||||
}
|
||||
if (d[v] == intMax) break;
|
||||
u[v] = true;
|
||||
for (int to in _dots[v].getL().keys) {
|
||||
int len = _dots[v].getL()[to]!;
|
||||
if (!_useLength && len == 0) len = 1;
|
||||
if (d[v]! + len < d[to - 1]!) {
|
||||
d[to - 1] = d[v]! + len;
|
||||
p[to - 1] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < d.length; i++) {
|
||||
if (d[i] == intMax) d[i] = null;
|
||||
}
|
||||
return d;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
class Dot {
|
||||
//Data
|
||||
String _name = "";
|
||||
int num = -1;
|
||||
Map<int, int> _ln = <int, int>{};
|
||||
***
|
|
@ -0,0 +1,24 @@
|
|||
Dot([String name = "Undefined", int n = -1]) {
|
||||
_name = name;
|
||||
num = n;
|
||||
_ln = <int, int>{};
|
||||
}
|
||||
Dot.fromTwoLists(String name, List<int> num0, List<int> length,
|
||||
[int n = -1]) {
|
||||
_name = name;
|
||||
num = n;
|
||||
Map<int, int> nw = <int, int>{};
|
||||
if (num0.length != length.length) {
|
||||
print("Error in lists");
|
||||
} else {
|
||||
for (var i = 0; i < num0.length; i++) {
|
||||
nw[num0[i]] = length[i];
|
||||
_ln = nw;
|
||||
}
|
||||
}
|
||||
}
|
||||
Dot.fromMap(String name, Map<int, int> l, [int n = -1]) {
|
||||
_name = name;
|
||||
num = n;
|
||||
_ln = l;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
void setName(String n) => _name = n;
|
||||
|
||||
void addPath(int inp, int length) => _ln[inp] = length;
|
||||
|
||||
void delPath(int n) => _ln.removeWhere((key, value) => key == n);
|
|
@ -0,0 +1,6 @@
|
|||
String _name = "Undefined"; //Èìÿ
|
||||
int _amount = 0; //Êîëè÷åñòâî âåðøèí
|
||||
List<Dot> _dots = <Dot>[]; //Ñïèñîê ñìåæíîñòè âåðøèí
|
||||
Map<int, String> _nameTable = <int, String>{}; //Ñïèñîê âåðøèí ïî èìåíàì
|
||||
bool _useLength = false; //Âçâåøåííîñòü
|
||||
bool _oriented = false; //Îðèåíòèðîâàííîñòü
|
|
@ -0,0 +1,28 @@
|
|||
Graphs? kruskal() {
|
||||
List<LenDotPath> g = getSortedPathList();
|
||||
//int cost = 0;
|
||||
List<Dot> res = <Dot>[];
|
||||
for (int i = 0; i < _amount; i++) {
|
||||
res.add(Dot(_dots[i].getName(), _dots[i].num));
|
||||
}
|
||||
List<int> treeId = List<int>.filled(_amount, 0);
|
||||
for (int i = 0; i < _amount; ++i) {
|
||||
treeId[i] = i;
|
||||
}
|
||||
for (int i = 0; i < g.length; ++i) {
|
||||
int a = g[i].d - 1, b = g[i].p - 1;
|
||||
int l = g[i].l;
|
||||
if (treeId[a] != treeId[b]) {
|
||||
//cost += l;
|
||||
res[a].addPath(b + 1, l);
|
||||
int oldId = treeId[b], newId = treeId[a];
|
||||
for (int j = 0; j < _amount; ++j) {
|
||||
if (treeId[j] == oldId) {
|
||||
treeId[j] = newId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_dots = res;
|
||||
return Graphs.fromList(_name, res, _useLength, _oriented);
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
screenSize = MediaQuery.of(context).size.width;
|
||||
_textGrNmController.text = graphData.getName();
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text("Graph name:\n",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
color: Colors.white,
|
||||
))),
|
||||
toolbarHeight: 110,
|
||||
flexibleSpace: Container(
|
||||
color: Colors.green.shade900,
|
||||
child: Column(children: <Widget>[
|
||||
/*
|
||||
Îïèñàíèå ýëåìåíòîâ íà ïàíåëå ïðèëîæåíèÿ
|
||||
*/
|
||||
]),
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
clearDropDownVals();
|
||||
graphData.flushData();
|
||||
clearInputData();
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.delete_sweep),
|
||||
iconSize: 60,
|
||||
),
|
||||
]),
|
||||
body: CustomPaint(
|
||||
painter: CurvePainter(
|
||||
graphData: graphData,
|
||||
intListPath: intListPath,
|
||||
dfsAccessTable: dfsAccessTable,
|
||||
start: startDot,
|
||||
end: endDot,
|
||||
op: op),
|
||||
child: Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: ButtonBar(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
/*
|
||||
Îïèñàíèå êíîïîê äåéñòâèÿ
|
||||
*/
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
ElevatedButton createButton(String txt, void Function() onPressing) {
|
||||
return ElevatedButton(
|
||||
onPressed: onPressing,
|
||||
style: ButtonStyle(
|
||||
backgroundColor: MaterialStateProperty.resolveWith<Color>(
|
||||
(states) => Colors.green.shade700)),
|
||||
child: Text(txt,
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
color: Colors.white70,
|
||||
height: 1,
|
||||
)),
|
||||
);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
void _drawHArrow(Canvas canvas, Size size, Offset from, Offset to, [bool doubleSided = false]) {
|
||||
Path path;
|
||||
|
||||
// The arrows usually looks better with rounded caps.
|
||||
Paint paint = ... // çàäàåòñÿ ñòèëü
|
||||
|
||||
var length = sqrt((to.dx - from.dx) * (to.dx - from.dx) +
|
||||
(to.dy - from.dy) * (to.dy - from.dy));
|
||||
|
||||
path = Path();
|
||||
path.moveTo(from.dx, from.dy);
|
||||
path.relativeCubicTo(
|
||||
0,
|
||||
0,
|
||||
-(from.dx + to.dx + length) / (length) - 40,
|
||||
-(from.dy + to.dy + length) / (length) - 40,
|
||||
to.dx - from.dx,
|
||||
to.dy - from.dy);
|
||||
path =
|
||||
ArrowPath.make(path: path, isDoubleSided: doubleSided, tipLength: 16);
|
||||
canvas.drawPath(path, paint);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
CurvePainter({
|
||||
Key? key,
|
||||
required this.graphData,
|
||||
required this.intListPath,
|
||||
required this.dfsAccessTable,
|
||||
required this.start,
|
||||
required this.end,
|
||||
required this.op,
|
||||
});
|
|
@ -0,0 +1,24 @@
|
|||
Map<int, Offset> _getDotPos(int dotsAm, Size size) {
|
||||
Map<int, Offset> off = <int, Offset>{};
|
||||
var width = size.width / 2;
|
||||
var height = size.height / 2;
|
||||
int add = 0;
|
||||
int h = _getHighInputConnections();
|
||||
for (int i = 0; i < dotsAm; i++) {
|
||||
if ((i + 1) != h) {
|
||||
double x =
|
||||
cos(2 * pi * (i - add) / (dotsAm - add)) * _circleRad + width;
|
||||
double y =
|
||||
sin(2 * pi * (i - add) / (dotsAm - add)) * _circleRad + height;
|
||||
|
||||
off[i + 1] = Offset(x, y);
|
||||
} else if ((i + 1) == h) {
|
||||
off[i + 1] = Offset(width + 2, height - 2);
|
||||
add = 1;
|
||||
h = 0;
|
||||
} else {
|
||||
print("GetDotPos error");
|
||||
}
|
||||
}
|
||||
return off;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
dijkstra (G, w, s):
|
||||
source(G,s)
|
||||
S <- null
|
||||
Q <- V[G]
|
||||
while Q!=null:
|
||||
u <- Extract_min(Q)
|
||||
s <- S + u
|
||||
äë˙ ęŕćäîé âĺđřčíű v čç Adj[u]:
|
||||
relax(u, v, w)
|
|
@ -0,0 +1,10 @@
|
|||
kruscal(G, w):
|
||||
A <- null
|
||||
for v èç V[G]:
|
||||
create_set(v)
|
||||
sort(E)
|
||||
for (u, v) èç E:
|
||||
if find_set(u) != find_set(v):
|
||||
A <- A + {(u,v)}
|
||||
|
||||
return A
|
|
@ -245,35 +245,49 @@ $$ E = \{(a, b), (a, c), (a, e), (b, c), (b, d), (c, e), (d, e)\}$$
|
|||
|
||||
Поиск в ширину имеет такое название потому, что в процессе обхода мы идём вширь, то есть перед тем как приступить к поиску вершин на расстоянии $k + 1$, выполняется обход вершин на расстоянии $k$~\cite{Algo_2013}.
|
||||
|
||||
Приведенная ниже процедура поиска в ширину BFS предполагает, что входной граф $G = (V, E)$ представлен при помощи списков смежности. Псевдокод:
|
||||
Приведенная ниже процедура поиска в ширину 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{Обход в глубину}
|
||||
Стратегия обхода в ширину состоит в том, чтобы идти ''вглубь'' графа. Сначала исследуются ребра, выходящие из вершины, открытой последней, и покидаем вершину, когда не остается неисследованных ребер --- при этом происходит возврат в вершину, из которой была открыта вершина $v$. Процесс продолжается, пока не будут открыты все вершины, достижимые из исходной.
|
||||
|
||||
|
||||
|
||||
|
||||
Псевдо код алгоритма:
|
||||
\inputminted[fontsize=\footnotesize, linenos]{python}{./dart/pseudoDFS.txt}
|
||||
|
||||
\subsubsection{Алгоритм Дейкстры}
|
||||
Алгоритм был предложен голландским исследователем Эдсгером Дейкстрой в 1959 году. Используется для поиска кратчайшего пути от одной вершины до всех остальных. Используется только если вес ребер неотрицательный.
|
||||
В алгоритме поддерживается множество вершин $U$, для которых уже вычислены длины кратчайших путей до них из $s$. На каждой итерации основного цикла выбирается вершина, которой на текущий момент соответствует минимальная оценка кратчайшего пути. Вершина $u$ добавляется в множество $U$ и производится релаксация всех исходящих из неё рёбер.
|
||||
|
||||
Псевдокод алгоритма:
|
||||
\inputminted[fontsize=\footnotesize, linenos]{python}{./dart/pseudoDijkstra.txt}
|
||||
|
||||
\subsubsection{Алгоритм Краскала}
|
||||
Алгоритм Краскала — алгоритм поиска минимального остовного дерева во взвешенном неориентированном связном графе. Был описан Джозефом Краскалом в 1956 году.
|
||||
|
||||
Алгоритм Крускала изначально помещает каждую вершину в своё дерево, а затем постепенно объединяет эти деревья, объединяя на каждой итерации два некоторых дерева некоторым ребром. Перед началом выполнения алгоритма, все рёбра сортируются по весу (в порядке неубывания). Затем начинается процесс объединения: перебираются все рёбра от первого до последнего (в порядке сортировки), и если у текущего ребра его концы принадлежат разным поддеревьям, то эти поддеревья объединяются, а ребро добавляется к ответу. По окончании перебора всех рёбер, все вершины окажутся принадлежащими одному поддереву.\cite{krusc}
|
||||
|
||||
\inputminted[fontsize=\footnotesize, linenos]{python}{./dart/pseudoKruscal.txt}
|
||||
|
||||
\section{Инструменты}
|
||||
Рассмотрим используемый язык и библиотеку для отрисовки.
|
||||
\subsection{Dart}
|
||||
В качестве основы используется язык \textbf{Dart}, разработанный компанией Google, и широко используемый для кросс-платформенной разработки~\cite{dart_web}.
|
||||
|
||||
Dart позиционируется в качестве замены/альтернативы JavaScript. Один из разработчиков языка Марк Миллер (Mark S. Miller) написал, что JavaScript «имеет фундаментальные изъяны»\cite{futureOfJavascript} («Javascript has fundamental flaws…»), которые невозможно исправить.
|
||||
Dart позиционируется в качестве замены/альтернативы JavaScript. Один из разработчиков языка Марк Миллер (Mark S. Miller) писал, что JavaScript «имеет фундаментальные изъяны»\cite{futureOfJavascript}, которые невозможно исправить.
|
||||
|
||||
Версия 1.0 вышла в 14 ноября 2013 года.
|
||||
Вторая версия была выпущена в августе 2018 года. В языке появилась надежная система типов, т.~е. во время выполнении программы все переменные будут гарантированно указанному типу~\cite{dart_sound}.
|
||||
|
||||
В Dart используется сборщик мусора. Синтаксис похож на языки: JavaScript, C\#, Java~\cite{dartInAction}.
|
||||
|
||||
Пример 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 Все, что можно поместить в переменную, является объектом, а каждый объект является частью класса;
|
||||
|
@ -283,7 +297,6 @@ Dart
|
|||
\item для объявления локальных функций и переменных необходимо начать имя со знака ''\_''
|
||||
\end{itemize}
|
||||
.
|
||||
|
||||
\subsection{Flutter}
|
||||
Для отрисовки информации используется фреймворк c открытым исходным кодом ''Flutter'', разработанный компанией Google.
|
||||
Flutter не использует нативные компоненты для отрисовки интерфейса. В его основе лежит графический движок ''Skia'', написанный преимущественно на С++.
|
||||
|
@ -299,48 +312,139 @@ Skia ---
|
|||
\caption{\label{fig:flutter_example}
|
||||
Простейшее приложение на Flutter}
|
||||
\end{figure}
|
||||
Интерфейс описывается с помощью виджетов.
|
||||
\section{Реализация}
|
||||
Структура программы разбита на 4 файла:
|
||||
|
||||
\begin{itemize}
|
||||
\item main.dart --- точка входа в программу;
|
||||
\item drawing\_page.dart --- страница с описанием работы кнопок;
|
||||
\item curve\_painter.dart --- функционал для отрисовки графа;
|
||||
\item graph.dart --- класс для хранения графа и манипуляции с ним.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Графы}
|
||||
\subsubsection{Класс для вершины}
|
||||
\subsubsection{Класс для графа}
|
||||
Информация хранится в виде списков смежности.
|
||||
Полный код можно посмотреть в приложении~\ref{graph}.
|
||||
\subsubsection{Класс для хранения вершины}
|
||||
Класс \textbf{Dot} используется для хранения информации о ребрах, исходящих из данной вершины.
|
||||
|
||||
Основная информация:
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/graph/dot.dart}
|
||||
\textit{String \_name} используется для хранения имени, \textit{int num} используется для хранения номера вершины.
|
||||
Информация о ребрах задается в виде \textit{Map<int, int> \_ln}, где каждой вершине можно присвоить вес ребра.
|
||||
|
||||
Создать вершину можно тремя способами:
|
||||
\begin{enumerate}
|
||||
\item Пустая точка;
|
||||
\item из двух списков, где в первом список вершин, а во втором - длины пути;
|
||||
\item из \textit{Map<int, int>}.
|
||||
\end{enumerate}
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/graph/dot_constr.dart}
|
||||
|
||||
Для манипуляций с информацией доступно:
|
||||
\begin{enumerate}
|
||||
\item изменение имени;
|
||||
\item добавление пути;
|
||||
\item удаление пути.
|
||||
\end{enumerate}
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/graph/dot_manip.dart}
|
||||
|
||||
\subsubsection{Класс для графов}
|
||||
Класс \textbf{Graphs} используется для хранения точек и манипуляции с ними.
|
||||
|
||||
Основная информация:
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/graph/graph.dart}
|
||||
\textit{String \_name} исользуется для имени графа, \textit{int \_amount} --- количество вершин, \textit{List<Dot> \_dots} --- массив точек, \textit{Map<int, String> \_nameTable} --- отслеживание имени каждой вершины, \textit{bool \_useLength} --- отслеживание взвешенности графа, \textit{bool \_oriented} --- отслеживание ориентированности графа.
|
||||
|
||||
Для работы графом доступны функции:
|
||||
\begin{enumerate}
|
||||
\item \textbf{String? addDot(Dot a)} --- добавление вершины;
|
||||
\item \textbf{String? addIsolated(String name)} --- добавление изолированной точки;
|
||||
\item \textbf{String? addPath(int from, int to, [int len = 0])} --- добавление пути;
|
||||
\item \textbf{String? delPath(int from, int to)} --- удаление пути;
|
||||
\item \textbf{String? delDot(int inn)} --- удаление вершины;
|
||||
\item \textbf{void flushData()} --- удаление информации из графа;
|
||||
\item \textbf{bool checkDots([bool verbose = false])} --- проверка графа на ошибки;
|
||||
\item \textbf{void \_fixAfterDel(int inn}) --- испралвение нумерации после удаления;
|
||||
\item \textbf{void \_syncNameTable()} --- синхронизация таблицы имен вершин;
|
||||
\item \textbf{void setName(String name)} --- изменение имени;
|
||||
\item \textbf{String? replaceDataFromFile(String path)} --- заменяет информацию графа на информацию из файла;
|
||||
\item \textbf{List<LenDotPath> getSortedPathList()} --- возвращает список всех путей, отсортированный в порядке неубывания;
|
||||
\item \textbf{void printG()} --- выводит информацию о графе в консоль;
|
||||
\item \textbf{void printToFile(String name)} --- выводит информацию о графе в файл;
|
||||
\end{enumerate}
|
||||
|
||||
Создать граф можно тремя способами:
|
||||
\begin{enumerate}
|
||||
\item пустой граф;
|
||||
\item из списка смежности;
|
||||
\item из файла.
|
||||
\end{enumerate}
|
||||
|
||||
\subsubsection{Алгоритмы}
|
||||
\subsubsection{Кнопки}
|
||||
Алгоритмы описаны в классе графа.\newline
|
||||
|
||||
Обход в ширину:
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/graph/bfs.dart}
|
||||
Обход в глубину:
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/graph/dfs.dart}
|
||||
Алгоритм Дейкстры:
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/graph/dijkstra.dart}
|
||||
Алгоритм Краскала:
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/graph/kruscal.dart}
|
||||
\subsubsection{Интерфейс}
|
||||
Интерфейс описан в файле drawing\_page.dart. Полный код доступен в приложении~\ref{buttons}.
|
||||
|
||||
Интерфейс программы:
|
||||
\begin{figure}[!ht]
|
||||
\centering
|
||||
\includegraphics[width=9cm]{./pic/grafs.png}
|
||||
\caption{\label{fig:programm}
|
||||
Интерфейс программы}
|
||||
\end{figure}
|
||||
\newpage
|
||||
В качестве основы выбран виджет, сохраняющий состояние.
|
||||
|
||||
Построение интерфейса:
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/page/build.dart}
|
||||
|
||||
Запуск работы алгоритмов происходит по нажатию соответствующих кнопок, затем страница отрисовки, используя полученные данные, отрисовывает на экране информацию.
|
||||
\subsubsection{Отрисовка графа}
|
||||
Отрисовка графа описана в файле curve\_painter.dart. Код доступен в приложении~\ref{painter}.
|
||||
|
||||
\section{Таблица}
|
||||
\subsection{Текст с таблицей}
|
||||
Для отрисовки информации используется виджет CustomPaint~\cite{custompaint}.
|
||||
|
||||
\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}
|
||||
Для передачи информации графа используется конструктор CurvePainter.
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/painter/constr.dart}
|
||||
|
||||
Отрисовка соединений происходит с помощью пакета ''arrow\_path''.
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/painter/arrow.dart}
|
||||
|
||||
Для упрощения отрисовки, точки располагаются на окружности с центом, совпадающим с центром экрана. Сначала вычисляется их местоположение на экране, точка с максимальным количеством соединений располагается в центре:
|
||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/painter/pos.dart}
|
||||
Процесс вывода на экран:
|
||||
\begin{enumerate}
|
||||
\item вывод вершин на экран;
|
||||
\item определение текущей операции и вывод работы текущего алгоритма;
|
||||
\item вывод ребер;
|
||||
\item вывод длин ребер;
|
||||
\item вывод имен вершин.
|
||||
\end{enumerate}
|
||||
\subsubsection{Итоговый вид приложения}
|
||||
Итоговое приложение выглядит так:
|
||||
\begin{figure}[!ht]
|
||||
\centering
|
||||
\includegraphics[width=15cm]{./pic/result.png}
|
||||
\caption{\label{fig:resutl}
|
||||
Интерфейс программы}
|
||||
\end{figure}
|
||||
\newpage
|
||||
% Раздел "Заключение"
|
||||
\conclusion
|
||||
Было разработано простое приложение для создания и работы с графами с использованием Dart и Flutter.
|
||||
|
||||
В приложении возможно:
|
||||
В приложении возможно с помощью графического интерфейса:
|
||||
\begin{itemize}
|
||||
\item создать пустой граф;
|
||||
\item добавить вершину;
|
||||
|
@ -349,20 +453,13 @@ Skia ---
|
|||
\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}
|
||||
|
|
|
@ -8,22 +8,29 @@
|
|||
\contentsline {subsubsection}{\numberline {1.3.2}\IeC {\CYRM }\IeC {\cyra }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrc }\IeC {\cyra } \IeC {\cyrs }\IeC {\cyrm }\IeC {\cyre }\IeC {\cyrzh }\IeC {\cyrn }\IeC {\cyro }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyri }}{6}{subsubsection.1.3.2}%
|
||||
\contentsline {subsubsection}{\numberline {1.3.3}\IeC {\CYRM }\IeC {\cyra }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrc }\IeC {\cyra } \IeC {\cyri }\IeC {\cyrn }\IeC {\cyrc }\IeC {\cyri }\IeC {\cyrd }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyrt }\IeC {\cyrn }\IeC {\cyro }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyri }}{6}{subsubsection.1.3.3}%
|
||||
\contentsline {subsubsection}{\numberline {1.3.4}\IeC {\CYRS }\IeC {\cyrp }\IeC {\cyri }\IeC {\cyrs }\IeC {\cyrk }\IeC {\cyri } \IeC {\cyrs }\IeC {\cyrm }\IeC {\cyre }\IeC {\cyrzh }\IeC {\cyrn }\IeC {\cyro }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyri }}{7}{subsubsection.1.3.4}%
|
||||
\contentsline {section}{\numberline {2}\IeC {\CYRI }\IeC {\cyrn }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyru }\IeC {\cyrm }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyrt }\IeC {\cyrery }}{8}{section.2}%
|
||||
\contentsline {subsection}{\numberline {2.1}Dart}{8}{subsection.2.1}%
|
||||
\contentsline {subsection}{\numberline {2.2}Flutter}{8}{subsection.2.2}%
|
||||
\contentsline {section}{\numberline {3}\IeC {\CYRR }\IeC {\cyre }\IeC {\cyra }\IeC {\cyrl }\IeC {\cyri }\IeC {\cyrz }\IeC {\cyra }\IeC {\cyrc }\IeC {\cyri }\IeC {\cyrya }}{8}{section.3}%
|
||||
\contentsline {subsection}{\numberline {3.1}\IeC {\CYRT }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyrs }\IeC {\cyrt } \IeC {\cyrs } \IeC {\cyrf }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyrm }\IeC {\cyru }\IeC {\cyrl }\IeC {\cyra }\IeC {\cyrm }\IeC {\cyri } \IeC {\cyri } \IeC {\cyrl }\IeC {\cyre }\IeC {\cyrm }\IeC {\cyrm }\IeC {\cyro }\IeC {\cyrishrt }}{8}{subsection.3.1}%
|
||||
\contentsline {subsection}{\numberline {3.2}\IeC {\CYRN }\IeC {\cyra }\IeC {\cyrz }\IeC {\cyrv }\IeC {\cyra }\IeC {\cyrn }\IeC {\cyri }\IeC {\cyre } \IeC {\cyrd }\IeC {\cyrr }\IeC {\cyru }\IeC {\cyrg }\IeC {\cyro }\IeC {\cyrg }\IeC {\cyro } \IeC {\cyrp }\IeC {\cyro }\IeC {\cyrd }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrz }\IeC {\cyrd }\IeC {\cyre }\IeC {\cyrl }\IeC {\cyra }}{8}{subsection.3.2}%
|
||||
\contentsline {subsubsection}{\numberline {3.2.1}\IeC {\CYRB }\IeC {\cyro }\IeC {\cyrl }\IeC {\cyre }\IeC {\cyre } \IeC {\cyrm }\IeC {\cyre }\IeC {\cyrl }\IeC {\cyrk }\IeC {\cyri }\IeC {\cyrishrt } \IeC {\cyrp }\IeC {\cyro }\IeC {\cyrd }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrz }\IeC {\cyrd }\IeC {\cyre }\IeC {\cyrl }}{8}{subsubsection.3.2.1}%
|
||||
\contentsline {subsubsection}{\numberline {3.2.2}\IeC {\CYRT }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyrs }\IeC {\cyrt } \IeC {\cyrs } \IeC {\cyrt }\IeC {\cyra }\IeC {\cyrb }\IeC {\cyrl }\IeC {\cyri }\IeC {\cyrc }\IeC {\cyre }\IeC {\cyrishrt }}{8}{subsubsection.3.2.2}%
|
||||
\contentsline {subsubsection}{\numberline {3.2.3}\IeC {\CYRT }\IeC {\cyre }\IeC {\cyrk }\IeC {\cyrs }\IeC {\cyrt } \IeC {\cyrs } \IeC {\cyrk }\IeC {\cyro }\IeC {\cyrd }\IeC {\cyro }\IeC {\cyrm } \IeC {\cyrp }\IeC {\cyrr }\IeC {\cyro }\IeC {\cyrg }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrm }\IeC {\cyrm }\IeC {\cyrery }}{8}{subsubsection.3.2.3}%
|
||||
\contentsline {section}{\cyrillictext \CYRZ \CYRA \CYRK \CYRL \CYRYU \CYRCH \CYRE \CYRN \CYRI \CYRE }{8}{section*.8}%
|
||||
\contentsline {section}{\cyrillictext \CYRS \CYRP \CYRI \CYRS \CYRO \CYRK \ \CYRI \CYRS \CYRP \CYRO \CYRL \CYRSFTSN \CYRZ \CYRO \CYRV \CYRA \CYRN \CYRN \CYRERY \CYRH \ \CYRI \CYRS \CYRT \CYRO \CYRCH \CYRN \CYRI \CYRK \CYRO \CYRV }{10}{section*.9}%
|
||||
\contentsline {subsection}{\numberline {1.4}\IeC {\CYRA }\IeC {\cyrl }\IeC {\cyrg }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrt }\IeC {\cyrm }\IeC {\cyrery }}{7}{subsection.1.4}%
|
||||
\contentsline {subsubsection}{\numberline {1.4.1}\IeC {\CYRO }\IeC {\cyrb }\IeC {\cyrh }\IeC {\cyro }\IeC {\cyrd } \IeC {\cyrv } \IeC {\cyrsh }\IeC {\cyri }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrn }\IeC {\cyru }}{7}{subsubsection.1.4.1}%
|
||||
\contentsline {subsubsection}{\numberline {1.4.2}\IeC {\CYRO }\IeC {\cyrb }\IeC {\cyrh }\IeC {\cyro }\IeC {\cyrd } \IeC {\cyrv } \IeC {\cyrg }\IeC {\cyrl }\IeC {\cyru }\IeC {\cyrb }\IeC {\cyri }\IeC {\cyrn }\IeC {\cyru }}{8}{subsubsection.1.4.2}%
|
||||
\contentsline {subsubsection}{\numberline {1.4.3}\IeC {\CYRA }\IeC {\cyrl }\IeC {\cyrg }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrt }\IeC {\cyrm } \IeC {\CYRD }\IeC {\cyre }\IeC {\cyrishrt }\IeC {\cyrk }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyrery }}{9}{subsubsection.1.4.3}%
|
||||
\contentsline {subsubsection}{\numberline {1.4.4}\IeC {\CYRA }\IeC {\cyrl }\IeC {\cyrg }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrt }\IeC {\cyrm } \IeC {\CYRK }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrs }\IeC {\cyrk }\IeC {\cyra }\IeC {\cyrl }\IeC {\cyra }}{9}{subsubsection.1.4.4}%
|
||||
\contentsline {section}{\numberline {2}\IeC {\CYRI }\IeC {\cyrn }\IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyru }\IeC {\cyrm }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyrt }\IeC {\cyrery }}{11}{section.2}%
|
||||
\contentsline {subsection}{\numberline {2.1}Dart}{11}{subsection.2.1}%
|
||||
\contentsline {subsection}{\numberline {2.2}Flutter}{12}{subsection.2.2}%
|
||||
\contentsline {section}{\numberline {3}\IeC {\CYRR }\IeC {\cyre }\IeC {\cyra }\IeC {\cyrl }\IeC {\cyri }\IeC {\cyrz }\IeC {\cyra }\IeC {\cyrc }\IeC {\cyri }\IeC {\cyrya }}{14}{section.3}%
|
||||
\contentsline {subsection}{\numberline {3.1}\IeC {\CYRG }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrf }\IeC {\cyrery }}{14}{subsection.3.1}%
|
||||
\contentsline {subsubsection}{\numberline {3.1.1}\IeC {\CYRK }\IeC {\cyrl }\IeC {\cyra }\IeC {\cyrs }\IeC {\cyrs } \IeC {\cyrd }\IeC {\cyrl }\IeC {\cyrya } \IeC {\cyrh }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrn }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyri }\IeC {\cyrya } \IeC {\cyrv }\IeC {\cyre }\IeC {\cyrr }\IeC {\cyrsh }\IeC {\cyri }\IeC {\cyrn }\IeC {\cyrery }}{14}{subsubsection.3.1.1}%
|
||||
\contentsline {subsubsection}{\numberline {3.1.2}\IeC {\CYRK }\IeC {\cyrl }\IeC {\cyra }\IeC {\cyrs }\IeC {\cyrs } \IeC {\cyrd }\IeC {\cyrl }\IeC {\cyrya } \IeC {\cyrg }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrf }\IeC {\cyro }\IeC {\cyrv }}{15}{subsubsection.3.1.2}%
|
||||
\contentsline {subsubsection}{\numberline {3.1.3}\IeC {\CYRA }\IeC {\cyrl }\IeC {\cyrg }\IeC {\cyro }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrt }\IeC {\cyrm }\IeC {\cyrery }}{16}{subsubsection.3.1.3}%
|
||||
\contentsline {subsubsection}{\numberline {3.1.4}\IeC {\CYRI }\IeC {\cyrn }\IeC {\cyrt }\IeC {\cyre }\IeC {\cyrr }\IeC {\cyrf }\IeC {\cyre }\IeC {\cyrishrt }\IeC {\cyrs }}{19}{subsubsection.3.1.4}%
|
||||
\contentsline {subsubsection}{\numberline {3.1.5}\IeC {\CYRO }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrs }\IeC {\cyro }\IeC {\cyrv }\IeC {\cyrk }\IeC {\cyra } \IeC {\cyrg }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrf }\IeC {\cyra }}{21}{subsubsection.3.1.5}%
|
||||
\contentsline {subsubsection}{\numberline {3.1.6}\IeC {\CYRI }\IeC {\cyrt }\IeC {\cyro }\IeC {\cyrg }\IeC {\cyro }\IeC {\cyrv }\IeC {\cyrery }\IeC {\cyrishrt } \IeC {\cyrv }\IeC {\cyri }\IeC {\cyrd } \IeC {\cyrp }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrl }\IeC {\cyro }\IeC {\cyrzh }\IeC {\cyre }\IeC {\cyrn }\IeC {\cyri }\IeC {\cyrya }}{23}{subsubsection.3.1.6}%
|
||||
\contentsline {section}{\cyrillictext \CYRZ \CYRA \CYRK \CYRL \CYRYU \CYRCH \CYRE \CYRN \CYRI \CYRE }{24}{section*.10}%
|
||||
\contentsline {section}{\cyrillictext \CYRS \CYRP \CYRI \CYRS \CYRO \CYRK \ \CYRI \CYRS \CYRP \CYRO \CYRL \CYRSFTSN \CYRZ \CYRO \CYRV \CYRA \CYRN \CYRN \CYRERY \CYRH \ \CYRI \CYRS \CYRT \CYRO \CYRCH \CYRN \CYRI \CYRK \CYRO \CYRV }{25}{section*.11}%
|
||||
\redeflsection
|
||||
\ttl@change@i {\@ne }{section}{3ex}{\hspace {-3ex}}{\appendixname ~\thecontentslabel \hspace {2ex}}{\hspace {2.3em}}{\titlerule *[0.98ex]{.}\contentspage }\relax
|
||||
\ttl@change@v {section}{}{}{}\relax
|
||||
\contentsline {section}{\numberline {\CYRA }\IeC {\CYRK }\IeC {\cyro }\IeC {\cyrd } main.dart}{11}{appendix.A}%
|
||||
\contentsline {section}{\numberline {\CYRB }\IeC {\CYRK }\IeC {\cyro }\IeC {\cyrd } \IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrn }\IeC {\cyri }\IeC {\cyrc }\IeC {\cyrery } \IeC {\cyro }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrs }\IeC {\cyro }\IeC {\cyrv }\IeC {\cyrk }\IeC {\cyri }}{12}{appendix.B}%
|
||||
\contentsline {section}{\numberline {\CYRV }\IeC {\CYRK }\IeC {\cyro }\IeC {\cyrd } \IeC {\cyro }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrs }\IeC {\cyro }\IeC {\cyrv }\IeC {\cyrk }\IeC {\cyri } \IeC {\cyrg }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrf }\IeC {\cyra }}{23}{appendix.C}%
|
||||
\contentsline {section}{\numberline {\CYRG }\IeC {\CYRK }\IeC {\cyro }\IeC {\cyrd } \IeC {\cyrk }\IeC {\cyrl }\IeC {\cyra }\IeC {\cyrs }\IeC {\cyrs }\IeC {\cyra } \IeC {\cyrd }\IeC {\cyrl }\IeC {\cyrya } \IeC {\cyrr }\IeC {\cyra }\IeC {\cyrb }\IeC {\cyro }\IeC {\cyrt }\IeC {\cyrery } \IeC {\cyrs } \IeC {\cyrg }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrf }\IeC {\cyro }\IeC {\cyrm }}{30}{appendix.D}%
|
||||
\contentsline {section}{\numberline {\CYRA }\IeC {\CYRK }\IeC {\cyro }\IeC {\cyrd } main.dart}{26}{appendix.A}%
|
||||
\contentsline {section}{\numberline {\CYRB }\IeC {\CYRK }\IeC {\cyro }\IeC {\cyrd } \IeC {\cyrs }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrn }\IeC {\cyri }\IeC {\cyrc }\IeC {\cyrery } \IeC {\cyro }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrs }\IeC {\cyro }\IeC {\cyrv }\IeC {\cyrk }\IeC {\cyri }}{27}{appendix.B}%
|
||||
\contentsline {section}{\numberline {\CYRV }\IeC {\CYRK }\IeC {\cyro }\IeC {\cyrd } \IeC {\cyro }\IeC {\cyrt }\IeC {\cyrr }\IeC {\cyri }\IeC {\cyrs }\IeC {\cyro }\IeC {\cyrv }\IeC {\cyrk }\IeC {\cyri } \IeC {\cyrg }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrf }\IeC {\cyra }}{38}{appendix.C}%
|
||||
\contentsline {section}{\numberline {\CYRG }\IeC {\CYRK }\IeC {\cyro }\IeC {\cyrd } \IeC {\cyrk }\IeC {\cyrl }\IeC {\cyra }\IeC {\cyrs }\IeC {\cyrs }\IeC {\cyra } \IeC {\cyrd }\IeC {\cyrl }\IeC {\cyrya } \IeC {\cyrr }\IeC {\cyra }\IeC {\cyrb }\IeC {\cyro }\IeC {\cyrt }\IeC {\cyrery } \IeC {\cyrs } \IeC {\cyrg }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrf }\IeC {\cyro }\IeC {\cyrm }}{45}{appendix.D}%
|
||||
\contentsfinish
|
||||
|
|
|
@ -24,7 +24,6 @@ class _DrawingPageState extends State<DrawingPage> {
|
|||
Graphs graphData = getGraph();
|
||||
List<int?>? intListPath;
|
||||
List<bool>? dfsAccessTable;
|
||||
//List<int?>? dijkstraTable;
|
||||
String op = Operations.none;
|
||||
int? startDot;
|
||||
int? endDot;
|
||||
|
|
|
@ -128,7 +128,6 @@ class CurvePainter extends CustomPainter {
|
|||
print("GetDotPos error");
|
||||
}
|
||||
}
|
||||
|
||||
return off;
|
||||
}
|
||||
|
||||
|
@ -245,7 +244,7 @@ class CurvePainter extends CustomPainter {
|
|||
_drawDot(canvas, _off[start]!, 9, Colors.green);
|
||||
_drawDot(canvas, _off[end]!, 7, Colors.red.shade200);
|
||||
for (int i = 0; i < intListPath!.length; i++) {
|
||||
_drawDotNum(canvas, _off[intListPath![i]]!, "bfs: ¹${i + 1}");
|
||||
_drawDotNum(canvas, _off[intListPath![i]]!, "bfs: <EFBFBD>${i + 1}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -449,7 +449,7 @@ class Graphs {
|
|||
result.sort((a, b) => a.l.compareTo(b.l));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//*****Getters*******
|
||||
|
||||
//******Print******
|
||||
|
@ -541,7 +541,6 @@ class Graphs {
|
|||
//************Àëãîðèòìû************
|
||||
List<int>? bfsPath(int startDot, int goalDot) {
|
||||
if (startDot == goalDot) return [startDot];
|
||||
//if (!bfsHasPath(startDot, goalDot)) return null;
|
||||
startDot--;
|
||||
goalDot--;
|
||||
List<List<int>>? graph = getLenTable();
|
||||
|
@ -559,8 +558,7 @@ class Graphs {
|
|||
q.add(startDot);
|
||||
used[startDot] = true;
|
||||
dst[startDot] = 0;
|
||||
pr[startDot] =
|
||||
-1; //Пометка, означающая, что у вершины startDot нет предыдущей.
|
||||
pr[startDot] = -1; //у вершины нет предыдущей.
|
||||
|
||||
while (q.isNotEmpty) {
|
||||
int cur = q.removeAt(0);
|
||||
|
@ -578,21 +576,16 @@ class Graphs {
|
|||
}
|
||||
}
|
||||
|
||||
//Восстановим кратчайший путь
|
||||
//Для восстановления пути пройдём его в обратном порядке, и развернём.
|
||||
//Восстановление кратчайшиего путьи
|
||||
List<int> path = <int>[];
|
||||
|
||||
int cur = goalDot; //текущая вершина пути
|
||||
int cur = goalDot;
|
||||
path.add(cur + 1);
|
||||
|
||||
while (pr[cur] != -1) {
|
||||
//пока существует предыдущая вершина
|
||||
cur = pr[cur]; //переходим в неё
|
||||
path.add(cur + 1); //и дописываем к пути
|
||||
cur = pr[cur];
|
||||
path.add(cur + 1);
|
||||
}
|
||||
|
||||
path = path.reversed.toList();
|
||||
|
||||
if (path[0] == (startDot + 1) &&
|
||||
path[1] == (goalDot + 1) &&
|
||||
!_dots[startDot].hasConnection(goalDot + 1)) return null;
|
||||
|
@ -607,14 +600,12 @@ class Graphs {
|
|||
}
|
||||
List<int> stack = <int>[];
|
||||
stack.add(v);
|
||||
//pos.add(v);
|
||||
while (stack.isNotEmpty) {
|
||||
v = stack.removeLast();
|
||||
if (!label[v]) {
|
||||
label[v] = true;
|
||||
for (int i in _dots[v].getL().keys) {
|
||||
stack.add(i - 1);
|
||||
//pos.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -630,7 +621,6 @@ class Graphs {
|
|||
for (int i = 0; i < _amount; ++i) {
|
||||
int v = -1;
|
||||
for (int j = 0; j < _amount; ++j) {
|
||||
// int t;
|
||||
if (!u[j] && (v == -1 || d[j]! < d[v]!)) {
|
||||
v = j;
|
||||
}
|
||||
|
@ -647,7 +637,6 @@ class Graphs {
|
|||
}
|
||||
}
|
||||
for (int i = 0; i < d.length; i++) {
|
||||
// подумать как убрать эту часть
|
||||
if (d[i] == intMax) d[i] = null;
|
||||
}
|
||||
return d;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
|
@ -61,4 +61,14 @@
|
|||
note={URL:~\url{https://skia.org/docs/}(Äàòà îáðàùåíèÿ 20.11.2021). Çàãë. ñ ýêð. ßç. àíãë.},
|
||||
}
|
||||
|
||||
@Manual{krusc,
|
||||
title={Ìèíèìàëüíîå îñòîâíîå äåðåâî. Àëãîðèòì Êðóñêàëà. [{Ý}ëåêòðîííûé ðåñóðñ]},
|
||||
note={URL:~\url{https://e-maxx.ru/algo/mst_kruskal}(Äàòà îáðàùåíèÿ 20.11.2021). Çàãë. ñ ýêð. ßç. ðóñ.},
|
||||
}
|
||||
|
||||
@Manual{custompaint,
|
||||
title={CustomPaint class. [{Ý}ëåêòðîííûé ðåñóðñ]},
|
||||
note={URL:~\url{https://api.flutter.dev/flutter/widgets/CustomPaint-class.html}(Äàòà îáðàùåíèÿ 20.11.2021). Çàãë. ñ ýêð. ßç. àíãë.},
|
||||
}
|
||||
|
||||
@Comment{jabref-meta: databaseType:bibtex;}
|
||||
|
|
Loading…
Reference in New Issue