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}.
|
Поиск в ширину имеет такое название потому, что в процессе обхода мы идём вширь, то есть перед тем как приступить к поиску вершин на расстоянии $k + 1$, выполняется обход вершин на расстоянии $k$~\cite{Algo_2013}.
|
||||||
|
|
||||||
Приведенная ниже процедура поиска в ширину BFS предполагает, что входной граф $G = (V, E)$ представлен при помощи списков смежности. Псевдокод:
|
Приведенная ниже процедура поиска в ширину BFS предполагает, что входной граф $G = (V, E)$ представлен при помощи списков смежности. Псевдокод алгоритма:
|
||||||
\inputminted[fontsize=\footnotesize, linenos]{python}{./dart/pseudoBFS.txt}
|
\inputminted[fontsize=\footnotesize, linenos]{python}{./dart/pseudoBFS.txt}
|
||||||
|
|
||||||
Воспользуемся групповым анализом. Операции внесения в очередь и удаление из нее требует $O(1)$ времени. Следовательно на очередь потребуется $O(V)$ времени. Т.к. максимальная длина списков смежности $\theta(E)$, то время, необходимое для сканирования списков, равно $O(E)$. Расходы на инициализацию: $O(V)$. Таким образом, общее время работы алгоритма: $O(V + E)$. Время поиска в ширину линейно зависит от размера представления графа.
|
Воспользуемся групповым анализом. Операции внесения в очередь и удаление из нее требует $O(1)$ времени. Следовательно на очередь потребуется $O(V)$ времени. Т.к. максимальная длина списков смежности $\theta(E)$, то время, необходимое для сканирования списков, равно $O(E)$. Расходы на инициализацию: $O(V)$. Таким образом, общее время работы алгоритма: $O(V + E)$. Время поиска в ширину линейно зависит от размера представления графа.
|
||||||
|
|
||||||
\subsubsection{Обход в глубину}
|
\subsubsection{Обход в глубину}
|
||||||
|
Стратегия обхода в ширину состоит в том, чтобы идти ''вглубь'' графа. Сначала исследуются ребра, выходящие из вершины, открытой последней, и покидаем вершину, когда не остается неисследованных ребер --- при этом происходит возврат в вершину, из которой была открыта вершина $v$. Процесс продолжается, пока не будут открыты все вершины, достижимые из исходной.
|
||||||
|
|
||||||
|
Псевдо код алгоритма:
|
||||||
|
|
||||||
|
|
||||||
\inputminted[fontsize=\footnotesize, linenos]{python}{./dart/pseudoDFS.txt}
|
\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{Инструменты}
|
\section{Инструменты}
|
||||||
Рассмотрим используемый язык и библиотеку для отрисовки.
|
Рассмотрим используемый язык и библиотеку для отрисовки.
|
||||||
\subsection{Dart}
|
\subsection{Dart}
|
||||||
В качестве основы используется язык \textbf{Dart}, разработанный компанией Google, и широко используемый для кросс-платформенной разработки~\cite{dart_web}.
|
В качестве основы используется язык \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 года.
|
Версия 1.0 вышла в 14 ноября 2013 года.
|
||||||
Вторая версия была выпущена в августе 2018 года. В языке появилась надежная система типов, т.~е. во время выполнении программы все переменные будут гарантированно указанному типу~\cite{dart_sound}.
|
Вторая версия была выпущена в августе 2018 года. В языке появилась надежная система типов, т.~е. во время выполнении программы все переменные будут гарантированно указанному типу~\cite{dart_sound}.
|
||||||
|
|
||||||
|
В Dart используется сборщик мусора. Синтаксис похож на языки: JavaScript, C\#, Java~\cite{dartInAction}.
|
||||||
|
|
||||||
Пример HelloWorld на Dart:
|
Пример HelloWorld на Dart:
|
||||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/helloWorld.dart}
|
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/helloWorld.dart}
|
||||||
|
|
||||||
Dart поддерживает сокращенную запись. Код примера HelloWorld можно записать так:
|
Dart поддерживает сокращенную запись. Код примера HelloWorld можно записать так:
|
||||||
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/hW.dart}
|
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/hW.dart}
|
||||||
|
|
||||||
|
|
||||||
Концепты языка~\cite{dart_tour}:
|
Концепты языка~\cite{dart_tour}:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Все, что можно поместить в переменную, является объектом, а каждый объект является частью класса;
|
\item Все, что можно поместить в переменную, является объектом, а каждый объект является частью класса;
|
||||||
|
@ -283,7 +297,6 @@ Dart
|
||||||
\item для объявления локальных функций и переменных необходимо начать имя со знака ''\_''
|
\item для объявления локальных функций и переменных необходимо начать имя со знака ''\_''
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
.
|
.
|
||||||
|
|
||||||
\subsection{Flutter}
|
\subsection{Flutter}
|
||||||
Для отрисовки информации используется фреймворк c открытым исходным кодом ''Flutter'', разработанный компанией Google.
|
Для отрисовки информации используется фреймворк c открытым исходным кодом ''Flutter'', разработанный компанией Google.
|
||||||
Flutter не использует нативные компоненты для отрисовки интерфейса. В его основе лежит графический движок ''Skia'', написанный преимущественно на С++.
|
Flutter не использует нативные компоненты для отрисовки интерфейса. В его основе лежит графический движок ''Skia'', написанный преимущественно на С++.
|
||||||
|
@ -299,48 +312,139 @@ Skia ---
|
||||||
\caption{\label{fig:flutter_example}
|
\caption{\label{fig:flutter_example}
|
||||||
Простейшее приложение на Flutter}
|
Простейшее приложение на Flutter}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
Интерфейс описывается с помощью виджетов.
|
||||||
\section{Реализация}
|
\section{Реализация}
|
||||||
|
Структура программы разбита на 4 файла:
|
||||||
|
|
||||||
|
\begin{itemize}
|
||||||
|
\item main.dart --- точка входа в программу;
|
||||||
|
\item drawing\_page.dart --- страница с описанием работы кнопок;
|
||||||
|
\item curve\_painter.dart --- функционал для отрисовки графа;
|
||||||
|
\item graph.dart --- класс для хранения графа и манипуляции с ним.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
\subsection{Графы}
|
\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{Алгоритмы}
|
||||||
\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{Отрисовка графа}
|
\subsubsection{Отрисовка графа}
|
||||||
|
Отрисовка графа описана в файле curve\_painter.dart. Код доступен в приложении~\ref{painter}.
|
||||||
|
|
||||||
\section{Таблица}
|
Для отрисовки информации используется виджет CustomPaint~\cite{custompaint}.
|
||||||
\subsection{Текст с таблицей}
|
|
||||||
|
|
||||||
\begin{table}[!ht]
|
Для передачи информации графа используется конструктор CurvePainter.
|
||||||
\small
|
\inputminted[fontsize=\footnotesize, linenos]{dart}{./dart/painter/constr.dart}
|
||||||
\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}
|
|
||||||
|
|
||||||
|
Отрисовка соединений происходит с помощью пакета ''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
|
\conclusion
|
||||||
Было разработано простое приложение для создания и работы с графами с использованием Dart и Flutter.
|
Было разработано простое приложение для создания и работы с графами с использованием Dart и Flutter.
|
||||||
|
|
||||||
В приложении возможно:
|
В приложении возможно с помощью графического интерфейса:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item создать пустой граф;
|
\item создать пустой граф;
|
||||||
\item добавить вершину;
|
\item добавить вершину;
|
||||||
|
@ -349,20 +453,13 @@ Skia ---
|
||||||
\item удалить путь;
|
\item удалить путь;
|
||||||
\item сохранить граф;
|
\item сохранить граф;
|
||||||
\item загрузить граф;
|
\item загрузить граф;
|
||||||
\item построить минимальное остовное дерево с помощью алгоритма Крускала;
|
\item построить минимальное остовное дерево с помощью алгоритма Краскала;
|
||||||
\item найти минимальный путь из выбранной вершины в другие с помощью алгоритма Дейкстры;
|
\item найти минимальный путь из выбранной вершины в другие с помощью алгоритма Дейкстры;
|
||||||
\item проверить доступность вершин с помощью обхода в глубину;
|
\item проверить доступность вершин с помощью обхода в глубину;
|
||||||
\item построить путь из одной вершины в другую с помощью обхода в ширину.
|
\item построить путь из одной вершины в другую с помощью обхода в ширину.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
%Библиографический список, составленный вручную, без использования BibTeX
|
|
||||||
%
|
|
||||||
%\begin{thebibliography}{99}
|
|
||||||
% \bibitem{Ione} Источник 1.
|
|
||||||
% \bibitem{Itwo} Источник 2
|
|
||||||
%\end{thebibliography}
|
|
||||||
|
|
||||||
%Библиографический список, составленный с помощью BibTeX
|
%Библиографический список, составленный с помощью BibTeX
|
||||||
%
|
%
|
||||||
\bibliographystyle{gost780uv}
|
\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.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.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 {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 {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 {subsection}{\numberline {2.1}Dart}{8}{subsection.2.1}%
|
\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 {subsection}{\numberline {2.2}Flutter}{8}{subsection.2.2}%
|
\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 {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 {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 {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 {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 {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 {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 {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 {subsection}{\numberline {2.1}Dart}{11}{subsection.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 {subsection}{\numberline {2.2}Flutter}{12}{subsection.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}{\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 {section}{\cyrillictext \CYRZ \CYRA \CYRK \CYRL \CYRYU \CYRCH \CYRE \CYRN \CYRI \CYRE }{8}{section*.8}%
|
\contentsline {subsection}{\numberline {3.1}\IeC {\CYRG }\IeC {\cyrr }\IeC {\cyra }\IeC {\cyrf }\IeC {\cyrery }}{14}{subsection.3.1}%
|
||||||
\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 {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
|
\redeflsection
|
||||||
\ttl@change@i {\@ne }{section}{3ex}{\hspace {-3ex}}{\appendixname ~\thecontentslabel \hspace {2ex}}{\hspace {2.3em}}{\titlerule *[0.98ex]{.}\contentspage }\relax
|
\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
|
\ttl@change@v {section}{}{}{}\relax
|
||||||
\contentsline {section}{\numberline {\CYRA }\IeC {\CYRK }\IeC {\cyro }\IeC {\cyrd } main.dart}{11}{appendix.A}%
|
\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 }}{12}{appendix.B}%
|
\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 }}{23}{appendix.C}%
|
\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 }}{30}{appendix.D}%
|
\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
|
\contentsfinish
|
||||||
|
|
|
@ -24,7 +24,6 @@ class _DrawingPageState extends State<DrawingPage> {
|
||||||
Graphs graphData = getGraph();
|
Graphs graphData = getGraph();
|
||||||
List<int?>? intListPath;
|
List<int?>? intListPath;
|
||||||
List<bool>? dfsAccessTable;
|
List<bool>? dfsAccessTable;
|
||||||
//List<int?>? dijkstraTable;
|
|
||||||
String op = Operations.none;
|
String op = Operations.none;
|
||||||
int? startDot;
|
int? startDot;
|
||||||
int? endDot;
|
int? endDot;
|
||||||
|
|
|
@ -128,7 +128,6 @@ class CurvePainter extends CustomPainter {
|
||||||
print("GetDotPos error");
|
print("GetDotPos error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +244,7 @@ class CurvePainter extends CustomPainter {
|
||||||
_drawDot(canvas, _off[start]!, 9, Colors.green);
|
_drawDot(canvas, _off[start]!, 9, Colors.green);
|
||||||
_drawDot(canvas, _off[end]!, 7, Colors.red.shade200);
|
_drawDot(canvas, _off[end]!, 7, Colors.red.shade200);
|
||||||
for (int i = 0; i < intListPath!.length; i++) {
|
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}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -541,7 +541,6 @@ class Graphs {
|
||||||
//************Àëãîðèòìû************
|
//************Àëãîðèòìû************
|
||||||
List<int>? bfsPath(int startDot, int goalDot) {
|
List<int>? bfsPath(int startDot, int goalDot) {
|
||||||
if (startDot == goalDot) return [startDot];
|
if (startDot == goalDot) return [startDot];
|
||||||
//if (!bfsHasPath(startDot, goalDot)) return null;
|
|
||||||
startDot--;
|
startDot--;
|
||||||
goalDot--;
|
goalDot--;
|
||||||
List<List<int>>? graph = getLenTable();
|
List<List<int>>? graph = getLenTable();
|
||||||
|
@ -559,8 +558,7 @@ class Graphs {
|
||||||
q.add(startDot);
|
q.add(startDot);
|
||||||
used[startDot] = true;
|
used[startDot] = true;
|
||||||
dst[startDot] = 0;
|
dst[startDot] = 0;
|
||||||
pr[startDot] =
|
pr[startDot] = -1; //у вершины нет предыдущей.
|
||||||
-1; //Пометка, означающая, что у вершины startDot нет предыдущей.
|
|
||||||
|
|
||||||
while (q.isNotEmpty) {
|
while (q.isNotEmpty) {
|
||||||
int cur = q.removeAt(0);
|
int cur = q.removeAt(0);
|
||||||
|
@ -578,21 +576,16 @@ class Graphs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Восстановим кратчайший путь
|
//Восстановление кратчайшиего путьи
|
||||||
//Для восстановления пути пройдём его в обратном порядке, и развернём.
|
|
||||||
List<int> path = <int>[];
|
List<int> path = <int>[];
|
||||||
|
int cur = goalDot;
|
||||||
int cur = goalDot; //текущая вершина пути
|
|
||||||
path.add(cur + 1);
|
path.add(cur + 1);
|
||||||
|
|
||||||
while (pr[cur] != -1) {
|
while (pr[cur] != -1) {
|
||||||
//пока существует предыдущая вершина
|
cur = pr[cur];
|
||||||
cur = pr[cur]; //переходим в неё
|
path.add(cur + 1);
|
||||||
path.add(cur + 1); //и дописываем к пути
|
|
||||||
}
|
}
|
||||||
|
|
||||||
path = path.reversed.toList();
|
path = path.reversed.toList();
|
||||||
|
|
||||||
if (path[0] == (startDot + 1) &&
|
if (path[0] == (startDot + 1) &&
|
||||||
path[1] == (goalDot + 1) &&
|
path[1] == (goalDot + 1) &&
|
||||||
!_dots[startDot].hasConnection(goalDot + 1)) return null;
|
!_dots[startDot].hasConnection(goalDot + 1)) return null;
|
||||||
|
@ -607,14 +600,12 @@ class Graphs {
|
||||||
}
|
}
|
||||||
List<int> stack = <int>[];
|
List<int> stack = <int>[];
|
||||||
stack.add(v);
|
stack.add(v);
|
||||||
//pos.add(v);
|
|
||||||
while (stack.isNotEmpty) {
|
while (stack.isNotEmpty) {
|
||||||
v = stack.removeLast();
|
v = stack.removeLast();
|
||||||
if (!label[v]) {
|
if (!label[v]) {
|
||||||
label[v] = true;
|
label[v] = true;
|
||||||
for (int i in _dots[v].getL().keys) {
|
for (int i in _dots[v].getL().keys) {
|
||||||
stack.add(i - 1);
|
stack.add(i - 1);
|
||||||
//pos.add(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -630,7 +621,6 @@ class Graphs {
|
||||||
for (int i = 0; i < _amount; ++i) {
|
for (int i = 0; i < _amount; ++i) {
|
||||||
int v = -1;
|
int v = -1;
|
||||||
for (int j = 0; j < _amount; ++j) {
|
for (int j = 0; j < _amount; ++j) {
|
||||||
// int t;
|
|
||||||
if (!u[j] && (v == -1 || d[j]! < d[v]!)) {
|
if (!u[j] && (v == -1 || d[j]! < d[v]!)) {
|
||||||
v = j;
|
v = j;
|
||||||
}
|
}
|
||||||
|
@ -647,7 +637,6 @@ class Graphs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < d.length; i++) {
|
for (int i = 0; i < d.length; i++) {
|
||||||
// подумать как убрать эту часть
|
|
||||||
if (d[i] == intMax) d[i] = null;
|
if (d[i] == intMax) d[i] = null;
|
||||||
}
|
}
|
||||||
return d;
|
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). Çàãë. ñ ýêð. ßç. àíãë.},
|
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;}
|
@Comment{jabref-meta: databaseType:bibtex;}
|
||||||
|
|
Loading…
Reference in New Issue