diff --git a/bin/src/graph.dart b/bin/src/graph.dart index 581b7b6..8778490 100644 --- a/bin/src/graph.dart +++ b/bin/src/graph.dart @@ -255,7 +255,7 @@ class Graphs { return null; } - List>? getTable() { + List>? getLenTable() { List>? out = >[]; for (int i = 0; i < _amount; i++) { List xx = []; @@ -266,6 +266,22 @@ class Graphs { } 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; + } //*****Getters******* //******Print****** @@ -316,11 +332,14 @@ class Graphs { //******Print****** //*******Constructor******** - Graphs() { - _name = "Udefined"; + Graphs( + [String name = "Undefined", + bool hasLen = false, + bool isOriented = false]) { + _name = name; _dots = []; - _useLength = false; - _oriented = false; + _useLength = hasLen; + _oriented = isOriented; _amount = 0; _nameTable = {}; } @@ -338,8 +357,8 @@ class Graphs { File file = File(path); List lines = file.readAsLinesSync(); _name = lines.removeAt(0); - _oriented = lines.removeAt(0) == sep.isOriented; - _useLength = lines.removeAt(0) == sep.hasLength; + _oriented = lines.removeAt(0) == sep.isOriented.trim(); + _useLength = lines.removeAt(0) == sep.hasLength.trim(); _dots = []; for (var l in lines) { if (l != sep.end) { @@ -373,4 +392,94 @@ class Graphs { _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 (!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 && path[1]==goalDot && !_dots[startDot].hasConnection(goalDot+1)) return null; + return path; + } + //************Алгоритмы************ }