Website Summary Files Commits Branches @commit @diff @stats
path: root / Seminar11 / DFS-Additional.cpp
diff options
context:
space:
mode:
Commit7eee5a78005a9a569186d2c8b4b645a818ab9bf1 (patch)
Author
 Stoycho Kyosev <skyosev@192.168.100.17>
2024-10-06 07:04:44 -0400
Committer
 Stoycho Kyosev <skyosev@192.168.100.17>
2024-10-06 07:04:44 -0400
Files84594e0af29cefa5aae76ace5f8eb81484400e31 /Seminar11/DFS-Additional.cpp
Data-structures-and-algorithms-7eee5a78005a9a569186d2c8b4b645a818ab9bf1.tar
Data-structures-and-algorithms-7eee5a78005a9a569186d2c8b4b645a818ab9bf1.tar.gz
Data-structures-and-algorithms-7eee5a78005a9a569186d2c8b4b645a818ab9bf1.zip
Parent0841635826cb03c0e74cd75ec3c97c4c3b594d8b (diff)
Cleanup
1 files changed, 0 insertions, 200 deletions
-rw-r--r--Seminar11/DFS-Additional.cpp200
diff --git a/Seminar11/DFS-Additional.cpp b/Seminar11/DFS-Additional.cpp
deleted file mode 100644
index a5022e3..0000000
--- a/Seminar11/DFS-Additional.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-// Малко допълнителни неща покрай дфс ако ви е интересно.
-#include<iostream>
-#include"Graph-Impl/AdjacencyListGraph/AdjListGraph.h"
-#include"Graph-Impl/MatrixGraph/MatrixGraph.h"
-#include<vector>
-#include<algorithm>
-
-using std::vector;
-using vertex_t = AdjListGraph::vertex_t; // Типа представящ връх в графа
-
-class DFSExamples {
-private:
- vector<size_t> in;
- vector<size_t> out;
- vector<vertex_t> parent;
-
-public:
-
-void DFS_Visit(const AdjListGraph& g, size_t& time, vertex_t s) {
- in[s] = time;
- time++;
-
- const auto& adj = g.adjacent(s);
-
- for(const auto& v : adj) {
- if(in[v.to] == -1) {
- parent[v.to] = s;
- DFS_Visit(g, time, v.to);
- }
- }
-
- time++;
- out[s] = time;
-}
-
-void DFS(const AdjListGraph& g, bool showDetails) {
- // Нека си представим, че имаме време. Всяка стъпка на алгоритъма отнема една единица време.
- size_t time = 0;
-
- // Всеки връх бива открит в някакво време. Нека в този масив записваме кога е бил открит всеки връх.
- in = vector(g.vertexCount(), (size_t)(-1));
-
- // С всеки връх приключваме по някое време. Той няма повече непосетени съседи и спираме да се интересуваме от него.
- // Нека в този масив записваме кога се случва това.
- out = vector(g.vertexCount(), (size_t)(-1));
-
- // std::vector<bool> visited(g.vertexCount(), false);
- // - от този масив вече нямаме нужда. Връх v e посетен когато in[v] != -1.
-
- // Също така в примера видяхме, че DFS прави дърво. Нека си запазим това дърво.
- // Тук стандартното представяне на дърво е неудобно, затова ще представяме дървото като масив от бащите.
- // Примомняне: Ако v e връх parent[v] е бащата на v или -1 ако v e корен.
- parent = vector(g.vertexCount(), (vertex_t)(-1));
-
- // За всеки връх
- for (vertex_t i = 0; i < g.vertexCount(); i++)
- if(in[i] == -1) // Ако не е посетен
- DFS_Visit(g, time, i); // Посети го и посети всички върхове достижими от него
-
- // Да видим какво имаме
- if(showDetails) {
- for (vertex_t i = 0; i < g.vertexCount(); i++) {
- std::cout << "Vertex " << i << std::endl;
- std::cout
- << "Discovered at: " << in[i] << std::endl
- << "Finished at: " << out[i] << std::endl
- << "Parent: " << parent[i] << std::endl << std::endl;
- }
- }
-}
-
-void DFS_Visit_Tsort(const MatrixGraph g, size_t& time, vertex_t s) {
- in[s] = time;
- time++;
-
- const auto& adj = g.adjacent(s);
-
- for(const auto& v : adj) {
- if(in[v] == -1) {
- parent[v] = s;
- DFS_Visit_Tsort(g, time, v);
- }
- }
-
- time++;
- out[s] = time;
-}
-
-// Топологически сортировки, Job scheduling
-// Защо са ни тези масиви in и out? Те ни дават информация, която можем да използваме за други интересни алгоритми.
-// Ще оставим подробното им разглеждане на други курсове, тук само ще разгледаме един бърз пример.
-
-// Нека си представим, че имаме някакви задачи за вършене. Абсолютно вероятно е някои от тези задачи да зависят от други.
-// Примерно, не мога да кандидатствам за университет ако преди това нямам диплома за завършен 12 клас
-// (въпреки, че май е възможно в някои нови български университети).
-//
-// Можем да си представим задачите като върхове, а това, че задача А трябва да се изпълни преди задача Б да
-// бележим чрез ориентирано ребро А -> Б.
-//
-// Искам така да си подредя задачите, че да ги изпълня без да нарушавам зависимостите.
-//
-// Твърдя, че ако пусна DFS, и сортирам върховете по out стойности в намаляващ ред това решава задачата ми.
-//
-// Накратко, защо това е вярно?
-// Нека имам V -> U. Има два случая, или да открия V преди U или да открия U преди V.
-//
-// 1. Откривам V преди U. Да де, но имам ребро от V към U, Следователно ще открия и финализирам U преди да финализирам V.
-// Сега out[U] > out[V] и не нарушавам зависимостите.
-// 2. Ако открия U преди V, ще финализирам U преди да стигна до V. В графа няма цикли и ако имаше път от U -> V това би затворило цикъл.
-// Тоест ще финализирам U преди да открия V. От тук следва, че out[U] > in[V] > out[V], което отново влече наредба, която не нарушава зависимостите.
-// Няма други случаи.
-
-void DFS_Tsort(const MatrixGraph& g) {
- size_t time = 0;
-
- in = vector(g.vertexCount(), (size_t)(-1));
- out = vector(g.vertexCount(), (size_t)(-1));
- parent = vector(g.vertexCount(), (vertex_t)(-1));
-
- for (vertex_t i = 0; i < g.vertexCount(); i++)
- if(in[i] == -1)
- DFS_Visit_Tsort(g, time, i);
-
- std::vector<std::pair<vertex_t, size_t>> result(g.vertexCount());
-
- for (vertex_t i = 0; i < g.vertexCount(); i++)
- result[i] = {i, out[i]};
-
- auto comp = [](std::pair<vertex_t, size_t>& fst, std::pair<vertex_t, size_t>& snd) -> bool {
- return fst.second > snd.second;
- };
-
- std::sort(result.begin(), result.end(), comp);
-
- for(const auto& vertexOutPair : result)
- std::cout << vertexOutPair.first << " ";
-}
-
-// Използвам матричния, понеже той е ориентиран.
-void tsort(const MatrixGraph& g) {
- size_t time = 0;
-
- // Нулираме масивите
- in = vector(g.vertexCount(), (size_t)(-1));
- out = vector(g.vertexCount(), (size_t)(-1));
- parent = vector(g.vertexCount(), (vertex_t)(-1));
-
- DFS_Tsort(g);
-}
-};
-
-int main() {
- DFSExamples d;
-
- // Нека си вземем графа от примера
- // Там върховете са номерирани от 1 до 12
- // Тук от 0 до 11
- AdjListGraph g(12);
-
- g.addEdge(0, 2, 1);
- g.addEdge(0, 4, 1);
- g.addEdge(0, 5, 1);
- g.addEdge(0, 8, 1);
-
- g.addEdge(1, 7, 1);
- g.addEdge(1, 3, 1);
-
- g.addEdge(2, 4, 1);
- g.addEdge(2, 5, 1);
- g.addEdge(2, 6, 1);
- g.addEdge(2, 7, 1);
-
- g.addEdge(3, 9, 1);
-
- g.addEdge(4, 6, 1);
-
- g.addEdge(8, 11, 1);
- g.addEdge(8, 10, 1);
-
- g.addEdge(10, 11, 1);
-
- d.DFS(g, true);
-
- // Пример за топосортировка
- MatrixGraph tsort(9);
-
-
- // https://ocw.mit.edu/courses/6-006-introduction-to-algorithms-fall-2011/resources/mit6_006f11_lec14_orig/
- // Този граф е взет от линка и е на страница 5.
- tsort.addDirectedEdge(5, 3, 1);
- tsort.addDirectedEdge(4, 3, 1);
- tsort.addDirectedEdge(4, 2, 1);
- tsort.addDirectedEdge(2, 1, 1);
- tsort.addDirectedEdge(1, 0, 1);
- tsort.addDirectedEdge(7, 2, 1);
- tsort.addDirectedEdge(7, 6, 1);
- tsort.addDirectedEdge(6, 1, 1);
-
- d.DFS_Tsort(tsort);
-} \ No newline at end of file