From 7bbb41421284a5dde4f7a4af056ba7e614c94aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=BE=D1=80=D0=BE=D0=B7=D0=BE=D0=B2=20=D0=90=D0=BD?= =?UTF-8?q?=D0=B4=D1=80=D0=B5=D0=B9?= Date: Wed, 10 Nov 2021 11:25:57 +0000 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B8=D1=82=D1=8C=20'f?= =?UTF-8?q?lutter/lib/graph.dart'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flutter/lib/graph.dart | 679 ----------------------------------------- 1 file changed, 679 deletions(-) delete mode 100644 flutter/lib/graph.dart diff --git a/flutter/lib/graph.dart b/flutter/lib/graph.dart deleted file mode 100644 index cd8707b..0000000 --- a/flutter/lib/graph.dart +++ /dev/null @@ -1,679 +0,0 @@ -import 'dart:io'; - -class Separators { - static const String dotToConnections = ": "; - static const String dotToLength = "|"; - static const String space = " "; - static const String hasLength = "Взвешенный"; - static const String hasNoLength = "НеВзвешенный"; - static const String isOriented = "Ориентированный"; - static const String isNotOriented = "НеОриентированный"; - static const String nL = "\n"; - static const String end = "END"; - - Separators(); -} - -class Dot { - //Data - // ignore: prefer_final_fields - String _name = ""; - int num = -1; - Map _ln = {}; - - //****Get**** - String getName() => _name; - bool hasConnection(int n) => _ln.containsKey(n); - Map getL() => _ln; - - int getLength(int x) { - if (hasConnection(x)) { - return _ln[x]!; - } - return -1; - } - //****Get**** - - //Set - void setName(String n) => _name = n; - - //Add - void addPath(int inp, int length) => _ln[inp] = length; - - //Del - void delPath(int n) => _ln.removeWhere((key, value) => - key == n); // удалить обратный путь если не ориентированный - - //Print - void printD() { - stdout.write("$_name: №$num => "); - for (var i in _ln.keys) { - stdout.write("$i|${_ln[i]} "); - } - stdout.write("\n"); - } - - //******Constructor****** - Dot([String name = "Undefined", int n = -1]) { - _name = name; - num = n; - _ln = {}; - } - Dot.fromTwoLists(String name, List num0, List length, - [int n = -1]) { - _name = name; - num = n; - Map nw = {}; - 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 l, [int n = -1]) { - _name = name; - num = n; - _ln = l; - } - //******Constructor****** - - //Copy - Dot.clone(Dot a) { - _name = a.getName(); - num = a.num; - _ln = a.getL(); - } -} - -class Graphs { - //Data - String _name = "Undefined"; //Имя - int _amount = 0; //Количество вершин - List _dots = []; //Список смежности вершин - Map _nameTable = {}; //Список вершин по именам - bool _useLength = false; //Взвешенность - bool _oriented = false; //Ориентированность - - //*********************Add************************ - String? addDot(Dot a) { - if (getNumByName(a.getName()) != null) { - return ("Dot name \"${a.getName()}\" already in use. Change name or use addPath"); - } - _amount++; - a.num = _amount; - _dots.add(a); - _syncNameTable(); - checkDots(false); - if (!_oriented) _fullFix(); - return null; - } - - bool addDotFromToLists(String name, List num0, List length, - [int n = -1]) { - var a = Dot.fromTwoLists(name, num0, length, n); - if (getNumByName(a.getName()) != null) { - print( - "Dot name ${a.getName()} already in use. Change name or use addPath"); - return false; - } - _amount++; - a.num = _amount; - _dots.add(a); - _syncNameTable(); - checkDots(false); - if (!_oriented) _fixPathAfterInsert(a); - return true; - } - - String? addIsolated(String name) { - var res = addDot(Dot.fromTwoLists(name, [], [])); - _syncNameTable(); - return res; - } - - String? addPath(int from, int to, [int len = 0]) { - if (from <= 0 || from > _amount || to <= 0 && to > _amount) { - return "Index out of range. Have dots 1..$_amount"; - } - _dots[from - 1].addPath(to, len); - if (!_oriented) { - _dots[to - 1].addPath(from, len); - } - return null; - } - //*********************Add************************ - - //*********Delete********* - String? delPath(int from, int to) { - if (from <= 0 || from > _amount || to <= 0 && to > _amount) { - return "Can't find specified path"; - } - _dots[from - 1].delPath(to); - if (!_oriented) { - _dots[to - 1].delPath(from); - } - return null; - } - - String? delDot(int inn) { - if (inn > _amount || inn < 1) { - return "Index out of range. Allowed 1..$_amount"; - } - List toDel = []; - for (int i in _dots[inn - 1].getL().keys) { - toDel.add(i); - } - for (int i in toDel) { - delPath(i, inn); - } - _dots.removeAt(inn - 1); - _syncNum(); - _syncNameTable(); - _fixAfterDel(inn); - return null; - } - - void flushData() { - _dots = []; - _amount = 0; - _nameTable = {}; - } - //*********Delete********* - - //******Helper******* - bool checkDots([bool verbose = false]) { - for (var a in _dots) { - for (var i in a.getL().keys) { - try { - if (!_dots[i - 1].getL().containsKey(a.num)) { - if (verbose) print("Can't find ${a.num}"); - return false; - } - } catch (e) { - if (verbose) { - print("Can't find Dot $i for path ${a.num}->$i. Exception $e"); - } - _dots[a.num - 1].getL().remove(i); - return false; - } - } - } - return true; - } - - void _fixAfterDel(int inn) { - for (int i = 0; i < _dots.length; i++) { - Map l = {}; - for (int j in _dots[i].getL().keys) { - if (j >= inn) { - l[j - 1] = _dots[i].getL()[j]!; - } else { - l[j] = _dots[i].getL()[j]!; - } - } - _dots[i] = Dot.fromMap(_dots[i].getName(), l, _dots[i].num); - } - } - - void _fixPathAfterInsert(Dot a) { - //Для неориентированного - for (var i in a.getL().keys) { - if (!_dots[i - 1].getL().containsKey(a.num)) { - addPath(i, a.num, a.getL()[i]!); - } - } - } - - void _fullFix() { - for (var i in _dots) { - _fixPathAfterInsert(i); - } - } - - void _syncNameTable() { - _nameTable = {}; - for (var i in _dots) { - _nameTable[i.num] = i.getName(); - } - } - - void _syncNum() { - _amount = 0; - for (var i in _dots) { - i.num = ++_amount; - } - _syncNameTable(); - } - //******Helper******* - - //*****Setters******* - void setName(String name) => _name = name; - String? flipUseOrientation() { - if (_amount != 0) { - return "Can change use of orientation only in empty graph"; - } - _oriented = !_oriented; - return null; - } - - String? flipUseLength() { - if (_amount != 0) { - return "Can change use of length only in empty graph"; - } - _useLength = !_useLength; - return null; - } - - String? replaceDataFromFile(String path) { - File file = File(path); - List lines = file.readAsLinesSync(); - if (lines.length < 3) { - return "Not enough lines in file"; - } - String name = lines.removeAt(0); - bool oriented; - switch (lines.removeAt(0)) { - case Separators.isOriented: - oriented = true; - break; - case Separators.isNotOriented: - oriented = false; - break; - default: - return "Error on parsing \"IsOriented\""; - } - bool useLength; - switch (lines.removeAt(0).trim()) { - case Separators.hasLength: - useLength = true; - break; - case Separators.hasNoLength: - useLength = false; - break; - default: - return "Error on parsing \"HasLength\""; - } - List dots = []; - for (var l in lines) { - l = l.trimRight(); - if (l != Separators.end) { - var spl = l.split(Separators.space); - List dot = []; - List len = []; - String name = spl.removeAt(0); - name = name.substring(0, name.length - 1); - for (var splitted in spl) { - if (splitted != "") { - var dt = splitted.split(Separators.dotToLength); - if (dt.length == 2) { - int? parsed = int.tryParse(dt[0]); - if (parsed == null) { - return "Error while parsing file\nin parsing int in \"${dt[0]}\""; - } - dot.add(parsed); - if (useLength) { - parsed = int.tryParse(dt[1]); - if (parsed == null) { - return "Error while parsing file\nin parsing int in \"${dt[1]}\""; - } - len.add(parsed); - } else { - len.add(0); - } - } else if (dt.length == 1) { - int? parsed = int.tryParse(splitted); - if (parsed == null) { - return "Error while parsing file\nin parsing int in \"$splitted\""; - } - dot.add(parsed); - len.add(0); - } - } - } - dots.add(Dot.fromTwoLists(name, dot, len)); - } - } - _name = name; - _oriented = oriented; - _useLength = useLength; - _dots = dots; - _syncNum(); - _syncNameTable(); - if (!_oriented) _fullFix(); - return null; - } - //*****Setters******* - - //*****Getters******* - bool getDoubleSidedBool() => _oriented; - String getDoubleSidedStr() { - if (_oriented) return Separators.isOriented; - return Separators.isNotOriented; - } - - bool getUseLengthBool() => _useLength; - String getUseLengthStr() { - if (_useLength) return Separators.hasLength; - return Separators.hasNoLength; - } - - List getDots() => _dots; - String getName() => _name; - String? getNameByNum(int n) => _nameTable[n]; - Map getNameTable() => _nameTable; - int getDotAmount() => _dots.length; - int? getNumByName(String n) { - for (var i in _nameTable.keys) { - if (_nameTable[i] == n) return i; - } - return null; - } - - List>? getLenTable() { - List>? out = >[]; - for (int i = 0; i < _amount; i++) { - List xx = []; - for (int j = 1; j <= _amount; j++) { - xx.add(_dots[i].getLength(j)); - } - out.add(xx); - } - return out; - } - - List>? getPathTable() { - List>? out = >[]; - for (int i = 0; i < _amount; i++) { - List xx = []; - for (int j = 1; j <= _amount; j++) { - if (_dots[i].getLength(j) != -1) { - xx.add(i); - } else { - xx.add(-1); - } - } - out.add(xx); - } - return out; - } - - /*List getNoRepeatDots() { - List ret = []; - for (int i = 0; i < _amount; i++) { - ret.add(Dot(_dots[i].getName(), _dots[i].num)); - } - for (int i = 0; i < _amount; i++) { - for (int j in _dots[i].getL().keys) { - if (!ret[j - 1].hasConnection(i + 1) && !ret[i].hasConnection(j) || - i == j) { - var len = _dots[i].getLength(j); - ret[i].addPath(j, len); - } - } - } - return ret; - }*/ - //*****Getters******* - - //******Print****** - void printG() { - stdout.write("$_name: "); - if (_oriented) { - stdout.write("Ориентированный, "); - } else { - stdout.write("Не ориентированный, "); - } - if (_useLength) { - print("Взвешенный"); - } else { - print("Не взвешенный"); - } - for (var i in _dots) { - i.printD(); - } - } - - void printToFile(String name) { - var file = File(name); - file.writeAsStringSync("$_name\n"); - if (_oriented) { - file.writeAsStringSync("${Separators.isOriented}\n", - mode: FileMode.append); - } else { - file.writeAsStringSync("${Separators.isNotOriented}\n", - mode: FileMode.append); - } - if (_useLength) { - file.writeAsStringSync("${Separators.hasLength}\n", - mode: FileMode.append); - } else { - file.writeAsStringSync("${Separators.hasNoLength}\n", - mode: FileMode.append); - } - for (int i = 0; i < _amount; i++) { - file.writeAsStringSync((i + 1).toString() + Separators.dotToConnections, - mode: FileMode.append); - var d = _dots[i].getL(); - for (var j in d.keys) { - file.writeAsStringSync( - j.toString() + Separators.dotToLength + d[j].toString() + " ", - mode: FileMode.append); - } - file.writeAsStringSync(Separators.nL, mode: FileMode.append); - } - file.writeAsStringSync(Separators.end, mode: FileMode.append); - } - //******Print****** - - //*******Constructor******** - Graphs( - [String name = "Undefined", - bool hasLen = false, - bool isOriented = false]) { - _name = name; - _dots = []; - _useLength = hasLen; - _oriented = isOriented; - _amount = 0; - _nameTable = {}; - } - Graphs.fromList(String name, List dots, bool hasLen, bool oriented) { - _name = name; - _dots = dots; - _useLength = hasLen; - _amount = _dots.length; - _oriented = oriented; - _syncNum(); - if (!_oriented) _fullFix(); - } - Graphs.fromFile(String path) { - replaceDataFromFile(path); - /*File file = File(path); - List lines = file.readAsLinesSync(); - _name = lines.removeAt(0); - _oriented = lines.removeAt(0) == Separators.isOriented.trim(); - _useLength = lines.removeAt(0) == Separators.hasLength.trim(); - _dots = []; - for (var l in lines) { - if (l != Separators.end) { - var spl = l.split(Separators.space); - List dot = []; - List len = []; - String name = spl.removeAt(0); - name = name.substring(0, name.length - 1); - for (var splitted in spl) { - var dt = splitted.split(Separators.dotToLength); - if (dt.length == 2) { - dot.add(int.parse(dt[0])); - if (_useLength) { - len.add(int.parse(dt[1])); - } else { - len.add(0); - } - } else if (dt.length == 1) { - dot.add(int.parse(splitted)); - len.add(0); - } - } - _dots.add(Dot.fromTwoLists(name, dot, len)); - } - } - _syncNum(); - _syncNameTable(); - if (!_oriented) _fullFix();*/ - } - //*******Constructor******** - - //Copy - Graphs.clone(Graphs a) { - _name = a.getName(); - _dots = a.getDots(); - _oriented = a.getDoubleSidedBool(); - _useLength = a.getUseLengthBool(); - _amount = _dots.length; - _syncNameTable(); - } - - //************Алгоритмы************ - /* bool bfsHasPath(int startDot, int goalDot) { - // обход в ширину - startDot--; - goalDot--; - List visited = []; - List queue = []; - for (int i = 0; i < _amount; i++) { - visited.add(false); - } // изначально список посещённых узлов пуст - queue.add(startDot); // начиная с узла-источника - visited[startDot] = true; - while (queue.isNotEmpty) { - // пока очередь не пуста - int node = queue.removeAt(0); // извлечь первый элемент в очереди - if (node == goalDot) { - return true; // проверить, не является ли текущий узел целевым - } - for (int child in _dots[node].getL().keys) { - // все преемники текущего узла, ... - if (!visited[child - 1]) { - // ... которые ещё не были посещены ... - queue.add(child - 1); // ... добавить в конец очереди... - visited[child - 1] = true; // ... и пометить как посещённые - } - } - } - return false; // Целевой узел недостижим - }*/ - - List? bfsPath(int startDot, int goalDot) { - if (startDot == goalDot) return [startDot]; - //if (!bfsHasPath(startDot, goalDot)) return null; - startDot--; - goalDot--; - List>? graph = getLenTable(); - List used = []; - List dst = []; - List pr = []; - - for (int i = 0; i < _amount; i++) { - dst.add(-1); - used.add(false); - pr.add(0); - } - - List q = []; - q.add(startDot); - used[startDot] = true; - dst[startDot] = 0; - pr[startDot] = - -1; //Пометка, означающая, что у вершины startDot нет предыдущей. - - 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 path = []; - - int cur = goalDot; //текущая вершина пути - path.add(cur + 1); - - while (pr[cur] != -1) { - //пока существует предыдущая вершина - cur = pr[cur]; //переходим в неё - path.add(cur + 1); //и дописываем к пути - } - - path = path.reversed.toList(); - - //print("Shortest path between vertices ${startDot+1} and ${goalDot+1} is: $path"); - if (path[0] == (startDot + 1) && - path[1] == (goalDot + 1) && - !_dots[startDot].hasConnection(goalDot + 1)) return null; - return path; - } - - List? dfsIterative(int v) { - v--; - //List? pos = []; - List label = []; - for (int i = 0; i < _amount; i++) { - label.add(false); - } - List stack = []; - 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); - } - } - } - //print(pos); - return label; - } - - void dijkstra(int source) { - /* - create vertex set Q; - - for each vertex v in Graph{ - dist[v] ← INFINITY ; - prev[v] ← UNDEFINED ; - add v to Q;} - dist[source] ← 0; - - while Q is not empty{ - u ← vertex in Q with min dist[u] - - remove u from Q - - for each neighbor v of u still in Q{ - alt ← dist[u] + length(u, v); - if alt < dist[v]: { - dist[v] ← alt; - prev[v] ← u;} - }} - return dist[], prev[]*/ - } - //************Алгоритмы************ -}