From b378a97d043842a058eac39f4b70f501c02441a7 Mon Sep 17 00:00:00 2001 From: Vanek <123vanichka321@gmail.com> Date: Wed, 23 Oct 2024 19:33:32 +0300 Subject: [PATCH 01/11] add task 1, task 2, lib --- .gitignore | 4 +- lib/CMakeLists.txt | 5 +- lib/src/Graph.h | 16 +++ lib/src/GraphDFSIterator.cpp | 38 +++++++ lib/src/GraphDFSIterator.h | 27 +++++ lib/src/NonOrientedGraph.cpp | 44 ++++++++ lib/src/NonOrientedGraph.h | 22 ++++ lib/src/OrientedGraph.cpp | 42 +++++++ lib/src/OrientedGraph.h | 12 ++ lib/src/WeightedGraph.cpp | 158 +++++++++++++++++++++++++++ lib/src/WeightedGraph.h | 31 ++++++ lib/src/WeightedNonOrientedGraph.cpp | 44 ++++++++ lib/src/WeightedNonOrientedGraph.h | 12 ++ lib/src/WeightedOrientedGraph.cpp | 42 +++++++ lib/src/WeightedOrientedGraph.h | 12 ++ lib/src/includes.h | 12 ++ lib/src/util.cpp | 52 ++++++++- lib/src/util.h | 12 ++ lib/src/util.hpp | 0 task_01/CMakeLists.txt | 4 +- task_01/src/main.cpp | 39 ++++++- task_01/src/topologicalSort.cpp | 44 ++++++++ task_01/src/topologicalSort.h | 7 ++ task_02/README.md | 2 +- task_02/src/SearchWeakVE.cpp | 43 ++++++++ task_02/src/SearchWeakVE.h | 7 ++ task_02/src/main.cpp | 40 ++++++- task_02/src/stack.cpp | 21 ---- task_02/src/stack.hpp | 23 ---- task_02/src/test.cpp | 42 ------- task_03/src/test.cpp | 8 -- task_03/src/topology_sort.cpp | 1 - task_03/src/topology_sort.hpp | 1 - 33 files changed, 763 insertions(+), 104 deletions(-) create mode 100644 lib/src/Graph.h create mode 100644 lib/src/GraphDFSIterator.cpp create mode 100644 lib/src/GraphDFSIterator.h create mode 100644 lib/src/NonOrientedGraph.cpp create mode 100644 lib/src/NonOrientedGraph.h create mode 100644 lib/src/OrientedGraph.cpp create mode 100644 lib/src/OrientedGraph.h create mode 100644 lib/src/WeightedGraph.cpp create mode 100644 lib/src/WeightedGraph.h create mode 100644 lib/src/WeightedNonOrientedGraph.cpp create mode 100644 lib/src/WeightedNonOrientedGraph.h create mode 100644 lib/src/WeightedOrientedGraph.cpp create mode 100644 lib/src/WeightedOrientedGraph.h create mode 100644 lib/src/includes.h create mode 100644 lib/src/util.h delete mode 100644 lib/src/util.hpp create mode 100644 task_01/src/topologicalSort.cpp create mode 100644 task_01/src/topologicalSort.h create mode 100644 task_02/src/SearchWeakVE.cpp create mode 100644 task_02/src/SearchWeakVE.h delete mode 100644 task_02/src/stack.cpp delete mode 100644 task_02/src/stack.hpp delete mode 100644 task_02/src/test.cpp delete mode 100644 task_03/src/test.cpp delete mode 100644 task_03/src/topology_sort.cpp delete mode 100644 task_03/src/topology_sort.hpp diff --git a/.gitignore b/.gitignore index 41f1b1b..6fee36c 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,6 @@ _deps .cache/* .vscode/* -build/* \ No newline at end of file +build/* +.vs +WeightedGraph.i diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 98320e1..f2cf684 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -3,7 +3,10 @@ project(Utils) set(CMAKE_CXX_STANDARD 23) -file(GLOB_RECURSE lib_source_list "src/*.cpp" "src/*.hpp") +file(GLOB_RECURSE lib_source_list "src/*.cpp") + +SET(BASEPATH "${CMAKE_SOURCE_DIR}") +INCLUDE_DIRECTORIES("${BASEPATH}") add_library(${PROJECT_NAME} ${lib_source_list}) diff --git a/lib/src/Graph.h b/lib/src/Graph.h new file mode 100644 index 0000000..acff929 --- /dev/null +++ b/lib/src/Graph.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include + +class Graph : public WeightedGraph +{ + int GetEdges() + { + int result = 0; + for (int i = 0; i < graph.size(); ++i) + result += sum(graph[i]); + return result; + } +}; \ No newline at end of file diff --git a/lib/src/GraphDFSIterator.cpp b/lib/src/GraphDFSIterator.cpp new file mode 100644 index 0000000..00acd40 --- /dev/null +++ b/lib/src/GraphDFSIterator.cpp @@ -0,0 +1,38 @@ +#include + +GraphDFSIterator::GraphDFSIterator(const WeightedGraph* const graph, int start_id) +{ + this->start_id = start_id; + this->graph = graph; + this->is_end = false; + this_id = start_id; + visited.resize(graph->GetVerts()); + visited[start_id] = true; + parent.resize(graph->GetVerts(), -1); +} + +int GraphDFSIterator::Next() +{ + for (int i = 0; i < graph->GetVerts(); ++i) + { + if ((*graph)[this_id][i] != 0 && !visited[i]) + { + visited[i] = true; + parent[i] = this_id; + this_id = i; + return i; + } + } + if (parent[this_id] == -1) + { + is_end = true; + return this_id; + } + this_id = parent[this_id]; + return Next(); +} + +bool GraphDFSIterator::IsEnd() +{ + return is_end; +} \ No newline at end of file diff --git a/lib/src/GraphDFSIterator.h b/lib/src/GraphDFSIterator.h new file mode 100644 index 0000000..7451627 --- /dev/null +++ b/lib/src/GraphDFSIterator.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +class WeightedGraph; + +class GraphDFSIterator +{ + const WeightedGraph* graph; + int start_id; + int this_id; + bool is_end; + std::vector visited; + std::vector parent; + + int Next(); + +public: + GraphDFSIterator() = delete; + GraphDFSIterator(const WeightedGraph* const graph, int start_id); + + int operator++() { return Next(); } + int operator()() { return this_id; } + bool IsEnd(); +}; \ No newline at end of file diff --git a/lib/src/NonOrientedGraph.cpp b/lib/src/NonOrientedGraph.cpp new file mode 100644 index 0000000..954d0a6 --- /dev/null +++ b/lib/src/NonOrientedGraph.cpp @@ -0,0 +1,44 @@ +#include "NonOrientedGraph.h" + +bool NonOrientedGraph::AddVert(int id) +{ + if (id >= graph.size()) + { + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) + { + graph[i].resize(id + 1); + graph[i][i] = 1; + } + } + return false; +} + +bool NonOrientedGraph::AddEdge(int id0, int id1) +{ + if (id0 == id1) + return true; + AddVert(std::max(id0, id1)); + graph[id0][id1] = 1; + graph[id1][id0] = 1; + return false; +} + +bool NonOrientedGraph::DeleteVert(int id) +{ + if (id >= graph.size()) + return true; + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) + graph[i].resize(id + 1); + return false; +} + +bool NonOrientedGraph::DeleteEdge(int id0, int id1) +{ + if (id0 == id1 || std::max(id0, id1) >= graph.size()) + return true; + graph[id0][id1] = 0; + graph[id1][id0] = 0; + return false; +} \ No newline at end of file diff --git a/lib/src/NonOrientedGraph.h b/lib/src/NonOrientedGraph.h new file mode 100644 index 0000000..4971643 --- /dev/null +++ b/lib/src/NonOrientedGraph.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include "Graph.h" +#include "util.h" + +class NonOrientedGraph : public Graph +{ +public: + int GetEdges() + { + int result = 0; + for (int i = 0; i < graph.size(); ++i) + result += sum(graph[i]); + return result / 2; + } + bool AddVert(int id); + bool AddEdge(int id0, int id1); + bool DeleteVert(int id); + bool DeleteEdge(int id0, int id1); +}; \ No newline at end of file diff --git a/lib/src/OrientedGraph.cpp b/lib/src/OrientedGraph.cpp new file mode 100644 index 0000000..b441fc5 --- /dev/null +++ b/lib/src/OrientedGraph.cpp @@ -0,0 +1,42 @@ +#include "OrientedGraph.h" + +bool OrientedGraph::AddVert(int id) +{ + if (id >= graph.size()) + { + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) + { + graph[i].resize(id + 1); + graph[i][i] = 1; + } + } + return false; +} + +bool OrientedGraph::AddEdge(int id0, int id1) +{ + if (id0 == id1) + return true; + AddVert(std::max(id0, id1)); + graph[id0][id1] = 1; + return false; +} + +bool OrientedGraph::DeleteVert(int id) +{ + if (id >= graph.size()) + return true; + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) + graph[i].resize(id + 1); + return false; +} + +bool OrientedGraph::DeleteEdge(int id0, int id1) +{ + if (id0 == id1 || std::max(id0, id1) >= graph.size()) + return true; + graph[id0][id1] = 0; + return false; +} \ No newline at end of file diff --git a/lib/src/OrientedGraph.h b/lib/src/OrientedGraph.h new file mode 100644 index 0000000..3e659ec --- /dev/null +++ b/lib/src/OrientedGraph.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Graph.h" + +class OrientedGraph : public Graph +{ +public: + bool AddVert(int id); + bool AddEdge(int id0, int id1); + bool DeleteVert(int id); + bool DeleteEdge(int id0, int id1); +}; \ No newline at end of file diff --git a/lib/src/WeightedGraph.cpp b/lib/src/WeightedGraph.cpp new file mode 100644 index 0000000..24ae4ad --- /dev/null +++ b/lib/src/WeightedGraph.cpp @@ -0,0 +1,158 @@ +#include "WeightedGraph.h" + +int WeightedGraph::GetEdges() const +{ + int result = 0; + for (int i = 0; i < graph.size(); ++i) + for (int j = 0; j < graph.size(); ++j) + if (graph[i][j]) + ++result; + return result - graph.size(); +} + +bool WeightedGraph::IsCycled(int id, std::vector& result, std::vector& visited) const +{ + for (int i = 0; i < graph.size(); ++i) + { + if (graph[id][i] && !visited[i]) + { + visited[i] = true; + if (IsCycled(i, result, visited)) + return true; + result.push_back(i); + } + else if (graph[id][i] && visited[i] && i != id) + { + if (!in(result, i)) + return true; + } + } + return false; +} + +bool WeightedGraph::IsCycled() const +{ + std::vector result; + std::vector visited(graph.size()); + visited[0] = true; + return IsCycled(0, result, visited); +} + +void WeightedGraph::Print() const +{ + for (int i = 0; i < graph.size(); ++i) + { + for (int j = 0; j < graph.size(); ++j) + std::cout << graph[i][j] << ", "; + std::cout << '\n'; + } +} + +bool WeightedGraph::SwapIds(int id0, int id1) +{ + if (std::max(id0, id1) >= graph.size() || id0 == id1) + return true; + if (id0 > id1) + std::swap(id0, id1); + + for (int i = 0; i < graph.size(); ++i) + std::swap(graph[i][id0], graph[i][id1]); + std::swap(graph[id0], graph[id1]); + return false; +} + +void WeightedGraph::DFS(int id, std::vector& result, std::vector& visited, bool before) +{ + for (int i = 0; i < graph.size(); ++i) + { + if (graph[id][i] && !visited[i]) + { + visited[i] = true; + if (!before) + result.push_back(i); + DFS(i, result, visited); + if (before) + result.push_back(i); + } + } +} + +std::vector WeightedGraph::DFS(int id, bool before) +{ + std::vector visited(graph.size()); + std::vector result; + visited[id] = true; + if (!before) + result.push_back(id); + + for (int i = 0; i < graph.size(); ++i) + { + if (graph[id][i] && !visited[i]) + { + visited[i] = true; + if (!before) + result.push_back(i); + DFS(i, result, visited); + if (before) + result.push_back(i); + } + } + if (before) + result.push_back(id); + + return result; +} + +std::vector WeightedGraph::DFS(bool before) +{ + return DFS(0, before); +} + +void WeightedGraph::BFS(int id, std::vector& result, std::vector& visited) +{ + std::vector need_visit; + for (int i = 0; i < graph.size(); ++i) + { + if (graph[id][i] && !visited[i]) + { + visited[i] = true; + result.push_back(i); + need_visit.push_back(i); + } + } + for (int i = 0; i < need_visit.size(); ++i) + { + if (!visited[need_visit[i]]) + BFS(need_visit[i], result, visited); + } +} + +std::vector WeightedGraph::BFS(int id) +{ + std::vector visited(graph.size()); + std::vector result; + visited[id] = true; + result.push_back(id); + + std::vector need_visit; + + for (int i = 0; i < graph.size(); ++i) + { + if (graph[id][i] && !visited[i]) + { + visited[i] = true; + result.push_back(i); + need_visit.push_back(i); + } + } + for (int i = 0; i < need_visit.size(); ++i) + { + BFS(need_visit[i], result, visited); + } + return result; +} + +std::vector WeightedGraph::BFS() +{ + return BFS(0); +} \ No newline at end of file diff --git a/lib/src/WeightedGraph.h b/lib/src/WeightedGraph.h new file mode 100644 index 0000000..8b2b515 --- /dev/null +++ b/lib/src/WeightedGraph.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include + +class WeightedGraph +{ +protected: + std::vector> graph; + + bool IsCycled(int id_start, std::vector& result, std::vector& visited) const; + void DFS(int id_start, std::vector& result, std::vector& visited, bool after = false); + void BFS(int id_start, std::vector& result, std::vector& visited); + +public: + const std::vector& operator[](int i) const { return graph[i]; } + std::vector& operator[](int i) { return graph[i]; } + int GetVerts() const { return graph.size(); } + int GetEdges() const; + bool IsCycled() const; + void Print() const; + + bool SwapIds(int id0, int id1); + + std::vector DFS(int id_start, bool after = false); + std::vector DFS(bool after = false); + std::vector BFS(int id_start); + std::vector BFS(); + +}; \ No newline at end of file diff --git a/lib/src/WeightedNonOrientedGraph.cpp b/lib/src/WeightedNonOrientedGraph.cpp new file mode 100644 index 0000000..96ed840 --- /dev/null +++ b/lib/src/WeightedNonOrientedGraph.cpp @@ -0,0 +1,44 @@ +#include "WeightedNonOrientedGraph.h" + +bool WeightedNonOrientedGraph::AddVert(int id) +{ + if (id >= graph.size()) + { + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) + { + graph[i].resize(id + 1); + graph[i][i] = 1; + } + } + return false; +} + +bool WeightedNonOrientedGraph::AddEdge(int id0, int id1, double value) +{ + if (id0 == id1) + return true; + AddVert(std::max(id0, id1)); + graph[id0][id1] = value; + graph[id1][id0] = value; + return false; +} + +bool WeightedNonOrientedGraph::DeleteVert(int id) +{ + if (id >= graph.size()) + return true; + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) + graph[i].resize(id + 1); + return false; +} + +bool WeightedNonOrientedGraph::DeleteEdge(int id0, int id1) +{ + if (id0 == id1 || std::max(id0, id1) >= graph.size()) + return true; + graph[id0][id1] = 0; + graph[id1][id0] = 0; + return false; +} \ No newline at end of file diff --git a/lib/src/WeightedNonOrientedGraph.h b/lib/src/WeightedNonOrientedGraph.h new file mode 100644 index 0000000..080a96c --- /dev/null +++ b/lib/src/WeightedNonOrientedGraph.h @@ -0,0 +1,12 @@ +#pragma once + +#include "WeightedGraph.h" + +class WeightedNonOrientedGraph : public WeightedGraph +{ +public: + bool AddVert(int id); + bool AddEdge(int id0, int id1, double value); + bool DeleteVert(int id); + bool DeleteEdge(int id0, int id1); +}; \ No newline at end of file diff --git a/lib/src/WeightedOrientedGraph.cpp b/lib/src/WeightedOrientedGraph.cpp new file mode 100644 index 0000000..cdd638b --- /dev/null +++ b/lib/src/WeightedOrientedGraph.cpp @@ -0,0 +1,42 @@ +#include "WeightedOrientedGraph.h" + +bool WeightedOrientedGraph::AddVert(int id) +{ + if (id >= graph.size()) + { + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) + { + graph[i].resize(id + 1); + graph[i][i] = 1; + } + } + return false; +} + +bool WeightedOrientedGraph::AddEdge(int id0, int id1, double value) +{ + if (id0 == id1) + return true; + AddVert(std::max(id0, id1)); + graph[id0][id1] = value; + return false; +} + +bool WeightedOrientedGraph::DeleteVert(int id) +{ + if (id >= graph.size()) + return true; + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) + graph[i].resize(id + 1); + return false; +} + +bool WeightedOrientedGraph::DeleteEdge(int id0, int id1) +{ + if (id0 == id1 || std::max(id0, id1) >= graph.size()) + return true; + graph[id0][id1] = 0; + return false; +} \ No newline at end of file diff --git a/lib/src/WeightedOrientedGraph.h b/lib/src/WeightedOrientedGraph.h new file mode 100644 index 0000000..f5e60d2 --- /dev/null +++ b/lib/src/WeightedOrientedGraph.h @@ -0,0 +1,12 @@ +#pragma once + +#include "WeightedGraph.h" + +class WeightedOrientedGraph : public WeightedGraph +{ +public: + bool AddVert(int id); + bool AddEdge(int id0, int id1, double value); + bool DeleteVert(int id); + bool DeleteEdge(int id0, int id1); +}; \ No newline at end of file diff --git a/lib/src/includes.h b/lib/src/includes.h new file mode 100644 index 0000000..8a6a7a4 --- /dev/null +++ b/lib/src/includes.h @@ -0,0 +1,12 @@ +#pragma once + +#include "WeightedGraph.h" +#include "WeightedOrientedGraph.h" +#include "WeightedNonOrientedGraph.h" +#include "Graph.h" +#include "OrientedGraph.h" +#include "NonOrientedGraph.h" + +#include "GraphDFSIterator.h" + +#include "util.h" \ No newline at end of file diff --git a/lib/src/util.cpp b/lib/src/util.cpp index 81e15bd..83cf442 100644 --- a/lib/src/util.cpp +++ b/lib/src/util.cpp @@ -1 +1,51 @@ -#include "util.hpp" +#include "util.h" + +int partition(std::vector& vec, int low, int high) +{ + int pivot = vec[high]; + int i = (low - 1); + + for (int j = low; j <= high - 1; j++) { + if (vec[j] <= pivot) { + i++; + std::swap(vec[i], vec[j]); + } + } + std::swap(vec[i + 1], vec[high]); + return (i + 1); +} + +void quickSort(std::vector& vec, int low, int high) +{ + if (low < high) { + int pi = partition(vec, low, high); + quickSort(vec, low, pi - 1); + quickSort(vec, pi + 1, high); + } +} + +void bubbleSort(std::vector& vec) { + int n = vec.size(); + for (int i = 0; i < n - 1; i++) { + for (int j = 0; j < n - i - 1; j++) { + if (vec[j] > vec[j + 1]) + std::swap(vec[j], vec[j + 1]); + } + } +} + +bool in(const std::vector& vec, int value) +{ + for (int i = 0; i < vec.size(); ++i) + if (vec[i] == value) + return true; + return false; +} + +int sum(const std::vector& vec) +{ + int result = 0; + for (auto value : vec) + result += value; + return result; +} \ No newline at end of file diff --git a/lib/src/util.h b/lib/src/util.h new file mode 100644 index 0000000..89bab2a --- /dev/null +++ b/lib/src/util.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +int partition(std::vector& vec, int low, int high); +void quickSort(std::vector& vec, int low, int high); + +void bubbleSort(std::vector& vec); + +bool in(const std::vector& vec, int value); + +int sum(const std::vector& vec); \ No newline at end of file diff --git a/lib/src/util.hpp b/lib/src/util.hpp deleted file mode 100644 index e69de29..0000000 diff --git a/task_01/CMakeLists.txt b/task_01/CMakeLists.txt index 6612735..0dd92e2 100644 --- a/task_01/CMakeLists.txt +++ b/task_01/CMakeLists.txt @@ -17,7 +17,7 @@ list(REMOVE_ITEM source_list ${test_list}) include_directories(${PROJECT_NAME} PUBLIC src) -add_executable(${PROJECT_NAME} ${source_list}) +add_executable(${PROJECT_NAME} ${source_list} "src/topologicalSort.cpp") # Locate GTest enable_testing() @@ -29,7 +29,7 @@ find_library(Utils ../) target_link_libraries(${PROJECT_NAME} PUBLIC Utils) # Link runTests with what we want to test and the GTest and pthread library -add_executable(${PROJECT_NAME}_tests ${test_source_list}) +add_executable(${PROJECT_NAME}_tests ${test_source_list} "src/topologicalSort.cpp") target_link_libraries( ${PROJECT_NAME}_tests GTest::gtest_main diff --git a/task_01/src/main.cpp b/task_01/src/main.cpp index 76e8197..3bc8a22 100644 --- a/task_01/src/main.cpp +++ b/task_01/src/main.cpp @@ -1 +1,38 @@ -int main() { return 0; } +#include +#include "topologicalSort.h" + +std::ostream& operator<<(std::ostream& os, const std::vector& vec) +{ + for (int i = 0; i < vec.size(); ++i) + os << vec[i] << ", "; + return os; +} + +int main() +{ + OrientedGraph graph; + graph.AddEdge(0, 3); + graph.AddEdge(3, 1); + graph.AddEdge(3, 2); + graph.AddEdge(2, 1); + graph.Print(); + std::cout << std::endl; + + std::cout << "DFS ITERATION: "; + for (auto iter = GraphDFSIterator(&graph, 0); !iter.IsEnd(); ++iter) + { + std::cout << iter() << ", "; + } + std::cout << std::endl; + + std::cout << "IsCycled: " << graph.IsCycled() << std::endl; + + std::cout << "DFS: " << graph.DFS() << std::endl; + std::cout << "after DFS: " << graph.DFS(true) << std::endl; + std::cout << "BFS: " << graph.BFS() << std::endl; + + auto top_graph = topologicalSort(graph); + std::cout << "topological sort: " << top_graph << std::endl; + topologicalSorted(graph); + graph.Print(); +} diff --git a/task_01/src/topologicalSort.cpp b/task_01/src/topologicalSort.cpp new file mode 100644 index 0000000..62db767 --- /dev/null +++ b/task_01/src/topologicalSort.cpp @@ -0,0 +1,44 @@ +#include "topologicalSort.h" + +std::vector topologicalSort(WeightedGraph& graph) +{ + if (graph.IsCycled()) + return std::vector{-1}; + + auto dfs = graph.DFS(true); + std::vector rdfs(dfs.size()); + for (int i = 0; i < dfs.size(); ++i) + rdfs[graph.GetVerts() - 1 - i] = dfs[i]; + return rdfs; +} + +bool topologicalSorted(WeightedGraph& graph) +{ + auto rdfs = topologicalSort(graph); + if (rdfs.size() == 1 && rdfs[0] == -1) + return true; + std::vector positions(graph.GetVerts()); + for (int i = 0; i < graph.GetVerts(); ++i) + positions[i] = i; + for (int i = 0; i < graph.GetVerts(); ++i) + { + int finded_id = -1; + for (int j = i; j < positions.size(); ++j) + if (positions[j] == rdfs[i]) + { + finded_id = j; + break; + } + graph.SwapIds(i, finded_id); + std::swap(positions[i], positions[finded_id]); + } + return false; +} + +WeightedGraph* topologicalSorting(WeightedGraph& graph) +{ + WeightedGraph* new_graph = new WeightedGraph(graph); + if (topologicalSorted(*new_graph)) + return nullptr; + return new_graph; +} \ No newline at end of file diff --git a/task_01/src/topologicalSort.h b/task_01/src/topologicalSort.h new file mode 100644 index 0000000..f85bd8c --- /dev/null +++ b/task_01/src/topologicalSort.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +std::vector topologicalSort(WeightedGraph& graph); +bool topologicalSorted(WeightedGraph& graph); +WeightedGraph* topologicalSorting(WeightedGraph& graph); \ No newline at end of file diff --git a/task_02/README.md b/task_02/README.md index 281bafb..2691b57 100644 --- a/task_02/README.md +++ b/task_02/README.md @@ -1,3 +1,3 @@ -# Задача: + # Задача: В городе N горожане одного из районов создали локальную сеть для того, чтобы обмениваться информацией и играть вместе по сети. У них было n роутеров. Между роутерами как-то были проложены кабели. Когда-то один нерадивый коммунальщик перерезал один из проводов, и сеть стала не связной. Пользователи восстановили этот провод и решили найти узкие места сети для того, чтобы позже устранить их. Для этого они решили найти провода, при повреждении которых сеть потеряет связность, и заодно ещё найти те роутеры, при выходе из строя которых сеть также потеряет связность. Задача состоит в том, чтобы помочь пользователям сделать свою сеть надежнее. \ No newline at end of file diff --git a/task_02/src/SearchWeakVE.cpp b/task_02/src/SearchWeakVE.cpp new file mode 100644 index 0000000..e203e3d --- /dev/null +++ b/task_02/src/SearchWeakVE.cpp @@ -0,0 +1,43 @@ +#include "SearchWeakVE.h" + +void dfs(WeakVE& result, const WeightedGraph& graph, int id, int parent, std::vector& disc, std::vector& low, std::vector& visited, int& time) +{ + disc[id] = time; + low[id] = time; + ++time; + visited[id] = true; + for (int i = 0; i < graph.GetVerts(); ++i) + { + if (graph[id][i] && !visited[i]) + { + dfs(result, graph, i, id, disc, low, visited, time); + low[id] = std::min(low[id], low[i]); + if (low[i] > disc[id]) + result.second.push_back(std::make_pair(id, i)); + if (parent != -1 && low[i] >= disc[id]) + result.first.push_back(id); + } + else if (graph[id][i] && i != parent) + low[id] = std::min(low[id], low[i]); + } +} + +WeakVE SearchWeakVE(const WeightedGraph& graph) +{ + WeakVE result; + std::vector disc(graph.GetVerts()); + std::vector low(graph.GetVerts()); + std::vector visited(graph.GetVerts()); + int time = 0; + int start_id = 0; + dfs(result, graph, start_id, -1, disc, low, visited, time); + int num_start_id_daughters = 0; + for (int i = 0; i < graph.GetVerts(); ++i) + { + if (graph[start_id][i] != 0) + ++num_start_id_daughters; + } + if (num_start_id_daughters > 1) + result.first.push_back(start_id); + return result; +} \ No newline at end of file diff --git a/task_02/src/SearchWeakVE.h b/task_02/src/SearchWeakVE.h new file mode 100644 index 0000000..853c252 --- /dev/null +++ b/task_02/src/SearchWeakVE.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +#define WeakVE std::pair, std::vector>> + +WeakVE SearchWeakVE(const WeightedGraph& graph); \ No newline at end of file diff --git a/task_02/src/main.cpp b/task_02/src/main.cpp index 0e4393b..0c8258d 100644 --- a/task_02/src/main.cpp +++ b/task_02/src/main.cpp @@ -1,3 +1,41 @@ #include -int main() { return 0; } +#include +#include "SearchWeakVE.h" + +int main() +{ + NonOrientedGraph graph; + graph.AddEdge(0, 1); + graph.AddEdge(0, 2); + graph.AddEdge(1, 2); + graph.AddEdge(2, 3); + graph.AddEdge(3, 4); + + //graph.AddEdge(0, 1); + //graph.AddEdge(1, 2); + //graph.AddEdge(2, 3); + //graph.AddEdge(1, 3); + //graph.AddEdge(3, 4); + //graph.AddEdge(4, 5); + //graph.AddEdge(5, 6); + //graph.AddEdge(6, 7); + //graph.AddEdge(7, 4); + graph.AddEdge(0, 1); + graph.AddEdge(1, 2); + graph.AddEdge(0, 2); + graph.AddEdge(2, 3); + graph.AddEdge(3, 4); + graph.AddEdge(3, 5); + graph.AddEdge(4, 5); + graph.Print(); + WeakVE result = SearchWeakVE(graph); + std::cout << "Weak Points: "; + for (int i = 0; i < result.first.size(); ++i) + std::cout << result.first[i] << ", "; + std::cout << "\nWeak Edges: "; + for (int i = 0; i < result.second.size(); ++i) + std::cout << "(" << result.second[i].first << ", " << result.second[i].second << "); "; + std::cout << std::endl; + return 0; +} diff --git a/task_02/src/stack.cpp b/task_02/src/stack.cpp deleted file mode 100644 index 8ca8990..0000000 --- a/task_02/src/stack.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "stack.hpp" - -#include - -void Stack::Push(int value) { data_.push(value); } - -int Stack::Pop() { - auto result = data_.top(); - data_.pop(); - return result; -} - -void MinStack::Push(int value) { data_.push_back(value); } - -int MinStack::Pop() { - auto result = data_.back(); - data_.pop_back(); - return result; -} - -int MinStack::GetMin() { return *std::min_element(data_.begin(), data_.end()); } \ No newline at end of file diff --git a/task_02/src/stack.hpp b/task_02/src/stack.hpp deleted file mode 100644 index 138ec40..0000000 --- a/task_02/src/stack.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include - -class Stack { - public: - void Push(int value); - int Pop(); - - private: - std::stack data_; -}; - -class MinStack { - public: - void Push(int value); - int Pop(); - int GetMin(); - - private: - std::vector data_; -}; diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp deleted file mode 100644 index 54e7ce9..0000000 --- a/task_02/src/test.cpp +++ /dev/null @@ -1,42 +0,0 @@ - -#include - -#include - -#include "stack.hpp" - -TEST(StackTest, Simple) { - Stack stack; - stack.Push(1); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - stack.Push(3); // Stack [1, 3] - ASSERT_EQ(stack.Pop(), 3); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] -} - -TEST(MinStackTest, Simple) { - MinStack stack; - stack.Push(1); // Stack [1] - ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - stack.Push(3); // Stack [1, 3] - ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 3); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] -} \ No newline at end of file diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp deleted file mode 100644 index ef5a86a..0000000 --- a/task_03/src/test.cpp +++ /dev/null @@ -1,8 +0,0 @@ - -#include - -#include "topology_sort.hpp" - -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] -} diff --git a/task_03/src/topology_sort.cpp b/task_03/src/topology_sort.cpp deleted file mode 100644 index e53f670..0000000 --- a/task_03/src/topology_sort.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "topology_sort.hpp" diff --git a/task_03/src/topology_sort.hpp b/task_03/src/topology_sort.hpp deleted file mode 100644 index 6f70f09..0000000 --- a/task_03/src/topology_sort.hpp +++ /dev/null @@ -1 +0,0 @@ -#pragma once From a38a21ef200c9a0bb69edb90708d72c87fcd4f86 Mon Sep 17 00:00:00 2001 From: Vanek <123vanichka321@gmail.com> Date: Fri, 25 Oct 2024 17:56:38 +0300 Subject: [PATCH 02/11] add 3 task --- .gitignore | 1 + .../WeightedOrientedGraphWithZeroWeight.cpp | 79 +++++++++ lib/src/WeightedOrientedGraphWithZeroWeight.h | 27 ++++ lib/src/includes.h | 1 + task_03/src/BellmanFordAlgorithm.cpp | 35 ++++ task_03/src/BellmanForlAlgorithm.h | 6 + task_03/src/DeikstraAlgorithm.cpp | 150 ++++++++++++++++++ task_03/src/DeikstraAlgorithm.h | 14 ++ task_03/src/JonsonAlgorithm.cpp | 30 ++++ task_03/src/JonsonAlgorithm.h | 7 + task_03/src/main.cpp | 55 ++++++- 11 files changed, 404 insertions(+), 1 deletion(-) create mode 100644 lib/src/WeightedOrientedGraphWithZeroWeight.cpp create mode 100644 lib/src/WeightedOrientedGraphWithZeroWeight.h create mode 100644 task_03/src/BellmanFordAlgorithm.cpp create mode 100644 task_03/src/BellmanForlAlgorithm.h create mode 100644 task_03/src/DeikstraAlgorithm.cpp create mode 100644 task_03/src/DeikstraAlgorithm.h create mode 100644 task_03/src/JonsonAlgorithm.cpp create mode 100644 task_03/src/JonsonAlgorithm.h diff --git a/.gitignore b/.gitignore index 6fee36c..93566c6 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ _deps build/* .vs WeightedGraph.i +out diff --git a/lib/src/WeightedOrientedGraphWithZeroWeight.cpp b/lib/src/WeightedOrientedGraphWithZeroWeight.cpp new file mode 100644 index 0000000..b87feff --- /dev/null +++ b/lib/src/WeightedOrientedGraphWithZeroWeight.cpp @@ -0,0 +1,79 @@ +#include "WeightedOrientedGraphWithZeroWeight.h" + +OrientedWeightedGraphWithZeroWeight::OrientedWeightedGraphWithZeroWeight(const WeightedGraph& graph) +{ + int n = graph.GetVerts(); + this->graph.resize(n); + this->weight_graph.resize(n); + for (int i = 0; i < n; ++i) + { + this->graph[i].resize(n); + this->weight_graph[i].resize(n); + for (int j = 0; j < n; ++j) + if (graph[i][j]) + { + this->graph[i][j] = 1; + this->weight_graph[i][j] = graph[i][j]; + } + } +} + +bool OrientedWeightedGraphWithZeroWeight::AddVert(int id) +{ + if (id >= graph.size()) + { + graph.resize(id + 1); + weight_graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) + { + graph[i].resize(id + 1); + weight_graph[i].resize(id + 1); + graph[i][i] = 1; + } + } + return false; +} + +bool OrientedWeightedGraphWithZeroWeight::AddEdge(int id0, int id1, double value) +{ + if (id0 == id1) + return true; + AddVert(std::max(id0, id1)); + graph[id0][id1] = 1; + weight_graph[id0][id1] = value; + return false; +} + +bool OrientedWeightedGraphWithZeroWeight::DeleteVert(int id) +{ + if (id >= graph.size()) + return true; + graph.resize(id + 1); + weight_graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) + { + graph[i].resize(id + 1); + weight_graph[i].resize(id + 1); + } + return false; +} + +bool OrientedWeightedGraphWithZeroWeight::DeleteEdge(int id0, int id1) +{ + if (id0 == id1 || std::max(id0, id1) >= graph.size()) + return true; + graph[id0][id1] = 0; + weight_graph[id0][id1] = 0; + return false; +} + +void OrientedWeightedGraphWithZeroWeight::Print() +{ + for (int i = 0; i < graph.size(); ++i) + { + for (int j = 0; j < graph.size(); ++j) + std::cout << "(" << graph[i][j] << ", " << weight_graph[i][j] << "), "; + std::cout << std::endl; + } + std::cout << std::endl; +} \ No newline at end of file diff --git a/lib/src/WeightedOrientedGraphWithZeroWeight.h b/lib/src/WeightedOrientedGraphWithZeroWeight.h new file mode 100644 index 0000000..096465b --- /dev/null +++ b/lib/src/WeightedOrientedGraphWithZeroWeight.h @@ -0,0 +1,27 @@ +#pragma once + +#include "WeightedGraph.h" + +class OrientedWeightedGraphWithZeroWeight +{ +private: + std::vector> graph; + std::vector> weight_graph; + +public: + OrientedWeightedGraphWithZeroWeight() = default; + OrientedWeightedGraphWithZeroWeight(const WeightedGraph& graph); + + const std::vector& operator[](int i) const { return graph[i]; } + std::vector& operator[](int i) { return graph[i]; } + int GetVerts() const { return graph.size(); } + void Print(); + + bool AddVert(int id); + bool AddEdge(int id0, int id1, double value); + bool DeleteVert(int id); + bool DeleteEdge(int id0, int id1); + + double GetWeight(int i, int j) const { return weight_graph[i][j]; } + double& GetWeight(int i, int j) { return weight_graph[i][j]; } +}; \ No newline at end of file diff --git a/lib/src/includes.h b/lib/src/includes.h index 8a6a7a4..f0dcfa1 100644 --- a/lib/src/includes.h +++ b/lib/src/includes.h @@ -3,6 +3,7 @@ #include "WeightedGraph.h" #include "WeightedOrientedGraph.h" #include "WeightedNonOrientedGraph.h" +#include "WeightedOrientedGraphWithZeroWeight.h" #include "Graph.h" #include "OrientedGraph.h" #include "NonOrientedGraph.h" diff --git a/task_03/src/BellmanFordAlgorithm.cpp b/task_03/src/BellmanFordAlgorithm.cpp new file mode 100644 index 0000000..67744ab --- /dev/null +++ b/task_03/src/BellmanFordAlgorithm.cpp @@ -0,0 +1,35 @@ +#include "BellmanForlAlgorithm.h" + +std::vector BellmanFordAlgorithm(const WeightedGraph& graph, int start_id) +{ + int n = graph.GetVerts(); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + for (int k = 0; k < n; ++k) + if (graph[j][k] && pathLength[j] != DBL_MAX && pathLength[j] + graph[j][k] < pathLength[k]) + { + if (i == n - 1) + return std::vector(0); + pathLength[k] = pathLength[j] + graph[j][k]; + } + return pathLength; +} + +std::vector BellmanFordAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id) +{ + int n = graph.GetVerts(); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + for (int k = 0; k < n; ++k) + if (graph[j][k] && pathLength[j] != DBL_MAX && pathLength[j] + graph.GetWeight(j, k) < pathLength[k]) + { + if (i == n - 1) + return std::vector(0); + pathLength[k] = pathLength[j] + graph.GetWeight(j, k); + } + return pathLength; +} \ No newline at end of file diff --git a/task_03/src/BellmanForlAlgorithm.h b/task_03/src/BellmanForlAlgorithm.h new file mode 100644 index 0000000..58add9b --- /dev/null +++ b/task_03/src/BellmanForlAlgorithm.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +std::vector BellmanFordAlgorithm(const WeightedGraph& graph, int start_id); +std::vector BellmanFordAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id); \ No newline at end of file diff --git a/task_03/src/DeikstraAlgorithm.cpp b/task_03/src/DeikstraAlgorithm.cpp new file mode 100644 index 0000000..7b5018b --- /dev/null +++ b/task_03/src/DeikstraAlgorithm.cpp @@ -0,0 +1,150 @@ +#include "DeikstraAlgorithm.h" + +double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id) +{ + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + int this_id = start_id; + int counter = 0; + for (; true; ) + { + if (counter >= n) + break; + for (int i = 0; i < n; ++i) + { + if (graph[this_id][i]) + pathLength[i] = std::min(pathLength[i], pathLength[this_id] + graph[this_id][i]); + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) + { + if (!ended[j]) + if (min > pathLength[j]) + { + min = pathLength[j]; + this_id = j; + } + } + if (this_id == end_id) + return pathLength[end_id]; + ++counter; + } + return pathLength[end_id]; +} + +double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id) +{ + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + int this_id = start_id; + int counter = 0; + for (; true; ) + { + if (counter >= n) + break; + for (int i = 0; i < n; ++i) + { + if (graph[this_id][i]) + pathLength[i] = std::min(pathLength[i], pathLength[this_id] + graph.GetWeight(this_id, i)); + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) + { + if (!ended[j]) + if (min > pathLength[j]) + { + min = pathLength[j]; + this_id = j; + } + } + if (this_id == end_id) + return pathLength[end_id]; + ++counter; + } + return pathLength[end_id]; +} + +DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, int end_id) +{ + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + std::vector prevs(n, -1); + pathLength[start_id] = 0; + int this_id = start_id; + for (int counter = 0; counter < n && this_id != end_id; ++counter) + { + for (int i = 0; i < n; ++i) + { + if (graph[this_id][i] && pathLength[i] > pathLength[this_id] + graph[this_id][i]) + { + pathLength[i] = pathLength[this_id] + graph[this_id][i]; + prevs[i] = this_id; + } + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) + { + if (!ended[j]) + if (min > pathLength[j]) + { + min = pathLength[j]; + this_id = j; + } + } + } + std::vector path; + for (int i = end_id; i != start_id ; i = prevs[i]) + path.push_back(prevs[i]); + for (int i = 0; i < path.size() / 2; ++i) + std::swap(path[i], path[path.size() - 1 - i]); + return DeikstraReturn(path, pathLength[end_id]); +} + +DeikstraReturn DeikstraPathAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id) +{ + if (start_id == end_id) + return DeikstraReturn(std::vector(), 0); + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + std::vector prevs(n, -1); + pathLength[start_id] = 0; + int this_id = start_id; + for (int counter = 0; counter < n && this_id != end_id; ++counter) + { + for (int i = 0; i < n; ++i) + { + if (graph[this_id][i] && pathLength[i] > pathLength[this_id] + graph.GetWeight(this_id, i)) + { + pathLength[i] = pathLength[this_id] + graph.GetWeight(this_id, i); + prevs[i] = this_id; + } + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) + { + if (!ended[j]) + if (min > pathLength[j]) + { + min = pathLength[j]; + this_id = j; + } + } + } + std::vector path; + path.push_back(end_id); + for (int i = end_id; i != start_id; i = prevs[i]) + path.push_back(prevs[i]); + for (int i = 0; i < path.size() / 2; ++i) + std::swap(path[i], path[path.size() - 1 - i]); + return DeikstraReturn(path, pathLength[end_id]); +} diff --git a/task_03/src/DeikstraAlgorithm.h b/task_03/src/DeikstraAlgorithm.h new file mode 100644 index 0000000..c44690a --- /dev/null +++ b/task_03/src/DeikstraAlgorithm.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +struct DeikstraReturn +{ + std::vector path; + double pathLength; +}; + +double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id); +double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id); +DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, int end_id); +DeikstraReturn DeikstraPathAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id); diff --git a/task_03/src/JonsonAlgorithm.cpp b/task_03/src/JonsonAlgorithm.cpp new file mode 100644 index 0000000..e4a62a4 --- /dev/null +++ b/task_03/src/JonsonAlgorithm.cpp @@ -0,0 +1,30 @@ +#include "JonsonAlgorithm.h" + +double GetPathLength(const WeightedGraph& graph, const std::vector& path) +{ + if (path.size() == 0) + return 0; + double result = 0; + for (int i = 0; i < path.size() - 1; ++i) + result += graph[path[i]][path[i + 1]]; + return result; +} + +OrientedWeightedGraphWithZeroWeight JonsonAlgorithm(const WeightedGraph& graph) +{ + int n = graph.GetVerts(); + OrientedWeightedGraphWithZeroWeight new_graph(graph); + for (int i = 0; i < n; ++i) + new_graph.AddEdge(n, i, 0); + auto h = BellmanFordAlgorithm(new_graph, n); + if (h.size() == 0) + return WeightedGraph(); + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + new_graph.GetWeight(i, j) += h[i] - h[j]; + OrientedWeightedGraphWithZeroWeight resultGraph; + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + resultGraph.AddEdge(i, j, GetPathLength(graph, DeikstraPathAlgorithm(new_graph, i, j).path)); + return resultGraph; +} \ No newline at end of file diff --git a/task_03/src/JonsonAlgorithm.h b/task_03/src/JonsonAlgorithm.h new file mode 100644 index 0000000..8abcb04 --- /dev/null +++ b/task_03/src/JonsonAlgorithm.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include "DeikstraAlgorithm.h" +#include "BellmanForlAlgorithm.h" + +OrientedWeightedGraphWithZeroWeight JonsonAlgorithm(const WeightedGraph& graph); \ No newline at end of file diff --git a/task_03/src/main.cpp b/task_03/src/main.cpp index 0e4393b..a0e986b 100644 --- a/task_03/src/main.cpp +++ b/task_03/src/main.cpp @@ -1,3 +1,56 @@ #include +#include +#include "DeikstraAlgorithm.h" +#include "BellmanForlAlgorithm.h" +#include "JonsonAlgorithm.h" -int main() { return 0; } +int main() +{ + WeightedNonOrientedGraph graph; + graph.AddEdge(0, 1, 10); + graph.AddEdge(0, 2, 2); + graph.AddEdge(0, 3, 7); + graph.AddEdge(0, 4, 8); + graph.AddEdge(1, 3, 1); + graph.AddEdge(1, 5, 5); + graph.AddEdge(2, 3, 3); + graph.AddEdge(2, 4, 5); + graph.AddEdge(3, 4, 1); + graph.AddEdge(3, 5, 4); + graph.AddEdge(4, 5, 2); + + auto bf = BellmanFordAlgorithm(graph, 0); + auto deikstra = DeikstraPathAlgorithm(graph, 0, 5); + + graph.Print(); + std::cout << "Deikstra: " << deikstra.pathLength << std::endl; + for (int i = 0; i < deikstra.path.size(); ++i) + std::cout << deikstra.path[i] << ", "; + std::cout << std::endl; + std::cout << "Bellman Ford: "; + for (int i = 0; i < bf.size(); ++i) + std::cout << bf[i] << ", "; + std::cout << std::endl; + + WeightedOrientedGraph secondGraph; + secondGraph.AddEdge(0, 1, 2); + secondGraph.AddEdge(0, 2, 3); + secondGraph.AddEdge(1, 0, -1); + secondGraph.AddEdge(1, 2, 4); + secondGraph.AddEdge(2, 0, -2); + secondGraph.AddEdge(2, 1, 1); + + bf = BellmanFordAlgorithm(secondGraph, 0); + + secondGraph.Print(); + std::cout << "Bellman Ford: "; + for (int i = 0; i < bf.size(); ++i) + std::cout << bf[i] << ", "; + std::cout << std::endl; + std::cout << "Jonson: " << std::endl; + auto jons = JonsonAlgorithm(secondGraph); + jons.Print(); + std::cout << std::endl; + + return 0; +} From e4b33bc07ed2fc3f1f1b1f0d0864597664bb54be Mon Sep 17 00:00:00 2001 From: Vanek <123vanichka321@gmail.com> Date: Fri, 25 Oct 2024 17:59:31 +0300 Subject: [PATCH 03/11] add task 4 --- task_04/src/DeikstraAlgorithm.cpp | 150 ++++++++++++++++++++++++++++++ task_04/src/DeikstraAlgorithm.h | 14 +++ task_04/src/main.cpp | 25 ++++- task_04/src/test.cpp | 6 -- 4 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 task_04/src/DeikstraAlgorithm.cpp create mode 100644 task_04/src/DeikstraAlgorithm.h delete mode 100644 task_04/src/test.cpp diff --git a/task_04/src/DeikstraAlgorithm.cpp b/task_04/src/DeikstraAlgorithm.cpp new file mode 100644 index 0000000..7b5018b --- /dev/null +++ b/task_04/src/DeikstraAlgorithm.cpp @@ -0,0 +1,150 @@ +#include "DeikstraAlgorithm.h" + +double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id) +{ + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + int this_id = start_id; + int counter = 0; + for (; true; ) + { + if (counter >= n) + break; + for (int i = 0; i < n; ++i) + { + if (graph[this_id][i]) + pathLength[i] = std::min(pathLength[i], pathLength[this_id] + graph[this_id][i]); + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) + { + if (!ended[j]) + if (min > pathLength[j]) + { + min = pathLength[j]; + this_id = j; + } + } + if (this_id == end_id) + return pathLength[end_id]; + ++counter; + } + return pathLength[end_id]; +} + +double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id) +{ + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + int this_id = start_id; + int counter = 0; + for (; true; ) + { + if (counter >= n) + break; + for (int i = 0; i < n; ++i) + { + if (graph[this_id][i]) + pathLength[i] = std::min(pathLength[i], pathLength[this_id] + graph.GetWeight(this_id, i)); + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) + { + if (!ended[j]) + if (min > pathLength[j]) + { + min = pathLength[j]; + this_id = j; + } + } + if (this_id == end_id) + return pathLength[end_id]; + ++counter; + } + return pathLength[end_id]; +} + +DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, int end_id) +{ + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + std::vector prevs(n, -1); + pathLength[start_id] = 0; + int this_id = start_id; + for (int counter = 0; counter < n && this_id != end_id; ++counter) + { + for (int i = 0; i < n; ++i) + { + if (graph[this_id][i] && pathLength[i] > pathLength[this_id] + graph[this_id][i]) + { + pathLength[i] = pathLength[this_id] + graph[this_id][i]; + prevs[i] = this_id; + } + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) + { + if (!ended[j]) + if (min > pathLength[j]) + { + min = pathLength[j]; + this_id = j; + } + } + } + std::vector path; + for (int i = end_id; i != start_id ; i = prevs[i]) + path.push_back(prevs[i]); + for (int i = 0; i < path.size() / 2; ++i) + std::swap(path[i], path[path.size() - 1 - i]); + return DeikstraReturn(path, pathLength[end_id]); +} + +DeikstraReturn DeikstraPathAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id) +{ + if (start_id == end_id) + return DeikstraReturn(std::vector(), 0); + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + std::vector prevs(n, -1); + pathLength[start_id] = 0; + int this_id = start_id; + for (int counter = 0; counter < n && this_id != end_id; ++counter) + { + for (int i = 0; i < n; ++i) + { + if (graph[this_id][i] && pathLength[i] > pathLength[this_id] + graph.GetWeight(this_id, i)) + { + pathLength[i] = pathLength[this_id] + graph.GetWeight(this_id, i); + prevs[i] = this_id; + } + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) + { + if (!ended[j]) + if (min > pathLength[j]) + { + min = pathLength[j]; + this_id = j; + } + } + } + std::vector path; + path.push_back(end_id); + for (int i = end_id; i != start_id; i = prevs[i]) + path.push_back(prevs[i]); + for (int i = 0; i < path.size() / 2; ++i) + std::swap(path[i], path[path.size() - 1 - i]); + return DeikstraReturn(path, pathLength[end_id]); +} diff --git a/task_04/src/DeikstraAlgorithm.h b/task_04/src/DeikstraAlgorithm.h new file mode 100644 index 0000000..c44690a --- /dev/null +++ b/task_04/src/DeikstraAlgorithm.h @@ -0,0 +1,14 @@ +#pragma once + +#include + +struct DeikstraReturn +{ + std::vector path; + double pathLength; +}; + +double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id); +double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id); +DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, int end_id); +DeikstraReturn DeikstraPathAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id); diff --git a/task_04/src/main.cpp b/task_04/src/main.cpp index 0e4393b..bdebb1e 100644 --- a/task_04/src/main.cpp +++ b/task_04/src/main.cpp @@ -1,3 +1,26 @@ #include +#include "DeikstraAlgorithm.h" -int main() { return 0; } +int main() +{ + WeightedNonOrientedGraph graph; + graph.AddEdge(0, 1, 10); + graph.AddEdge(0, 2, 2); + graph.AddEdge(0, 3, 7); + graph.AddEdge(0, 4, 8); + graph.AddEdge(1, 3, 1); + graph.AddEdge(1, 5, 5); + graph.AddEdge(2, 3, 3); + graph.AddEdge(2, 4, 5); + graph.AddEdge(3, 4, 1); + graph.AddEdge(3, 5, 4); + graph.AddEdge(4, 5, 2); + + auto deikstra = DeikstraPathAlgorithm(graph, 0, 5); + + graph.Print(); + std::cout << "Deikstra: " << deikstra.pathLength << std::endl; + for (int i = 0; i < deikstra.path.size(); ++i) + std::cout << deikstra.path[i] << ", "; + std::cout << std::endl; +} diff --git a/task_04/src/test.cpp b/task_04/src/test.cpp deleted file mode 100644 index 5e11617..0000000 --- a/task_04/src/test.cpp +++ /dev/null @@ -1,6 +0,0 @@ - -#include - -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] -} From 3c7eabd36bd219163c0e65c17f998f17c3b41a08 Mon Sep 17 00:00:00 2001 From: Vanek <123vanichka321@gmail.com> Date: Wed, 15 Jan 2025 16:36:24 +0300 Subject: [PATCH 04/11] add 5 task --- lib/src/NonOrientedGraph.cpp | 28 ++++++++++++++++++++++++ lib/src/NonOrientedGraph.h | 5 +++++ lib/src/RMQ.cpp | 42 ++++++++++++++++++++++++++++++++++++ lib/src/RMQ.h | 18 ++++++++++++++++ task_05/src/main.cpp | 11 ++++++++-- 5 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 lib/src/RMQ.cpp create mode 100644 lib/src/RMQ.h diff --git a/lib/src/NonOrientedGraph.cpp b/lib/src/NonOrientedGraph.cpp index 954d0a6..f683d19 100644 --- a/lib/src/NonOrientedGraph.cpp +++ b/lib/src/NonOrientedGraph.cpp @@ -1,5 +1,33 @@ #include "NonOrientedGraph.h" +bool NonOrientedGraph::IsCycled(int parent, int id, std::vector& result, std::vector& visited) const +{ + for (int i = 0; i < graph.size(); ++i) + { + if (graph[id][i] && !visited[i] && i != parent) + { + visited[i] = true; + if (IsCycled(id, i, result, visited)) + return true; + result.push_back(i); + } + else if (graph[id][i] && visited[i] && i != id && i != parent) + { + if (!in(result, i)) + return true; + } + } + return false; +} + +bool NonOrientedGraph::IsCycled() const +{ + std::vector result; + std::vector visited(graph.size()); + visited[0] = true; + return IsCycled(0, 0, result, visited); +} + bool NonOrientedGraph::AddVert(int id) { if (id >= graph.size()) diff --git a/lib/src/NonOrientedGraph.h b/lib/src/NonOrientedGraph.h index 4971643..a1afde1 100644 --- a/lib/src/NonOrientedGraph.h +++ b/lib/src/NonOrientedGraph.h @@ -7,6 +7,9 @@ class NonOrientedGraph : public Graph { +private: + bool IsCycled(int parent, int id, std::vector& result, std::vector& visited) const; + public: int GetEdges() { @@ -19,4 +22,6 @@ class NonOrientedGraph : public Graph bool AddEdge(int id0, int id1); bool DeleteVert(int id); bool DeleteEdge(int id0, int id1); + + bool IsCycled() const; }; \ No newline at end of file diff --git a/lib/src/RMQ.cpp b/lib/src/RMQ.cpp new file mode 100644 index 0000000..9905b59 --- /dev/null +++ b/lib/src/RMQ.cpp @@ -0,0 +1,42 @@ +#include + +RMQ::RMQ(std::vector vec) : vector(vec), lookup(vec.size()) +{ + for (int i = 0; i < vec.size(); ++i) + lookup[i] = std::vector(vec.size()); + preprocess(); +} + +void RMQ::preprocess() +{ + for (int i = 0; i < vector.size(); i++) + lookup[i][i] = i; + + for (int i = 0; i < vector.size(); i++) { + for (int j = i + 1; j < vector.size(); j++) + if (vector[lookup[i][j - 1]] < vector[j]) + lookup[i][j] = lookup[i][j - 1]; + else + lookup[i][j] = j; + } +} + +double RMQ::get_min(int i, int j) +{ + return lookup[i][j]; +} + +void RMQ::Print() +{ + for (int i = 0; i < vector.size(); ++i) + { + std::cout << vector[i] << ", "; + } + std::cout << std::endl; + for (int i = 0; i < vector.size(); ++i) + { + for (int j = 0; j < vector.size(); ++j) + std::cout << lookup[i][j] << '(' << vector[lookup[i][j]] << "), "; + std::cout << '\n'; + } +} \ No newline at end of file diff --git a/lib/src/RMQ.h b/lib/src/RMQ.h new file mode 100644 index 0000000..71d1c36 --- /dev/null +++ b/lib/src/RMQ.h @@ -0,0 +1,18 @@ +#include +#include + +class RMQ +{ + + std::vector vector; + std::vector> lookup; + + void preprocess(); + +public: + RMQ(std::vector vec); + RMQ() = delete; + + double get_min(int i, int j); + void Print(); +}; \ No newline at end of file diff --git a/task_05/src/main.cpp b/task_05/src/main.cpp index 0e4393b..ff91baa 100644 --- a/task_05/src/main.cpp +++ b/task_05/src/main.cpp @@ -1,3 +1,10 @@ -#include +#include -int main() { return 0; } +// Driver code +int main() +{ + std::vector a = { 1, 3, 2, 7, 9, 11, 5, 4, 6, 8 }; + RMQ rmq(a); + rmq.Print(); + return 0; +} \ No newline at end of file From 493682c76926aeedb10680c3068966687005f3cc Mon Sep 17 00:00:00 2001 From: Vanek <123vanichka321@gmail.com> Date: Wed, 15 Jan 2025 17:39:58 +0300 Subject: [PATCH 05/11] add task 6 --- task_06/src/main.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/task_06/src/main.cpp b/task_06/src/main.cpp index 0e4393b..7f1d45d 100644 --- a/task_06/src/main.cpp +++ b/task_06/src/main.cpp @@ -1,3 +1,47 @@ #include -int main() { return 0; } +struct Node { + int data; + Node* left; + Node* right; + Node(int val) { + data = val; + left = nullptr; + right = nullptr; + } +}; + +Node* lca(Node* root, int n1, int n2) { + + if (root == nullptr) + return nullptr; + if (root->data > n1 && root->data > n2) + return lca(root->left, n1, n2); + if (root->data < n1 && root->data < n2) + return lca(root->right, n1, n2); + return root; +} + +int main() { + Node* root = new Node(20); + root->left = new Node(8); + root->right = new Node(22); + root->left->left = new Node(4); + root->left->right = new Node(12); + root->left->right->left = new Node(10); + root->left->right->right = new Node(14); + + int n1 = 10, n2 = 14; + Node* t = lca(root, n1, n2); + std::cout << n1 << " < " << t->data << " < " << n2 << std::endl; + + n1 = 14, n2 = 8; + t = lca(root, n1, n2); + std::cout << n1 << " < " << t->data << " < " << n2 << std::endl; + + n1 = 10, n2 = 22; + t = lca(root, n1, n2); + std::cout<< n1 << " < " << t->data << " < " << n2 << std::endl; + + return 0; +} \ No newline at end of file From 77f4a7b724f221b9e02e3341b30ebf2332545121 Mon Sep 17 00:00:00 2001 From: Vanek <123vanichka321@gmail.com> Date: Thu, 16 Jan 2025 13:49:20 +0300 Subject: [PATCH 06/11] add 6 task and tests --- lib/src/Lca.h | 25 +++++++++++++++++++++++++ task_01/src/test.cpp | 11 +++++++++-- task_02/src/test.cpp | 23 +++++++++++++++++++++++ task_03/src/test.cpp | 35 +++++++++++++++++++++++++++++++++++ task_04/src/test.cpp | 29 +++++++++++++++++++++++++++++ task_05/src/test.cpp | 15 +++++++++++---- task_06/src/main.cpp | 29 ++++------------------------- task_06/src/test.cpp | 25 ++++++++++++++++++++++--- 8 files changed, 158 insertions(+), 34 deletions(-) create mode 100644 lib/src/Lca.h create mode 100644 task_02/src/test.cpp create mode 100644 task_03/src/test.cpp create mode 100644 task_04/src/test.cpp diff --git a/lib/src/Lca.h b/lib/src/Lca.h new file mode 100644 index 0000000..60c1989 --- /dev/null +++ b/lib/src/Lca.h @@ -0,0 +1,25 @@ +#pragma once + +struct Node +{ + int data; + Node* left; + Node* right; + Node(int val) { + data = val; + left = nullptr; + right = nullptr; + } +}; + +Node* LCA(Node* root, int n1, int n2) +{ + + if (root == nullptr) + return nullptr; + if (root->data > n1 && root->data > n2) + return LCA(root->left, n1, n2); + if (root->data < n1 && root->data < n2) + return LCA(root->right, n1, n2); + return root; +} \ No newline at end of file diff --git a/task_01/src/test.cpp b/task_01/src/test.cpp index 87cef73..ca5797f 100644 --- a/task_01/src/test.cpp +++ b/task_01/src/test.cpp @@ -1,5 +1,12 @@ +#include #include +#include "topologicalSort.h" -TEST(Test, Simple) { - ASSERT_EQ(1, 1); // Stack [] +TEST(TopologicalSort, Simple) { + OrientedGraph graph; + graph.AddEdge(0, 3); + graph.AddEdge(3, 1); + graph.AddEdge(3, 2); + graph.AddEdge(2, 1); + ASSERT_EQ(topologicalSort(graph), std::vector({0, 3, 2, 1})); // Stack [] } \ No newline at end of file diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp new file mode 100644 index 0000000..0325adb --- /dev/null +++ b/task_02/src/test.cpp @@ -0,0 +1,23 @@ +#include +#include +#include "SearchWeakVE.h" + +TEST(TopologicalSort, Simple) { + NonOrientedGraph graph; + graph.AddEdge(0, 1); + graph.AddEdge(0, 2); + graph.AddEdge(1, 2); + graph.AddEdge(2, 3); + graph.AddEdge(3, 4); + graph.AddEdge(0, 1); + graph.AddEdge(1, 2); + graph.AddEdge(0, 2); + graph.AddEdge(2, 3); + graph.AddEdge(3, 4); + graph.AddEdge(3, 5); + graph.AddEdge(4, 5); + WeakVE result = SearchWeakVE(graph); + WeakVE true_result = WeakVE({ {3, 2, 0}, { {2, 3}} }); + ASSERT_EQ(result.first, true_result.first); + ASSERT_EQ(result.second, true_result.second); +} \ No newline at end of file diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp new file mode 100644 index 0000000..87e9d4d --- /dev/null +++ b/task_03/src/test.cpp @@ -0,0 +1,35 @@ +#include +#include +#include "JonsonAlgorithm.h" + +bool operator==(const OrientedWeightedGraphWithZeroWeight& first, const OrientedWeightedGraphWithZeroWeight& second) +{ + if (first.GetVerts() != second.GetVerts()) + return false; + for (int i = 0; i < first.GetVerts(); ++i) + for (int j = 0; j < first.GetVerts(); ++j) + if (first[i][j] != second[i][j] || first.GetWeight(i, j) != second.GetWeight(i, j)) + return false; + return true; +} + +TEST(TopologicalSort, Simple) { + WeightedOrientedGraph test_graph; + test_graph.AddEdge(0, 1, 2); + test_graph.AddEdge(0, 2, 3); + test_graph.AddEdge(1, 0, -1); + test_graph.AddEdge(1, 2, 4); + test_graph.AddEdge(2, 0, -2); + test_graph.AddEdge(2, 1, 1); + auto jons_graph = JonsonAlgorithm(test_graph); + + OrientedWeightedGraphWithZeroWeight true_jons_graph; + true_jons_graph.AddEdge(0, 1, 2); + true_jons_graph.AddEdge(0, 2, 3); + true_jons_graph.AddEdge(1, 0, -1); + true_jons_graph.AddEdge(1, 2, 2); + true_jons_graph.AddEdge(2, 0, -2); + true_jons_graph.AddEdge(2, 1, 0); + + ASSERT_EQ(jons_graph, true_jons_graph); +} \ No newline at end of file diff --git a/task_04/src/test.cpp b/task_04/src/test.cpp new file mode 100644 index 0000000..44e2b16 --- /dev/null +++ b/task_04/src/test.cpp @@ -0,0 +1,29 @@ +#include +#include +#include "DeikstraAlgorithm.h" + +bool operator==(const DeikstraReturn& first, const DeikstraReturn& second) +{ + if (first.path != second.path || first.pathLength != second.pathLength) + return false; + return true; +} + +TEST(TopologicalSort, Simple) { + WeightedNonOrientedGraph graph; + graph.AddEdge(0, 1, 10); + graph.AddEdge(0, 2, 2); + graph.AddEdge(0, 3, 7); + graph.AddEdge(0, 4, 8); + graph.AddEdge(1, 3, 1); + graph.AddEdge(1, 5, 5); + graph.AddEdge(2, 3, 3); + graph.AddEdge(2, 4, 5); + graph.AddEdge(3, 4, 1); + graph.AddEdge(3, 5, 4); + graph.AddEdge(4, 5, 2); + + auto deikstra = DeikstraPathAlgorithm(graph, 0, 5); + DeikstraReturn true_deikstra({0, 2, 3, 4}, 8); + ASSERT_EQ(deikstra, true_deikstra); +} \ No newline at end of file diff --git a/task_05/src/test.cpp b/task_05/src/test.cpp index 5e11617..94a87e8 100644 --- a/task_05/src/test.cpp +++ b/task_05/src/test.cpp @@ -1,6 +1,13 @@ - +#include #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] -} +TEST(RMQTest, Simple) { + std::vector testArray = { 1, 3, 2, 7, 9, 11, 5, 4, 6, 8 }; + RMQ testRMQ(testArray); + ASSERT_EQ(testRMQ.get_min(0, 5), 0); + ASSERT_EQ(testRMQ.get_min(3, 7), 7); + ASSERT_EQ(testRMQ.get_min(7, 8), 7); + ASSERT_EQ(testRMQ.get_min(2, 2), 2); + ASSERT_EQ(testRMQ.get_min(3, 5), 3); + ASSERT_EQ(testRMQ.get_min(5, 9), 7); +} \ No newline at end of file diff --git a/task_06/src/main.cpp b/task_06/src/main.cpp index 7f1d45d..65a823e 100644 --- a/task_06/src/main.cpp +++ b/task_06/src/main.cpp @@ -1,26 +1,5 @@ #include - -struct Node { - int data; - Node* left; - Node* right; - Node(int val) { - data = val; - left = nullptr; - right = nullptr; - } -}; - -Node* lca(Node* root, int n1, int n2) { - - if (root == nullptr) - return nullptr; - if (root->data > n1 && root->data > n2) - return lca(root->left, n1, n2); - if (root->data < n1 && root->data < n2) - return lca(root->right, n1, n2); - return root; -} +#include int main() { Node* root = new Node(20); @@ -32,15 +11,15 @@ int main() { root->left->right->right = new Node(14); int n1 = 10, n2 = 14; - Node* t = lca(root, n1, n2); + Node* t = LCA(root, n1, n2); std::cout << n1 << " < " << t->data << " < " << n2 << std::endl; n1 = 14, n2 = 8; - t = lca(root, n1, n2); + t = LCA(root, n1, n2); std::cout << n1 << " < " << t->data << " < " << n2 << std::endl; n1 = 10, n2 = 22; - t = lca(root, n1, n2); + t = LCA(root, n1, n2); std::cout<< n1 << " < " << t->data << " < " << n2 << std::endl; return 0; diff --git a/task_06/src/test.cpp b/task_06/src/test.cpp index 5e11617..85683da 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,6 +1,25 @@ - #include +#include + +TEST(LCATest, Simple) { + Node* root = new Node(20); + root->left = new Node(8); + root->right = new Node(22); + root->left->left = new Node(4); + root->left->right = new Node(12); + root->left->right->left = new Node(10); + root->left->right->right = new Node(14); + + int n1 = 10, n2 = 14; + Node* t = LCA(root, n1, n2); + ASSERT_EQ(t->data, 12); + + n1 = 8, n2 = 14; + t = LCA(root, n1, n2); + ASSERT_EQ(t->data, 8); + + n1 = 10, n2 = 22; + t = LCA(root, n1, n2); + ASSERT_EQ(t->data, 20); -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] } From f5607f541360d384691d99d27e959de66f3951ca Mon Sep 17 00:00:00 2001 From: Vanek <123vanichka321@gmail.com> Date: Thu, 16 Jan 2025 14:01:24 +0300 Subject: [PATCH 07/11] accept google clang format --- .gitignore | 1 + lib/src/Graph.h | 20 +- lib/src/GraphDFSIterator.cpp | 57 ++-- lib/src/GraphDFSIterator.h | 34 +-- lib/src/Lca.h | 36 +-- lib/src/NonOrientedGraph.cpp | 103 +++---- lib/src/NonOrientedGraph.h | 37 ++- lib/src/OrientedGraph.cpp | 58 ++-- lib/src/OrientedGraph.h | 15 +- lib/src/RMQ.cpp | 59 ++-- lib/src/RMQ.h | 22 +- lib/src/WeightedGraph.cpp | 234 +++++++--------- lib/src/WeightedGraph.h | 45 +-- lib/src/WeightedNonOrientedGraph.cpp | 62 ++--- lib/src/WeightedNonOrientedGraph.h | 15 +- lib/src/WeightedOrientedGraph.cpp | 58 ++-- lib/src/WeightedOrientedGraph.h | 15 +- .../WeightedOrientedGraphWithZeroWeight.cpp | 121 ++++---- lib/src/WeightedOrientedGraphWithZeroWeight.h | 37 ++- lib/src/includes.h | 14 +- lib/src/util.cpp | 67 ++--- lib/src/util.h | 2 +- task_01/src/main.cpp | 53 ++-- task_01/src/test.cpp | 18 +- task_01/src/topologicalSort.cpp | 64 ++--- task_01/src/topologicalSort.h | 2 +- task_02/src/SearchWeakVE.cpp | 70 +++-- task_02/src/SearchWeakVE.h | 2 +- task_02/src/main.cpp | 63 ++--- task_02/src/test.cpp | 39 +-- task_03/src/BellmanFordAlgorithm.cpp | 60 ++-- task_03/src/BellmanForlAlgorithm.h | 6 +- task_03/src/DeikstraAlgorithm.cpp | 261 ++++++++---------- task_03/src/DeikstraAlgorithm.h | 16 +- task_03/src/JonsonAlgorithm.cpp | 49 ++-- task_03/src/main.cpp | 101 ++++--- task_03/src/test.cpp | 55 ++-- task_04/src/DeikstraAlgorithm.cpp | 261 ++++++++---------- task_04/src/DeikstraAlgorithm.h | 16 +- task_04/src/main.cpp | 40 +-- task_04/src/test.cpp | 44 +-- task_05/src/main.cpp | 13 +- task_05/src/test.cpp | 18 +- task_06/src/main.cpp | 39 +-- task_06/src/test.cpp | 35 ++- 45 files changed, 1115 insertions(+), 1322 deletions(-) diff --git a/.gitignore b/.gitignore index 93566c6..96c0402 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ build/* .vs WeightedGraph.i out +CMakeSettings.json diff --git a/lib/src/Graph.h b/lib/src/Graph.h index acff929..6078a33 100644 --- a/lib/src/Graph.h +++ b/lib/src/Graph.h @@ -1,16 +1,14 @@ #pragma once -#include #include #include -class Graph : public WeightedGraph -{ - int GetEdges() - { - int result = 0; - for (int i = 0; i < graph.size(); ++i) - result += sum(graph[i]); - return result; - } -}; \ No newline at end of file +#include + +class Graph : public WeightedGraph { + int GetEdges() { + int result = 0; + for (int i = 0; i < graph.size(); ++i) result += sum(graph[i]); + return result; + } +}; diff --git a/lib/src/GraphDFSIterator.cpp b/lib/src/GraphDFSIterator.cpp index 00acd40..c8aa621 100644 --- a/lib/src/GraphDFSIterator.cpp +++ b/lib/src/GraphDFSIterator.cpp @@ -1,38 +1,31 @@ #include -GraphDFSIterator::GraphDFSIterator(const WeightedGraph* const graph, int start_id) -{ - this->start_id = start_id; - this->graph = graph; - this->is_end = false; - this_id = start_id; - visited.resize(graph->GetVerts()); - visited[start_id] = true; - parent.resize(graph->GetVerts(), -1); +GraphDFSIterator::GraphDFSIterator(const WeightedGraph* const graph, + int start_id) { + this->start_id = start_id; + this->graph = graph; + this->is_end = false; + this_id = start_id; + visited.resize(graph->GetVerts()); + visited[start_id] = true; + parent.resize(graph->GetVerts(), -1); } -int GraphDFSIterator::Next() -{ - for (int i = 0; i < graph->GetVerts(); ++i) - { - if ((*graph)[this_id][i] != 0 && !visited[i]) - { - visited[i] = true; - parent[i] = this_id; - this_id = i; - return i; - } - } - if (parent[this_id] == -1) - { - is_end = true; - return this_id; - } - this_id = parent[this_id]; - return Next(); +int GraphDFSIterator::Next() { + for (int i = 0; i < graph->GetVerts(); ++i) { + if ((*graph)[this_id][i] != 0 && !visited[i]) { + visited[i] = true; + parent[i] = this_id; + this_id = i; + return i; + } + } + if (parent[this_id] == -1) { + is_end = true; + return this_id; + } + this_id = parent[this_id]; + return Next(); } -bool GraphDFSIterator::IsEnd() -{ - return is_end; -} \ No newline at end of file +bool GraphDFSIterator::IsEnd() { return is_end; } diff --git a/lib/src/GraphDFSIterator.h b/lib/src/GraphDFSIterator.h index 7451627..a3bf147 100644 --- a/lib/src/GraphDFSIterator.h +++ b/lib/src/GraphDFSIterator.h @@ -1,27 +1,27 @@ #pragma once -#include #include #include +#include + class WeightedGraph; -class GraphDFSIterator -{ - const WeightedGraph* graph; - int start_id; - int this_id; - bool is_end; - std::vector visited; - std::vector parent; +class GraphDFSIterator { + const WeightedGraph* graph; + int start_id; + int this_id; + bool is_end; + std::vector visited; + std::vector parent; - int Next(); + int Next(); -public: - GraphDFSIterator() = delete; - GraphDFSIterator(const WeightedGraph* const graph, int start_id); + public: + GraphDFSIterator() = delete; + GraphDFSIterator(const WeightedGraph* const graph, int start_id); - int operator++() { return Next(); } - int operator()() { return this_id; } - bool IsEnd(); -}; \ No newline at end of file + int operator++() { return Next(); } + int operator()() { return this_id; } + bool IsEnd(); +}; diff --git a/lib/src/Lca.h b/lib/src/Lca.h index 60c1989..8b36c94 100644 --- a/lib/src/Lca.h +++ b/lib/src/Lca.h @@ -1,25 +1,19 @@ #pragma once -struct Node -{ - int data; - Node* left; - Node* right; - Node(int val) { - data = val; - left = nullptr; - right = nullptr; - } +struct Node { + int data; + Node* left; + Node* right; + Node(int val) { + data = val; + left = nullptr; + right = nullptr; + } }; -Node* LCA(Node* root, int n1, int n2) -{ - - if (root == nullptr) - return nullptr; - if (root->data > n1 && root->data > n2) - return LCA(root->left, n1, n2); - if (root->data < n1 && root->data < n2) - return LCA(root->right, n1, n2); - return root; -} \ No newline at end of file +Node* LCA(Node* root, int n1, int n2) { + if (root == nullptr) return nullptr; + if (root->data > n1 && root->data > n2) return LCA(root->left, n1, n2); + if (root->data < n1 && root->data < n2) return LCA(root->right, n1, n2); + return root; +} diff --git a/lib/src/NonOrientedGraph.cpp b/lib/src/NonOrientedGraph.cpp index f683d19..6480764 100644 --- a/lib/src/NonOrientedGraph.cpp +++ b/lib/src/NonOrientedGraph.cpp @@ -1,72 +1,55 @@ #include "NonOrientedGraph.h" -bool NonOrientedGraph::IsCycled(int parent, int id, std::vector& result, std::vector& visited) const -{ - for (int i = 0; i < graph.size(); ++i) - { - if (graph[id][i] && !visited[i] && i != parent) - { - visited[i] = true; - if (IsCycled(id, i, result, visited)) - return true; - result.push_back(i); - } - else if (graph[id][i] && visited[i] && i != id && i != parent) - { - if (!in(result, i)) - return true; - } - } - return false; +bool NonOrientedGraph::IsCycled(int parent, int id, std::vector& result, + std::vector& visited) const { + for (int i = 0; i < graph.size(); ++i) { + if (graph[id][i] && !visited[i] && i != parent) { + visited[i] = true; + if (IsCycled(id, i, result, visited)) return true; + result.push_back(i); + } else if (graph[id][i] && visited[i] && i != id && i != parent) { + if (!in(result, i)) return true; + } + } + return false; } -bool NonOrientedGraph::IsCycled() const -{ - std::vector result; - std::vector visited(graph.size()); - visited[0] = true; - return IsCycled(0, 0, result, visited); +bool NonOrientedGraph::IsCycled() const { + std::vector result; + std::vector visited(graph.size()); + visited[0] = true; + return IsCycled(0, 0, result, visited); } -bool NonOrientedGraph::AddVert(int id) -{ - if (id >= graph.size()) - { - graph.resize(id + 1); - for (int i = 0; i < graph.size(); ++i) - { - graph[i].resize(id + 1); - graph[i][i] = 1; - } - } - return false; +bool NonOrientedGraph::AddVert(int id) { + if (id >= graph.size()) { + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) { + graph[i].resize(id + 1); + graph[i][i] = 1; + } + } + return false; } -bool NonOrientedGraph::AddEdge(int id0, int id1) -{ - if (id0 == id1) - return true; - AddVert(std::max(id0, id1)); - graph[id0][id1] = 1; - graph[id1][id0] = 1; - return false; +bool NonOrientedGraph::AddEdge(int id0, int id1) { + if (id0 == id1) return true; + AddVert(std::max(id0, id1)); + graph[id0][id1] = 1; + graph[id1][id0] = 1; + return false; } -bool NonOrientedGraph::DeleteVert(int id) -{ - if (id >= graph.size()) - return true; - graph.resize(id + 1); - for (int i = 0; i < graph.size(); ++i) - graph[i].resize(id + 1); - return false; +bool NonOrientedGraph::DeleteVert(int id) { + if (id >= graph.size()) return true; + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) graph[i].resize(id + 1); + return false; } -bool NonOrientedGraph::DeleteEdge(int id0, int id1) -{ - if (id0 == id1 || std::max(id0, id1) >= graph.size()) - return true; - graph[id0][id1] = 0; - graph[id1][id0] = 0; - return false; -} \ No newline at end of file +bool NonOrientedGraph::DeleteEdge(int id0, int id1) { + if (id0 == id1 || std::max(id0, id1) >= graph.size()) return true; + graph[id0][id1] = 0; + graph[id1][id0] = 0; + return false; +} diff --git a/lib/src/NonOrientedGraph.h b/lib/src/NonOrientedGraph.h index a1afde1..50aff82 100644 --- a/lib/src/NonOrientedGraph.h +++ b/lib/src/NonOrientedGraph.h @@ -1,27 +1,26 @@ #pragma once -#include #include +#include + #include "Graph.h" #include "util.h" -class NonOrientedGraph : public Graph -{ -private: - bool IsCycled(int parent, int id, std::vector& result, std::vector& visited) const; +class NonOrientedGraph : public Graph { + private: + bool IsCycled(int parent, int id, std::vector& result, + std::vector& visited) const; -public: - int GetEdges() - { - int result = 0; - for (int i = 0; i < graph.size(); ++i) - result += sum(graph[i]); - return result / 2; - } - bool AddVert(int id); - bool AddEdge(int id0, int id1); - bool DeleteVert(int id); - bool DeleteEdge(int id0, int id1); + public: + int GetEdges() { + int result = 0; + for (int i = 0; i < graph.size(); ++i) result += sum(graph[i]); + return result / 2; + } + bool AddVert(int id); + bool AddEdge(int id0, int id1); + bool DeleteVert(int id); + bool DeleteEdge(int id0, int id1); - bool IsCycled() const; -}; \ No newline at end of file + bool IsCycled() const; +}; diff --git a/lib/src/OrientedGraph.cpp b/lib/src/OrientedGraph.cpp index b441fc5..bfea4d1 100644 --- a/lib/src/OrientedGraph.cpp +++ b/lib/src/OrientedGraph.cpp @@ -1,42 +1,32 @@ #include "OrientedGraph.h" -bool OrientedGraph::AddVert(int id) -{ - if (id >= graph.size()) - { - graph.resize(id + 1); - for (int i = 0; i < graph.size(); ++i) - { - graph[i].resize(id + 1); - graph[i][i] = 1; - } - } - return false; +bool OrientedGraph::AddVert(int id) { + if (id >= graph.size()) { + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) { + graph[i].resize(id + 1); + graph[i][i] = 1; + } + } + return false; } -bool OrientedGraph::AddEdge(int id0, int id1) -{ - if (id0 == id1) - return true; - AddVert(std::max(id0, id1)); - graph[id0][id1] = 1; - return false; +bool OrientedGraph::AddEdge(int id0, int id1) { + if (id0 == id1) return true; + AddVert(std::max(id0, id1)); + graph[id0][id1] = 1; + return false; } -bool OrientedGraph::DeleteVert(int id) -{ - if (id >= graph.size()) - return true; - graph.resize(id + 1); - for (int i = 0; i < graph.size(); ++i) - graph[i].resize(id + 1); - return false; +bool OrientedGraph::DeleteVert(int id) { + if (id >= graph.size()) return true; + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) graph[i].resize(id + 1); + return false; } -bool OrientedGraph::DeleteEdge(int id0, int id1) -{ - if (id0 == id1 || std::max(id0, id1) >= graph.size()) - return true; - graph[id0][id1] = 0; - return false; -} \ No newline at end of file +bool OrientedGraph::DeleteEdge(int id0, int id1) { + if (id0 == id1 || std::max(id0, id1) >= graph.size()) return true; + graph[id0][id1] = 0; + return false; +} diff --git a/lib/src/OrientedGraph.h b/lib/src/OrientedGraph.h index 3e659ec..4697a24 100644 --- a/lib/src/OrientedGraph.h +++ b/lib/src/OrientedGraph.h @@ -2,11 +2,10 @@ #include "Graph.h" -class OrientedGraph : public Graph -{ -public: - bool AddVert(int id); - bool AddEdge(int id0, int id1); - bool DeleteVert(int id); - bool DeleteEdge(int id0, int id1); -}; \ No newline at end of file +class OrientedGraph : public Graph { + public: + bool AddVert(int id); + bool AddEdge(int id0, int id1); + bool DeleteVert(int id); + bool DeleteEdge(int id0, int id1); +}; diff --git a/lib/src/RMQ.cpp b/lib/src/RMQ.cpp index 9905b59..167b0e8 100644 --- a/lib/src/RMQ.cpp +++ b/lib/src/RMQ.cpp @@ -1,42 +1,33 @@ #include -RMQ::RMQ(std::vector vec) : vector(vec), lookup(vec.size()) -{ - for (int i = 0; i < vec.size(); ++i) - lookup[i] = std::vector(vec.size()); - preprocess(); +RMQ::RMQ(std::vector vec) : vector(vec), lookup(vec.size()) { + for (int i = 0; i < vec.size(); ++i) + lookup[i] = std::vector(vec.size()); + preprocess(); } -void RMQ::preprocess() -{ - for (int i = 0; i < vector.size(); i++) - lookup[i][i] = i; +void RMQ::preprocess() { + for (int i = 0; i < vector.size(); i++) lookup[i][i] = i; - for (int i = 0; i < vector.size(); i++) { - for (int j = i + 1; j < vector.size(); j++) - if (vector[lookup[i][j - 1]] < vector[j]) - lookup[i][j] = lookup[i][j - 1]; - else - lookup[i][j] = j; - } + for (int i = 0; i < vector.size(); i++) { + for (int j = i + 1; j < vector.size(); j++) + if (vector[lookup[i][j - 1]] < vector[j]) + lookup[i][j] = lookup[i][j - 1]; + else + lookup[i][j] = j; + } } -double RMQ::get_min(int i, int j) -{ - return lookup[i][j]; -} +double RMQ::get_min(int i, int j) { return lookup[i][j]; } -void RMQ::Print() -{ - for (int i = 0; i < vector.size(); ++i) - { - std::cout << vector[i] << ", "; - } - std::cout << std::endl; - for (int i = 0; i < vector.size(); ++i) - { - for (int j = 0; j < vector.size(); ++j) - std::cout << lookup[i][j] << '(' << vector[lookup[i][j]] << "), "; - std::cout << '\n'; - } -} \ No newline at end of file +void RMQ::Print() { + for (int i = 0; i < vector.size(); ++i) { + std::cout << vector[i] << ", "; + } + std::cout << std::endl; + for (int i = 0; i < vector.size(); ++i) { + for (int j = 0; j < vector.size(); ++j) + std::cout << lookup[i][j] << '(' << vector[lookup[i][j]] << "), "; + std::cout << '\n'; + } +} diff --git a/lib/src/RMQ.h b/lib/src/RMQ.h index 71d1c36..8931871 100644 --- a/lib/src/RMQ.h +++ b/lib/src/RMQ.h @@ -1,18 +1,16 @@ #include #include -class RMQ -{ +class RMQ { + std::vector vector; + std::vector> lookup; - std::vector vector; - std::vector> lookup; + void preprocess(); - void preprocess(); + public: + RMQ(std::vector vec); + RMQ() = delete; -public: - RMQ(std::vector vec); - RMQ() = delete; - - double get_min(int i, int j); - void Print(); -}; \ No newline at end of file + double get_min(int i, int j); + void Print(); +}; diff --git a/lib/src/WeightedGraph.cpp b/lib/src/WeightedGraph.cpp index 24ae4ad..5dc5a4b 100644 --- a/lib/src/WeightedGraph.cpp +++ b/lib/src/WeightedGraph.cpp @@ -1,158 +1,118 @@ #include "WeightedGraph.h" -int WeightedGraph::GetEdges() const -{ - int result = 0; - for (int i = 0; i < graph.size(); ++i) - for (int j = 0; j < graph.size(); ++j) - if (graph[i][j]) - ++result; - return result - graph.size(); +int WeightedGraph::GetEdges() const { + int result = 0; + for (int i = 0; i < graph.size(); ++i) + for (int j = 0; j < graph.size(); ++j) + if (graph[i][j]) ++result; + return result - graph.size(); } -bool WeightedGraph::IsCycled(int id, std::vector& result, std::vector& visited) const -{ - for (int i = 0; i < graph.size(); ++i) - { - if (graph[id][i] && !visited[i]) - { - visited[i] = true; - if (IsCycled(i, result, visited)) - return true; - result.push_back(i); - } - else if (graph[id][i] && visited[i] && i != id) - { - if (!in(result, i)) - return true; - } - } - return false; +bool WeightedGraph::IsCycled(int id, std::vector& result, + std::vector& visited) const { + for (int i = 0; i < graph.size(); ++i) { + if (graph[id][i] && !visited[i]) { + visited[i] = true; + if (IsCycled(i, result, visited)) return true; + result.push_back(i); + } else if (graph[id][i] && visited[i] && i != id) { + if (!in(result, i)) return true; + } + } + return false; } -bool WeightedGraph::IsCycled() const -{ - std::vector result; - std::vector visited(graph.size()); - visited[0] = true; - return IsCycled(0, result, visited); +bool WeightedGraph::IsCycled() const { + std::vector result; + std::vector visited(graph.size()); + visited[0] = true; + return IsCycled(0, result, visited); } -void WeightedGraph::Print() const -{ - for (int i = 0; i < graph.size(); ++i) - { - for (int j = 0; j < graph.size(); ++j) - std::cout << graph[i][j] << ", "; - std::cout << '\n'; - } +void WeightedGraph::Print() const { + for (int i = 0; i < graph.size(); ++i) { + for (int j = 0; j < graph.size(); ++j) std::cout << graph[i][j] << ", "; + std::cout << '\n'; + } } -bool WeightedGraph::SwapIds(int id0, int id1) -{ - if (std::max(id0, id1) >= graph.size() || id0 == id1) - return true; - if (id0 > id1) - std::swap(id0, id1); - - for (int i = 0; i < graph.size(); ++i) - std::swap(graph[i][id0], graph[i][id1]); - std::swap(graph[id0], graph[id1]); - return false; -} +bool WeightedGraph::SwapIds(int id0, int id1) { + if (std::max(id0, id1) >= graph.size() || id0 == id1) return true; + if (id0 > id1) std::swap(id0, id1); -void WeightedGraph::DFS(int id, std::vector& result, std::vector& visited, bool before) -{ - for (int i = 0; i < graph.size(); ++i) - { - if (graph[id][i] && !visited[i]) - { - visited[i] = true; - if (!before) - result.push_back(i); - DFS(i, result, visited); - if (before) - result.push_back(i); - } - } + for (int i = 0; i < graph.size(); ++i) + std::swap(graph[i][id0], graph[i][id1]); + std::swap(graph[id0], graph[id1]); + return false; } -std::vector WeightedGraph::DFS(int id, bool before) -{ - std::vector visited(graph.size()); - std::vector result; - visited[id] = true; - if (!before) - result.push_back(id); - - for (int i = 0; i < graph.size(); ++i) - { - if (graph[id][i] && !visited[i]) - { - visited[i] = true; - if (!before) - result.push_back(i); - DFS(i, result, visited); - if (before) - result.push_back(i); - } - } - if (before) - result.push_back(id); - - return result; +void WeightedGraph::DFS(int id, std::vector& result, + std::vector& visited, bool before) { + for (int i = 0; i < graph.size(); ++i) { + if (graph[id][i] && !visited[i]) { + visited[i] = true; + if (!before) result.push_back(i); + DFS(i, result, visited); + if (before) result.push_back(i); + } + } } -std::vector WeightedGraph::DFS(bool before) -{ - return DFS(0, before); +std::vector WeightedGraph::DFS(int id, bool before) { + std::vector visited(graph.size()); + std::vector result; + visited[id] = true; + if (!before) result.push_back(id); + + for (int i = 0; i < graph.size(); ++i) { + if (graph[id][i] && !visited[i]) { + visited[i] = true; + if (!before) result.push_back(i); + DFS(i, result, visited); + if (before) result.push_back(i); + } + } + if (before) result.push_back(id); + + return result; } -void WeightedGraph::BFS(int id, std::vector& result, std::vector& visited) -{ - std::vector need_visit; - for (int i = 0; i < graph.size(); ++i) - { - if (graph[id][i] && !visited[i]) - { - visited[i] = true; - result.push_back(i); - need_visit.push_back(i); - } - } - for (int i = 0; i < need_visit.size(); ++i) - { - if (!visited[need_visit[i]]) - BFS(need_visit[i], result, visited); - } +std::vector WeightedGraph::DFS(bool before) { return DFS(0, before); } + +void WeightedGraph::BFS(int id, std::vector& result, + std::vector& visited) { + std::vector need_visit; + for (int i = 0; i < graph.size(); ++i) { + if (graph[id][i] && !visited[i]) { + visited[i] = true; + result.push_back(i); + need_visit.push_back(i); + } + } + for (int i = 0; i < need_visit.size(); ++i) { + if (!visited[need_visit[i]]) BFS(need_visit[i], result, visited); + } } -std::vector WeightedGraph::BFS(int id) -{ - std::vector visited(graph.size()); - std::vector result; - visited[id] = true; - result.push_back(id); - - std::vector need_visit; - - for (int i = 0; i < graph.size(); ++i) - { - if (graph[id][i] && !visited[i]) - { - visited[i] = true; - result.push_back(i); - need_visit.push_back(i); - } - } - for (int i = 0; i < need_visit.size(); ++i) - { - BFS(need_visit[i], result, visited); - } - return result; +std::vector WeightedGraph::BFS(int id) { + std::vector visited(graph.size()); + std::vector result; + visited[id] = true; + result.push_back(id); + + std::vector need_visit; + + for (int i = 0; i < graph.size(); ++i) { + if (graph[id][i] && !visited[i]) { + visited[i] = true; + result.push_back(i); + need_visit.push_back(i); + } + } + for (int i = 0; i < need_visit.size(); ++i) { + BFS(need_visit[i], result, visited); + } + return result; } -std::vector WeightedGraph::BFS() -{ - return BFS(0); -} \ No newline at end of file +std::vector WeightedGraph::BFS() { return BFS(0); } diff --git a/lib/src/WeightedGraph.h b/lib/src/WeightedGraph.h index 8b2b515..0c9ec2d 100644 --- a/lib/src/WeightedGraph.h +++ b/lib/src/WeightedGraph.h @@ -1,31 +1,32 @@ #pragma once -#include -#include #include -class WeightedGraph -{ -protected: - std::vector> graph; +#include +#include - bool IsCycled(int id_start, std::vector& result, std::vector& visited) const; - void DFS(int id_start, std::vector& result, std::vector& visited, bool after = false); - void BFS(int id_start, std::vector& result, std::vector& visited); +class WeightedGraph { + protected: + std::vector> graph; -public: - const std::vector& operator[](int i) const { return graph[i]; } - std::vector& operator[](int i) { return graph[i]; } - int GetVerts() const { return graph.size(); } - int GetEdges() const; - bool IsCycled() const; - void Print() const; + bool IsCycled(int id_start, std::vector& result, + std::vector& visited) const; + void DFS(int id_start, std::vector& result, std::vector& visited, + bool after = false); + void BFS(int id_start, std::vector& result, std::vector& visited); - bool SwapIds(int id0, int id1); + public: + const std::vector& operator[](int i) const { return graph[i]; } + std::vector& operator[](int i) { return graph[i]; } + int GetVerts() const { return graph.size(); } + int GetEdges() const; + bool IsCycled() const; + void Print() const; - std::vector DFS(int id_start, bool after = false); - std::vector DFS(bool after = false); - std::vector BFS(int id_start); - std::vector BFS(); + bool SwapIds(int id0, int id1); -}; \ No newline at end of file + std::vector DFS(int id_start, bool after = false); + std::vector DFS(bool after = false); + std::vector BFS(int id_start); + std::vector BFS(); +}; diff --git a/lib/src/WeightedNonOrientedGraph.cpp b/lib/src/WeightedNonOrientedGraph.cpp index 96ed840..daf021d 100644 --- a/lib/src/WeightedNonOrientedGraph.cpp +++ b/lib/src/WeightedNonOrientedGraph.cpp @@ -1,44 +1,34 @@ #include "WeightedNonOrientedGraph.h" -bool WeightedNonOrientedGraph::AddVert(int id) -{ - if (id >= graph.size()) - { - graph.resize(id + 1); - for (int i = 0; i < graph.size(); ++i) - { - graph[i].resize(id + 1); - graph[i][i] = 1; - } - } - return false; +bool WeightedNonOrientedGraph::AddVert(int id) { + if (id >= graph.size()) { + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) { + graph[i].resize(id + 1); + graph[i][i] = 1; + } + } + return false; } -bool WeightedNonOrientedGraph::AddEdge(int id0, int id1, double value) -{ - if (id0 == id1) - return true; - AddVert(std::max(id0, id1)); - graph[id0][id1] = value; - graph[id1][id0] = value; - return false; +bool WeightedNonOrientedGraph::AddEdge(int id0, int id1, double value) { + if (id0 == id1) return true; + AddVert(std::max(id0, id1)); + graph[id0][id1] = value; + graph[id1][id0] = value; + return false; } -bool WeightedNonOrientedGraph::DeleteVert(int id) -{ - if (id >= graph.size()) - return true; - graph.resize(id + 1); - for (int i = 0; i < graph.size(); ++i) - graph[i].resize(id + 1); - return false; +bool WeightedNonOrientedGraph::DeleteVert(int id) { + if (id >= graph.size()) return true; + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) graph[i].resize(id + 1); + return false; } -bool WeightedNonOrientedGraph::DeleteEdge(int id0, int id1) -{ - if (id0 == id1 || std::max(id0, id1) >= graph.size()) - return true; - graph[id0][id1] = 0; - graph[id1][id0] = 0; - return false; -} \ No newline at end of file +bool WeightedNonOrientedGraph::DeleteEdge(int id0, int id1) { + if (id0 == id1 || std::max(id0, id1) >= graph.size()) return true; + graph[id0][id1] = 0; + graph[id1][id0] = 0; + return false; +} diff --git a/lib/src/WeightedNonOrientedGraph.h b/lib/src/WeightedNonOrientedGraph.h index 080a96c..6aab16a 100644 --- a/lib/src/WeightedNonOrientedGraph.h +++ b/lib/src/WeightedNonOrientedGraph.h @@ -2,11 +2,10 @@ #include "WeightedGraph.h" -class WeightedNonOrientedGraph : public WeightedGraph -{ -public: - bool AddVert(int id); - bool AddEdge(int id0, int id1, double value); - bool DeleteVert(int id); - bool DeleteEdge(int id0, int id1); -}; \ No newline at end of file +class WeightedNonOrientedGraph : public WeightedGraph { + public: + bool AddVert(int id); + bool AddEdge(int id0, int id1, double value); + bool DeleteVert(int id); + bool DeleteEdge(int id0, int id1); +}; diff --git a/lib/src/WeightedOrientedGraph.cpp b/lib/src/WeightedOrientedGraph.cpp index cdd638b..2bf2257 100644 --- a/lib/src/WeightedOrientedGraph.cpp +++ b/lib/src/WeightedOrientedGraph.cpp @@ -1,42 +1,32 @@ #include "WeightedOrientedGraph.h" -bool WeightedOrientedGraph::AddVert(int id) -{ - if (id >= graph.size()) - { - graph.resize(id + 1); - for (int i = 0; i < graph.size(); ++i) - { - graph[i].resize(id + 1); - graph[i][i] = 1; - } - } - return false; +bool WeightedOrientedGraph::AddVert(int id) { + if (id >= graph.size()) { + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) { + graph[i].resize(id + 1); + graph[i][i] = 1; + } + } + return false; } -bool WeightedOrientedGraph::AddEdge(int id0, int id1, double value) -{ - if (id0 == id1) - return true; - AddVert(std::max(id0, id1)); - graph[id0][id1] = value; - return false; +bool WeightedOrientedGraph::AddEdge(int id0, int id1, double value) { + if (id0 == id1) return true; + AddVert(std::max(id0, id1)); + graph[id0][id1] = value; + return false; } -bool WeightedOrientedGraph::DeleteVert(int id) -{ - if (id >= graph.size()) - return true; - graph.resize(id + 1); - for (int i = 0; i < graph.size(); ++i) - graph[i].resize(id + 1); - return false; +bool WeightedOrientedGraph::DeleteVert(int id) { + if (id >= graph.size()) return true; + graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) graph[i].resize(id + 1); + return false; } -bool WeightedOrientedGraph::DeleteEdge(int id0, int id1) -{ - if (id0 == id1 || std::max(id0, id1) >= graph.size()) - return true; - graph[id0][id1] = 0; - return false; -} \ No newline at end of file +bool WeightedOrientedGraph::DeleteEdge(int id0, int id1) { + if (id0 == id1 || std::max(id0, id1) >= graph.size()) return true; + graph[id0][id1] = 0; + return false; +} diff --git a/lib/src/WeightedOrientedGraph.h b/lib/src/WeightedOrientedGraph.h index f5e60d2..fd9fd07 100644 --- a/lib/src/WeightedOrientedGraph.h +++ b/lib/src/WeightedOrientedGraph.h @@ -2,11 +2,10 @@ #include "WeightedGraph.h" -class WeightedOrientedGraph : public WeightedGraph -{ -public: - bool AddVert(int id); - bool AddEdge(int id0, int id1, double value); - bool DeleteVert(int id); - bool DeleteEdge(int id0, int id1); -}; \ No newline at end of file +class WeightedOrientedGraph : public WeightedGraph { + public: + bool AddVert(int id); + bool AddEdge(int id0, int id1, double value); + bool DeleteVert(int id); + bool DeleteEdge(int id0, int id1); +}; diff --git a/lib/src/WeightedOrientedGraphWithZeroWeight.cpp b/lib/src/WeightedOrientedGraphWithZeroWeight.cpp index b87feff..2a9cb02 100644 --- a/lib/src/WeightedOrientedGraphWithZeroWeight.cpp +++ b/lib/src/WeightedOrientedGraphWithZeroWeight.cpp @@ -1,79 +1,66 @@ #include "WeightedOrientedGraphWithZeroWeight.h" -OrientedWeightedGraphWithZeroWeight::OrientedWeightedGraphWithZeroWeight(const WeightedGraph& graph) -{ - int n = graph.GetVerts(); - this->graph.resize(n); - this->weight_graph.resize(n); - for (int i = 0; i < n; ++i) - { - this->graph[i].resize(n); - this->weight_graph[i].resize(n); - for (int j = 0; j < n; ++j) - if (graph[i][j]) - { - this->graph[i][j] = 1; - this->weight_graph[i][j] = graph[i][j]; - } - } +OrientedWeightedGraphWithZeroWeight::OrientedWeightedGraphWithZeroWeight( + const WeightedGraph& graph) { + int n = graph.GetVerts(); + this->graph.resize(n); + this->weight_graph.resize(n); + for (int i = 0; i < n; ++i) { + this->graph[i].resize(n); + this->weight_graph[i].resize(n); + for (int j = 0; j < n; ++j) + if (graph[i][j]) { + this->graph[i][j] = 1; + this->weight_graph[i][j] = graph[i][j]; + } + } } -bool OrientedWeightedGraphWithZeroWeight::AddVert(int id) -{ - if (id >= graph.size()) - { - graph.resize(id + 1); - weight_graph.resize(id + 1); - for (int i = 0; i < graph.size(); ++i) - { - graph[i].resize(id + 1); - weight_graph[i].resize(id + 1); - graph[i][i] = 1; - } - } - return false; +bool OrientedWeightedGraphWithZeroWeight::AddVert(int id) { + if (id >= graph.size()) { + graph.resize(id + 1); + weight_graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) { + graph[i].resize(id + 1); + weight_graph[i].resize(id + 1); + graph[i][i] = 1; + } + } + return false; } -bool OrientedWeightedGraphWithZeroWeight::AddEdge(int id0, int id1, double value) -{ - if (id0 == id1) - return true; - AddVert(std::max(id0, id1)); - graph[id0][id1] = 1; - weight_graph[id0][id1] = value; - return false; +bool OrientedWeightedGraphWithZeroWeight::AddEdge(int id0, int id1, + double value) { + if (id0 == id1) return true; + AddVert(std::max(id0, id1)); + graph[id0][id1] = 1; + weight_graph[id0][id1] = value; + return false; } -bool OrientedWeightedGraphWithZeroWeight::DeleteVert(int id) -{ - if (id >= graph.size()) - return true; - graph.resize(id + 1); - weight_graph.resize(id + 1); - for (int i = 0; i < graph.size(); ++i) - { - graph[i].resize(id + 1); - weight_graph[i].resize(id + 1); - } - return false; +bool OrientedWeightedGraphWithZeroWeight::DeleteVert(int id) { + if (id >= graph.size()) return true; + graph.resize(id + 1); + weight_graph.resize(id + 1); + for (int i = 0; i < graph.size(); ++i) { + graph[i].resize(id + 1); + weight_graph[i].resize(id + 1); + } + return false; } -bool OrientedWeightedGraphWithZeroWeight::DeleteEdge(int id0, int id1) -{ - if (id0 == id1 || std::max(id0, id1) >= graph.size()) - return true; - graph[id0][id1] = 0; - weight_graph[id0][id1] = 0; - return false; +bool OrientedWeightedGraphWithZeroWeight::DeleteEdge(int id0, int id1) { + if (id0 == id1 || std::max(id0, id1) >= graph.size()) return true; + graph[id0][id1] = 0; + weight_graph[id0][id1] = 0; + return false; } -void OrientedWeightedGraphWithZeroWeight::Print() -{ - for (int i = 0; i < graph.size(); ++i) - { - for (int j = 0; j < graph.size(); ++j) - std::cout << "(" << graph[i][j] << ", " << weight_graph[i][j] << "), "; - std::cout << std::endl; - } - std::cout << std::endl; -} \ No newline at end of file +void OrientedWeightedGraphWithZeroWeight::Print() { + for (int i = 0; i < graph.size(); ++i) { + for (int j = 0; j < graph.size(); ++j) + std::cout << "(" << graph[i][j] << ", " << weight_graph[i][j] << "), "; + std::cout << std::endl; + } + std::cout << std::endl; +} diff --git a/lib/src/WeightedOrientedGraphWithZeroWeight.h b/lib/src/WeightedOrientedGraphWithZeroWeight.h index 096465b..13f595b 100644 --- a/lib/src/WeightedOrientedGraphWithZeroWeight.h +++ b/lib/src/WeightedOrientedGraphWithZeroWeight.h @@ -2,26 +2,25 @@ #include "WeightedGraph.h" -class OrientedWeightedGraphWithZeroWeight -{ -private: - std::vector> graph; - std::vector> weight_graph; +class OrientedWeightedGraphWithZeroWeight { + private: + std::vector> graph; + std::vector> weight_graph; -public: - OrientedWeightedGraphWithZeroWeight() = default; - OrientedWeightedGraphWithZeroWeight(const WeightedGraph& graph); + public: + OrientedWeightedGraphWithZeroWeight() = default; + OrientedWeightedGraphWithZeroWeight(const WeightedGraph& graph); - const std::vector& operator[](int i) const { return graph[i]; } - std::vector& operator[](int i) { return graph[i]; } - int GetVerts() const { return graph.size(); } - void Print(); + const std::vector& operator[](int i) const { return graph[i]; } + std::vector& operator[](int i) { return graph[i]; } + int GetVerts() const { return graph.size(); } + void Print(); - bool AddVert(int id); - bool AddEdge(int id0, int id1, double value); - bool DeleteVert(int id); - bool DeleteEdge(int id0, int id1); + bool AddVert(int id); + bool AddEdge(int id0, int id1, double value); + bool DeleteVert(int id); + bool DeleteEdge(int id0, int id1); - double GetWeight(int i, int j) const { return weight_graph[i][j]; } - double& GetWeight(int i, int j) { return weight_graph[i][j]; } -}; \ No newline at end of file + double GetWeight(int i, int j) const { return weight_graph[i][j]; } + double& GetWeight(int i, int j) { return weight_graph[i][j]; } +}; diff --git a/lib/src/includes.h b/lib/src/includes.h index f0dcfa1..75bb903 100644 --- a/lib/src/includes.h +++ b/lib/src/includes.h @@ -1,13 +1,11 @@ #pragma once +#include "Graph.h" +#include "GraphDFSIterator.h" +#include "NonOrientedGraph.h" +#include "OrientedGraph.h" #include "WeightedGraph.h" -#include "WeightedOrientedGraph.h" #include "WeightedNonOrientedGraph.h" +#include "WeightedOrientedGraph.h" #include "WeightedOrientedGraphWithZeroWeight.h" -#include "Graph.h" -#include "OrientedGraph.h" -#include "NonOrientedGraph.h" - -#include "GraphDFSIterator.h" - -#include "util.h" \ No newline at end of file +#include "util.h" diff --git a/lib/src/util.cpp b/lib/src/util.cpp index 83cf442..a848d1e 100644 --- a/lib/src/util.cpp +++ b/lib/src/util.cpp @@ -1,51 +1,44 @@ #include "util.h" -int partition(std::vector& vec, int low, int high) -{ - int pivot = vec[high]; - int i = (low - 1); +int partition(std::vector& vec, int low, int high) { + int pivot = vec[high]; + int i = (low - 1); - for (int j = low; j <= high - 1; j++) { - if (vec[j] <= pivot) { - i++; - std::swap(vec[i], vec[j]); - } + for (int j = low; j <= high - 1; j++) { + if (vec[j] <= pivot) { + i++; + std::swap(vec[i], vec[j]); } - std::swap(vec[i + 1], vec[high]); - return (i + 1); + } + std::swap(vec[i + 1], vec[high]); + return (i + 1); } -void quickSort(std::vector& vec, int low, int high) -{ - if (low < high) { - int pi = partition(vec, low, high); - quickSort(vec, low, pi - 1); - quickSort(vec, pi + 1, high); - } +void quickSort(std::vector& vec, int low, int high) { + if (low < high) { + int pi = partition(vec, low, high); + quickSort(vec, low, pi - 1); + quickSort(vec, pi + 1, high); + } } void bubbleSort(std::vector& vec) { - int n = vec.size(); - for (int i = 0; i < n - 1; i++) { - for (int j = 0; j < n - i - 1; j++) { - if (vec[j] > vec[j + 1]) - std::swap(vec[j], vec[j + 1]); - } + int n = vec.size(); + for (int i = 0; i < n - 1; i++) { + for (int j = 0; j < n - i - 1; j++) { + if (vec[j] > vec[j + 1]) std::swap(vec[j], vec[j + 1]); } + } } -bool in(const std::vector& vec, int value) -{ - for (int i = 0; i < vec.size(); ++i) - if (vec[i] == value) - return true; - return false; +bool in(const std::vector& vec, int value) { + for (int i = 0; i < vec.size(); ++i) + if (vec[i] == value) return true; + return false; } -int sum(const std::vector& vec) -{ - int result = 0; - for (auto value : vec) - result += value; - return result; -} \ No newline at end of file +int sum(const std::vector& vec) { + int result = 0; + for (auto value : vec) result += value; + return result; +} diff --git a/lib/src/util.h b/lib/src/util.h index 89bab2a..b264ede 100644 --- a/lib/src/util.h +++ b/lib/src/util.h @@ -9,4 +9,4 @@ void bubbleSort(std::vector& vec); bool in(const std::vector& vec, int value); -int sum(const std::vector& vec); \ No newline at end of file +int sum(const std::vector& vec); diff --git a/task_01/src/main.cpp b/task_01/src/main.cpp index 3bc8a22..f606ee2 100644 --- a/task_01/src/main.cpp +++ b/task_01/src/main.cpp @@ -1,38 +1,35 @@ #include + #include "topologicalSort.h" -std::ostream& operator<<(std::ostream& os, const std::vector& vec) -{ - for (int i = 0; i < vec.size(); ++i) - os << vec[i] << ", "; - return os; +std::ostream& operator<<(std::ostream& os, const std::vector& vec) { + for (int i = 0; i < vec.size(); ++i) os << vec[i] << ", "; + return os; } -int main() -{ - OrientedGraph graph; - graph.AddEdge(0, 3); - graph.AddEdge(3, 1); - graph.AddEdge(3, 2); - graph.AddEdge(2, 1); - graph.Print(); - std::cout << std::endl; +int main() { + OrientedGraph graph; + graph.AddEdge(0, 3); + graph.AddEdge(3, 1); + graph.AddEdge(3, 2); + graph.AddEdge(2, 1); + graph.Print(); + std::cout << std::endl; - std::cout << "DFS ITERATION: "; - for (auto iter = GraphDFSIterator(&graph, 0); !iter.IsEnd(); ++iter) - { - std::cout << iter() << ", "; - } - std::cout << std::endl; + std::cout << "DFS ITERATION: "; + for (auto iter = GraphDFSIterator(&graph, 0); !iter.IsEnd(); ++iter) { + std::cout << iter() << ", "; + } + std::cout << std::endl; - std::cout << "IsCycled: " << graph.IsCycled() << std::endl; + std::cout << "IsCycled: " << graph.IsCycled() << std::endl; - std::cout << "DFS: " << graph.DFS() << std::endl; - std::cout << "after DFS: " << graph.DFS(true) << std::endl; - std::cout << "BFS: " << graph.BFS() << std::endl; + std::cout << "DFS: " << graph.DFS() << std::endl; + std::cout << "after DFS: " << graph.DFS(true) << std::endl; + std::cout << "BFS: " << graph.BFS() << std::endl; - auto top_graph = topologicalSort(graph); - std::cout << "topological sort: " << top_graph << std::endl; - topologicalSorted(graph); - graph.Print(); + auto top_graph = topologicalSort(graph); + std::cout << "topological sort: " << top_graph << std::endl; + topologicalSorted(graph); + graph.Print(); } diff --git a/task_01/src/test.cpp b/task_01/src/test.cpp index ca5797f..936c720 100644 --- a/task_01/src/test.cpp +++ b/task_01/src/test.cpp @@ -1,12 +1,14 @@ -#include #include +#include + #include "topologicalSort.h" TEST(TopologicalSort, Simple) { - OrientedGraph graph; - graph.AddEdge(0, 3); - graph.AddEdge(3, 1); - graph.AddEdge(3, 2); - graph.AddEdge(2, 1); - ASSERT_EQ(topologicalSort(graph), std::vector({0, 3, 2, 1})); // Stack [] -} \ No newline at end of file + OrientedGraph graph; + graph.AddEdge(0, 3); + graph.AddEdge(3, 1); + graph.AddEdge(3, 2); + graph.AddEdge(2, 1); + ASSERT_EQ(topologicalSort(graph), + std::vector({0, 3, 2, 1})); // Stack [] +} diff --git a/task_01/src/topologicalSort.cpp b/task_01/src/topologicalSort.cpp index 62db767..5f7a1ac 100644 --- a/task_01/src/topologicalSort.cpp +++ b/task_01/src/topologicalSort.cpp @@ -1,44 +1,34 @@ #include "topologicalSort.h" -std::vector topologicalSort(WeightedGraph& graph) -{ - if (graph.IsCycled()) - return std::vector{-1}; +std::vector topologicalSort(WeightedGraph& graph) { + if (graph.IsCycled()) return std::vector{-1}; - auto dfs = graph.DFS(true); - std::vector rdfs(dfs.size()); - for (int i = 0; i < dfs.size(); ++i) - rdfs[graph.GetVerts() - 1 - i] = dfs[i]; - return rdfs; + auto dfs = graph.DFS(true); + std::vector rdfs(dfs.size()); + for (int i = 0; i < dfs.size(); ++i) rdfs[graph.GetVerts() - 1 - i] = dfs[i]; + return rdfs; } -bool topologicalSorted(WeightedGraph& graph) -{ - auto rdfs = topologicalSort(graph); - if (rdfs.size() == 1 && rdfs[0] == -1) - return true; - std::vector positions(graph.GetVerts()); - for (int i = 0; i < graph.GetVerts(); ++i) - positions[i] = i; - for (int i = 0; i < graph.GetVerts(); ++i) - { - int finded_id = -1; - for (int j = i; j < positions.size(); ++j) - if (positions[j] == rdfs[i]) - { - finded_id = j; - break; - } - graph.SwapIds(i, finded_id); - std::swap(positions[i], positions[finded_id]); - } - return false; +bool topologicalSorted(WeightedGraph& graph) { + auto rdfs = topologicalSort(graph); + if (rdfs.size() == 1 && rdfs[0] == -1) return true; + std::vector positions(graph.GetVerts()); + for (int i = 0; i < graph.GetVerts(); ++i) positions[i] = i; + for (int i = 0; i < graph.GetVerts(); ++i) { + int finded_id = -1; + for (int j = i; j < positions.size(); ++j) + if (positions[j] == rdfs[i]) { + finded_id = j; + break; + } + graph.SwapIds(i, finded_id); + std::swap(positions[i], positions[finded_id]); + } + return false; } -WeightedGraph* topologicalSorting(WeightedGraph& graph) -{ - WeightedGraph* new_graph = new WeightedGraph(graph); - if (topologicalSorted(*new_graph)) - return nullptr; - return new_graph; -} \ No newline at end of file +WeightedGraph* topologicalSorting(WeightedGraph& graph) { + WeightedGraph* new_graph = new WeightedGraph(graph); + if (topologicalSorted(*new_graph)) return nullptr; + return new_graph; +} diff --git a/task_01/src/topologicalSort.h b/task_01/src/topologicalSort.h index f85bd8c..3b9517d 100644 --- a/task_01/src/topologicalSort.h +++ b/task_01/src/topologicalSort.h @@ -4,4 +4,4 @@ std::vector topologicalSort(WeightedGraph& graph); bool topologicalSorted(WeightedGraph& graph); -WeightedGraph* topologicalSorting(WeightedGraph& graph); \ No newline at end of file +WeightedGraph* topologicalSorting(WeightedGraph& graph); diff --git a/task_02/src/SearchWeakVE.cpp b/task_02/src/SearchWeakVE.cpp index e203e3d..ea7a543 100644 --- a/task_02/src/SearchWeakVE.cpp +++ b/task_02/src/SearchWeakVE.cpp @@ -1,43 +1,35 @@ #include "SearchWeakVE.h" -void dfs(WeakVE& result, const WeightedGraph& graph, int id, int parent, std::vector& disc, std::vector& low, std::vector& visited, int& time) -{ - disc[id] = time; - low[id] = time; - ++time; - visited[id] = true; - for (int i = 0; i < graph.GetVerts(); ++i) - { - if (graph[id][i] && !visited[i]) - { - dfs(result, graph, i, id, disc, low, visited, time); - low[id] = std::min(low[id], low[i]); - if (low[i] > disc[id]) - result.second.push_back(std::make_pair(id, i)); - if (parent != -1 && low[i] >= disc[id]) - result.first.push_back(id); - } - else if (graph[id][i] && i != parent) - low[id] = std::min(low[id], low[i]); - } +void dfs(WeakVE& result, const WeightedGraph& graph, int id, int parent, + std::vector& disc, std::vector& low, + std::vector& visited, int& time) { + disc[id] = time; + low[id] = time; + ++time; + visited[id] = true; + for (int i = 0; i < graph.GetVerts(); ++i) { + if (graph[id][i] && !visited[i]) { + dfs(result, graph, i, id, disc, low, visited, time); + low[id] = std::min(low[id], low[i]); + if (low[i] > disc[id]) result.second.push_back(std::make_pair(id, i)); + if (parent != -1 && low[i] >= disc[id]) result.first.push_back(id); + } else if (graph[id][i] && i != parent) + low[id] = std::min(low[id], low[i]); + } } -WeakVE SearchWeakVE(const WeightedGraph& graph) -{ - WeakVE result; - std::vector disc(graph.GetVerts()); - std::vector low(graph.GetVerts()); - std::vector visited(graph.GetVerts()); - int time = 0; - int start_id = 0; - dfs(result, graph, start_id, -1, disc, low, visited, time); - int num_start_id_daughters = 0; - for (int i = 0; i < graph.GetVerts(); ++i) - { - if (graph[start_id][i] != 0) - ++num_start_id_daughters; - } - if (num_start_id_daughters > 1) - result.first.push_back(start_id); - return result; -} \ No newline at end of file +WeakVE SearchWeakVE(const WeightedGraph& graph) { + WeakVE result; + std::vector disc(graph.GetVerts()); + std::vector low(graph.GetVerts()); + std::vector visited(graph.GetVerts()); + int time = 0; + int start_id = 0; + dfs(result, graph, start_id, -1, disc, low, visited, time); + int num_start_id_daughters = 0; + for (int i = 0; i < graph.GetVerts(); ++i) { + if (graph[start_id][i] != 0) ++num_start_id_daughters; + } + if (num_start_id_daughters > 1) result.first.push_back(start_id); + return result; +} diff --git a/task_02/src/SearchWeakVE.h b/task_02/src/SearchWeakVE.h index 853c252..088c404 100644 --- a/task_02/src/SearchWeakVE.h +++ b/task_02/src/SearchWeakVE.h @@ -4,4 +4,4 @@ #define WeakVE std::pair, std::vector>> -WeakVE SearchWeakVE(const WeightedGraph& graph); \ No newline at end of file +WeakVE SearchWeakVE(const WeightedGraph& graph); diff --git a/task_02/src/main.cpp b/task_02/src/main.cpp index 0c8258d..25087f2 100644 --- a/task_02/src/main.cpp +++ b/task_02/src/main.cpp @@ -1,41 +1,32 @@ +#include + #include -#include #include "SearchWeakVE.h" -int main() -{ - NonOrientedGraph graph; - graph.AddEdge(0, 1); - graph.AddEdge(0, 2); - graph.AddEdge(1, 2); - graph.AddEdge(2, 3); - graph.AddEdge(3, 4); - - //graph.AddEdge(0, 1); - //graph.AddEdge(1, 2); - //graph.AddEdge(2, 3); - //graph.AddEdge(1, 3); - //graph.AddEdge(3, 4); - //graph.AddEdge(4, 5); - //graph.AddEdge(5, 6); - //graph.AddEdge(6, 7); - //graph.AddEdge(7, 4); - graph.AddEdge(0, 1); - graph.AddEdge(1, 2); - graph.AddEdge(0, 2); - graph.AddEdge(2, 3); - graph.AddEdge(3, 4); - graph.AddEdge(3, 5); - graph.AddEdge(4, 5); - graph.Print(); - WeakVE result = SearchWeakVE(graph); - std::cout << "Weak Points: "; - for (int i = 0; i < result.first.size(); ++i) - std::cout << result.first[i] << ", "; - std::cout << "\nWeak Edges: "; - for (int i = 0; i < result.second.size(); ++i) - std::cout << "(" << result.second[i].first << ", " << result.second[i].second << "); "; - std::cout << std::endl; - return 0; +int main() { + NonOrientedGraph graph; + graph.AddEdge(0, 1); + graph.AddEdge(0, 2); + graph.AddEdge(1, 2); + graph.AddEdge(2, 3); + graph.AddEdge(3, 4); + graph.AddEdge(0, 1); + graph.AddEdge(1, 2); + graph.AddEdge(0, 2); + graph.AddEdge(2, 3); + graph.AddEdge(3, 4); + graph.AddEdge(3, 5); + graph.AddEdge(4, 5); + graph.Print(); + WeakVE result = SearchWeakVE(graph); + std::cout << "Weak Points: "; + for (int i = 0; i < result.first.size(); ++i) + std::cout << result.first[i] << ", "; + std::cout << "\nWeak Edges: "; + for (int i = 0; i < result.second.size(); ++i) + std::cout << "(" << result.second[i].first << ", " + << result.second[i].second << "); "; + std::cout << std::endl; + return 0; } diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index 0325adb..c7c9608 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -1,23 +1,24 @@ -#include #include +#include + #include "SearchWeakVE.h" TEST(TopologicalSort, Simple) { - NonOrientedGraph graph; - graph.AddEdge(0, 1); - graph.AddEdge(0, 2); - graph.AddEdge(1, 2); - graph.AddEdge(2, 3); - graph.AddEdge(3, 4); - graph.AddEdge(0, 1); - graph.AddEdge(1, 2); - graph.AddEdge(0, 2); - graph.AddEdge(2, 3); - graph.AddEdge(3, 4); - graph.AddEdge(3, 5); - graph.AddEdge(4, 5); - WeakVE result = SearchWeakVE(graph); - WeakVE true_result = WeakVE({ {3, 2, 0}, { {2, 3}} }); - ASSERT_EQ(result.first, true_result.first); - ASSERT_EQ(result.second, true_result.second); -} \ No newline at end of file + NonOrientedGraph graph; + graph.AddEdge(0, 1); + graph.AddEdge(0, 2); + graph.AddEdge(1, 2); + graph.AddEdge(2, 3); + graph.AddEdge(3, 4); + graph.AddEdge(0, 1); + graph.AddEdge(1, 2); + graph.AddEdge(0, 2); + graph.AddEdge(2, 3); + graph.AddEdge(3, 4); + graph.AddEdge(3, 5); + graph.AddEdge(4, 5); + WeakVE result = SearchWeakVE(graph); + WeakVE true_result = WeakVE({{3, 2, 0}, {{2, 3}}}); + ASSERT_EQ(result.first, true_result.first); + ASSERT_EQ(result.second, true_result.second); +} diff --git a/task_03/src/BellmanFordAlgorithm.cpp b/task_03/src/BellmanFordAlgorithm.cpp index 67744ab..7c4254c 100644 --- a/task_03/src/BellmanFordAlgorithm.cpp +++ b/task_03/src/BellmanFordAlgorithm.cpp @@ -1,35 +1,33 @@ #include "BellmanForlAlgorithm.h" -std::vector BellmanFordAlgorithm(const WeightedGraph& graph, int start_id) -{ - int n = graph.GetVerts(); - std::vector pathLength(n, DBL_MAX); - pathLength[start_id] = 0; - for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - for (int k = 0; k < n; ++k) - if (graph[j][k] && pathLength[j] != DBL_MAX && pathLength[j] + graph[j][k] < pathLength[k]) - { - if (i == n - 1) - return std::vector(0); - pathLength[k] = pathLength[j] + graph[j][k]; - } - return pathLength; +std::vector BellmanFordAlgorithm(const WeightedGraph& graph, + int start_id) { + int n = graph.GetVerts(); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + for (int k = 0; k < n; ++k) + if (graph[j][k] && pathLength[j] != DBL_MAX && + pathLength[j] + graph[j][k] < pathLength[k]) { + if (i == n - 1) return std::vector(0); + pathLength[k] = pathLength[j] + graph[j][k]; + } + return pathLength; } -std::vector BellmanFordAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id) -{ - int n = graph.GetVerts(); - std::vector pathLength(n, DBL_MAX); - pathLength[start_id] = 0; - for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - for (int k = 0; k < n; ++k) - if (graph[j][k] && pathLength[j] != DBL_MAX && pathLength[j] + graph.GetWeight(j, k) < pathLength[k]) - { - if (i == n - 1) - return std::vector(0); - pathLength[k] = pathLength[j] + graph.GetWeight(j, k); - } - return pathLength; -} \ No newline at end of file +std::vector BellmanFordAlgorithm( + const OrientedWeightedGraphWithZeroWeight& graph, int start_id) { + int n = graph.GetVerts(); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + for (int k = 0; k < n; ++k) + if (graph[j][k] && pathLength[j] != DBL_MAX && + pathLength[j] + graph.GetWeight(j, k) < pathLength[k]) { + if (i == n - 1) return std::vector(0); + pathLength[k] = pathLength[j] + graph.GetWeight(j, k); + } + return pathLength; +} diff --git a/task_03/src/BellmanForlAlgorithm.h b/task_03/src/BellmanForlAlgorithm.h index 58add9b..e76e046 100644 --- a/task_03/src/BellmanForlAlgorithm.h +++ b/task_03/src/BellmanForlAlgorithm.h @@ -2,5 +2,7 @@ #include -std::vector BellmanFordAlgorithm(const WeightedGraph& graph, int start_id); -std::vector BellmanFordAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id); \ No newline at end of file +std::vector BellmanFordAlgorithm(const WeightedGraph& graph, + int start_id); +std::vector BellmanFordAlgorithm( + const OrientedWeightedGraphWithZeroWeight& graph, int start_id); diff --git a/task_03/src/DeikstraAlgorithm.cpp b/task_03/src/DeikstraAlgorithm.cpp index 7b5018b..baab66b 100644 --- a/task_03/src/DeikstraAlgorithm.cpp +++ b/task_03/src/DeikstraAlgorithm.cpp @@ -1,150 +1,129 @@ #include "DeikstraAlgorithm.h" -double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id) -{ - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - pathLength[start_id] = 0; - int this_id = start_id; - int counter = 0; - for (; true; ) - { - if (counter >= n) - break; - for (int i = 0; i < n; ++i) - { - if (graph[this_id][i]) - pathLength[i] = std::min(pathLength[i], pathLength[this_id] + graph[this_id][i]); - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) - { - if (!ended[j]) - if (min > pathLength[j]) - { - min = pathLength[j]; - this_id = j; - } - } - if (this_id == end_id) - return pathLength[end_id]; - ++counter; - } - return pathLength[end_id]; +double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id) { + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + int this_id = start_id; + int counter = 0; + for (; true;) { + if (counter >= n) break; + for (int i = 0; i < n; ++i) { + if (graph[this_id][i]) + pathLength[i] = + std::min(pathLength[i], pathLength[this_id] + graph[this_id][i]); + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) { + if (!ended[j]) + if (min > pathLength[j]) { + min = pathLength[j]; + this_id = j; + } + } + if (this_id == end_id) return pathLength[end_id]; + ++counter; + } + return pathLength[end_id]; } -double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id) -{ - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - pathLength[start_id] = 0; - int this_id = start_id; - int counter = 0; - for (; true; ) - { - if (counter >= n) - break; - for (int i = 0; i < n; ++i) - { - if (graph[this_id][i]) - pathLength[i] = std::min(pathLength[i], pathLength[this_id] + graph.GetWeight(this_id, i)); - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) - { - if (!ended[j]) - if (min > pathLength[j]) - { - min = pathLength[j]; - this_id = j; - } - } - if (this_id == end_id) - return pathLength[end_id]; - ++counter; - } - return pathLength[end_id]; +double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, + int start_id, int end_id) { + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + int this_id = start_id; + int counter = 0; + for (; true;) { + if (counter >= n) break; + for (int i = 0; i < n; ++i) { + if (graph[this_id][i]) + pathLength[i] = std::min( + pathLength[i], pathLength[this_id] + graph.GetWeight(this_id, i)); + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) { + if (!ended[j]) + if (min > pathLength[j]) { + min = pathLength[j]; + this_id = j; + } + } + if (this_id == end_id) return pathLength[end_id]; + ++counter; + } + return pathLength[end_id]; } -DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, int end_id) -{ - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - std::vector prevs(n, -1); - pathLength[start_id] = 0; - int this_id = start_id; - for (int counter = 0; counter < n && this_id != end_id; ++counter) - { - for (int i = 0; i < n; ++i) - { - if (graph[this_id][i] && pathLength[i] > pathLength[this_id] + graph[this_id][i]) - { - pathLength[i] = pathLength[this_id] + graph[this_id][i]; - prevs[i] = this_id; - } - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) - { - if (!ended[j]) - if (min > pathLength[j]) - { - min = pathLength[j]; - this_id = j; - } - } - } - std::vector path; - for (int i = end_id; i != start_id ; i = prevs[i]) - path.push_back(prevs[i]); - for (int i = 0; i < path.size() / 2; ++i) - std::swap(path[i], path[path.size() - 1 - i]); - return DeikstraReturn(path, pathLength[end_id]); +DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, + int end_id) { + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + std::vector prevs(n, -1); + pathLength[start_id] = 0; + int this_id = start_id; + for (int counter = 0; counter < n && this_id != end_id; ++counter) { + for (int i = 0; i < n; ++i) { + if (graph[this_id][i] && + pathLength[i] > pathLength[this_id] + graph[this_id][i]) { + pathLength[i] = pathLength[this_id] + graph[this_id][i]; + prevs[i] = this_id; + } + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) { + if (!ended[j]) + if (min > pathLength[j]) { + min = pathLength[j]; + this_id = j; + } + } + } + std::vector path; + for (int i = end_id; i != start_id; i = prevs[i]) path.push_back(prevs[i]); + for (int i = 0; i < path.size() / 2; ++i) + std::swap(path[i], path[path.size() - 1 - i]); + return DeikstraReturn(path, pathLength[end_id]); } -DeikstraReturn DeikstraPathAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id) -{ - if (start_id == end_id) - return DeikstraReturn(std::vector(), 0); - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - std::vector prevs(n, -1); - pathLength[start_id] = 0; - int this_id = start_id; - for (int counter = 0; counter < n && this_id != end_id; ++counter) - { - for (int i = 0; i < n; ++i) - { - if (graph[this_id][i] && pathLength[i] > pathLength[this_id] + graph.GetWeight(this_id, i)) - { - pathLength[i] = pathLength[this_id] + graph.GetWeight(this_id, i); - prevs[i] = this_id; - } - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) - { - if (!ended[j]) - if (min > pathLength[j]) - { - min = pathLength[j]; - this_id = j; - } - } - } - std::vector path; - path.push_back(end_id); - for (int i = end_id; i != start_id; i = prevs[i]) - path.push_back(prevs[i]); - for (int i = 0; i < path.size() / 2; ++i) - std::swap(path[i], path[path.size() - 1 - i]); - return DeikstraReturn(path, pathLength[end_id]); +DeikstraReturn DeikstraPathAlgorithm( + const OrientedWeightedGraphWithZeroWeight& graph, int start_id, + int end_id) { + if (start_id == end_id) return DeikstraReturn(std::vector(), 0); + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + std::vector prevs(n, -1); + pathLength[start_id] = 0; + int this_id = start_id; + for (int counter = 0; counter < n && this_id != end_id; ++counter) { + for (int i = 0; i < n; ++i) { + if (graph[this_id][i] && + pathLength[i] > pathLength[this_id] + graph.GetWeight(this_id, i)) { + pathLength[i] = pathLength[this_id] + graph.GetWeight(this_id, i); + prevs[i] = this_id; + } + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) { + if (!ended[j]) + if (min > pathLength[j]) { + min = pathLength[j]; + this_id = j; + } + } + } + std::vector path; + path.push_back(end_id); + for (int i = end_id; i != start_id; i = prevs[i]) path.push_back(prevs[i]); + for (int i = 0; i < path.size() / 2; ++i) + std::swap(path[i], path[path.size() - 1 - i]); + return DeikstraReturn(path, pathLength[end_id]); } diff --git a/task_03/src/DeikstraAlgorithm.h b/task_03/src/DeikstraAlgorithm.h index c44690a..61bf7d5 100644 --- a/task_03/src/DeikstraAlgorithm.h +++ b/task_03/src/DeikstraAlgorithm.h @@ -2,13 +2,15 @@ #include -struct DeikstraReturn -{ - std::vector path; - double pathLength; +struct DeikstraReturn { + std::vector path; + double pathLength; }; double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id); -double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id); -DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, int end_id); -DeikstraReturn DeikstraPathAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id); +double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, + int start_id, int end_id); +DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, + int end_id); +DeikstraReturn DeikstraPathAlgorithm( + const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id); diff --git a/task_03/src/JonsonAlgorithm.cpp b/task_03/src/JonsonAlgorithm.cpp index e4a62a4..7654cac 100644 --- a/task_03/src/JonsonAlgorithm.cpp +++ b/task_03/src/JonsonAlgorithm.cpp @@ -1,30 +1,27 @@ #include "JonsonAlgorithm.h" -double GetPathLength(const WeightedGraph& graph, const std::vector& path) -{ - if (path.size() == 0) - return 0; - double result = 0; - for (int i = 0; i < path.size() - 1; ++i) - result += graph[path[i]][path[i + 1]]; - return result; +double GetPathLength(const WeightedGraph& graph, const std::vector& path) { + if (path.size() == 0) return 0; + double result = 0; + for (int i = 0; i < path.size() - 1; ++i) + result += graph[path[i]][path[i + 1]]; + return result; } -OrientedWeightedGraphWithZeroWeight JonsonAlgorithm(const WeightedGraph& graph) -{ - int n = graph.GetVerts(); - OrientedWeightedGraphWithZeroWeight new_graph(graph); - for (int i = 0; i < n; ++i) - new_graph.AddEdge(n, i, 0); - auto h = BellmanFordAlgorithm(new_graph, n); - if (h.size() == 0) - return WeightedGraph(); - for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - new_graph.GetWeight(i, j) += h[i] - h[j]; - OrientedWeightedGraphWithZeroWeight resultGraph; - for (int i = 0; i < n; ++i) - for (int j = 0; j < n; ++j) - resultGraph.AddEdge(i, j, GetPathLength(graph, DeikstraPathAlgorithm(new_graph, i, j).path)); - return resultGraph; -} \ No newline at end of file +OrientedWeightedGraphWithZeroWeight JonsonAlgorithm( + const WeightedGraph& graph) { + int n = graph.GetVerts(); + OrientedWeightedGraphWithZeroWeight new_graph(graph); + for (int i = 0; i < n; ++i) new_graph.AddEdge(n, i, 0); + auto h = BellmanFordAlgorithm(new_graph, n); + if (h.size() == 0) return WeightedGraph(); + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) new_graph.GetWeight(i, j) += h[i] - h[j]; + OrientedWeightedGraphWithZeroWeight resultGraph; + for (int i = 0; i < n; ++i) + for (int j = 0; j < n; ++j) + resultGraph.AddEdge( + i, j, + GetPathLength(graph, DeikstraPathAlgorithm(new_graph, i, j).path)); + return resultGraph; +} diff --git a/task_03/src/main.cpp b/task_03/src/main.cpp index a0e986b..8fc394d 100644 --- a/task_03/src/main.cpp +++ b/task_03/src/main.cpp @@ -1,56 +1,55 @@ -#include #include -#include "DeikstraAlgorithm.h" + +#include + #include "BellmanForlAlgorithm.h" +#include "DeikstraAlgorithm.h" #include "JonsonAlgorithm.h" -int main() -{ - WeightedNonOrientedGraph graph; - graph.AddEdge(0, 1, 10); - graph.AddEdge(0, 2, 2); - graph.AddEdge(0, 3, 7); - graph.AddEdge(0, 4, 8); - graph.AddEdge(1, 3, 1); - graph.AddEdge(1, 5, 5); - graph.AddEdge(2, 3, 3); - graph.AddEdge(2, 4, 5); - graph.AddEdge(3, 4, 1); - graph.AddEdge(3, 5, 4); - graph.AddEdge(4, 5, 2); - - auto bf = BellmanFordAlgorithm(graph, 0); - auto deikstra = DeikstraPathAlgorithm(graph, 0, 5); - - graph.Print(); - std::cout << "Deikstra: " << deikstra.pathLength << std::endl; - for (int i = 0; i < deikstra.path.size(); ++i) - std::cout << deikstra.path[i] << ", "; - std::cout << std::endl; - std::cout << "Bellman Ford: "; - for (int i = 0; i < bf.size(); ++i) - std::cout << bf[i] << ", "; - std::cout << std::endl; - - WeightedOrientedGraph secondGraph; - secondGraph.AddEdge(0, 1, 2); - secondGraph.AddEdge(0, 2, 3); - secondGraph.AddEdge(1, 0, -1); - secondGraph.AddEdge(1, 2, 4); - secondGraph.AddEdge(2, 0, -2); - secondGraph.AddEdge(2, 1, 1); - - bf = BellmanFordAlgorithm(secondGraph, 0); - - secondGraph.Print(); - std::cout << "Bellman Ford: "; - for (int i = 0; i < bf.size(); ++i) - std::cout << bf[i] << ", "; - std::cout << std::endl; - std::cout << "Jonson: " << std::endl; - auto jons = JonsonAlgorithm(secondGraph); - jons.Print(); - std::cout << std::endl; - - return 0; +int main() { + WeightedNonOrientedGraph graph; + graph.AddEdge(0, 1, 10); + graph.AddEdge(0, 2, 2); + graph.AddEdge(0, 3, 7); + graph.AddEdge(0, 4, 8); + graph.AddEdge(1, 3, 1); + graph.AddEdge(1, 5, 5); + graph.AddEdge(2, 3, 3); + graph.AddEdge(2, 4, 5); + graph.AddEdge(3, 4, 1); + graph.AddEdge(3, 5, 4); + graph.AddEdge(4, 5, 2); + + auto bf = BellmanFordAlgorithm(graph, 0); + auto deikstra = DeikstraPathAlgorithm(graph, 0, 5); + + graph.Print(); + std::cout << "Deikstra: " << deikstra.pathLength << std::endl; + for (int i = 0; i < deikstra.path.size(); ++i) + std::cout << deikstra.path[i] << ", "; + std::cout << std::endl; + std::cout << "Bellman Ford: "; + for (int i = 0; i < bf.size(); ++i) std::cout << bf[i] << ", "; + std::cout << std::endl; + + WeightedOrientedGraph secondGraph; + secondGraph.AddEdge(0, 1, 2); + secondGraph.AddEdge(0, 2, 3); + secondGraph.AddEdge(1, 0, -1); + secondGraph.AddEdge(1, 2, 4); + secondGraph.AddEdge(2, 0, -2); + secondGraph.AddEdge(2, 1, 1); + + bf = BellmanFordAlgorithm(secondGraph, 0); + + secondGraph.Print(); + std::cout << "Bellman Ford: "; + for (int i = 0; i < bf.size(); ++i) std::cout << bf[i] << ", "; + std::cout << std::endl; + std::cout << "Jonson: " << std::endl; + auto jons = JonsonAlgorithm(secondGraph); + jons.Print(); + std::cout << std::endl; + + return 0; } diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index 87e9d4d..5ad5b61 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,35 +1,36 @@ -#include #include +#include + #include "JonsonAlgorithm.h" -bool operator==(const OrientedWeightedGraphWithZeroWeight& first, const OrientedWeightedGraphWithZeroWeight& second) -{ - if (first.GetVerts() != second.GetVerts()) - return false; - for (int i = 0; i < first.GetVerts(); ++i) - for (int j = 0; j < first.GetVerts(); ++j) - if (first[i][j] != second[i][j] || first.GetWeight(i, j) != second.GetWeight(i, j)) - return false; - return true; +bool operator==(const OrientedWeightedGraphWithZeroWeight& first, + const OrientedWeightedGraphWithZeroWeight& second) { + if (first.GetVerts() != second.GetVerts()) return false; + for (int i = 0; i < first.GetVerts(); ++i) + for (int j = 0; j < first.GetVerts(); ++j) + if (first[i][j] != second[i][j] || + first.GetWeight(i, j) != second.GetWeight(i, j)) + return false; + return true; } TEST(TopologicalSort, Simple) { - WeightedOrientedGraph test_graph; - test_graph.AddEdge(0, 1, 2); - test_graph.AddEdge(0, 2, 3); - test_graph.AddEdge(1, 0, -1); - test_graph.AddEdge(1, 2, 4); - test_graph.AddEdge(2, 0, -2); - test_graph.AddEdge(2, 1, 1); - auto jons_graph = JonsonAlgorithm(test_graph); + WeightedOrientedGraph test_graph; + test_graph.AddEdge(0, 1, 2); + test_graph.AddEdge(0, 2, 3); + test_graph.AddEdge(1, 0, -1); + test_graph.AddEdge(1, 2, 4); + test_graph.AddEdge(2, 0, -2); + test_graph.AddEdge(2, 1, 1); + auto jons_graph = JonsonAlgorithm(test_graph); - OrientedWeightedGraphWithZeroWeight true_jons_graph; - true_jons_graph.AddEdge(0, 1, 2); - true_jons_graph.AddEdge(0, 2, 3); - true_jons_graph.AddEdge(1, 0, -1); - true_jons_graph.AddEdge(1, 2, 2); - true_jons_graph.AddEdge(2, 0, -2); - true_jons_graph.AddEdge(2, 1, 0); + OrientedWeightedGraphWithZeroWeight true_jons_graph; + true_jons_graph.AddEdge(0, 1, 2); + true_jons_graph.AddEdge(0, 2, 3); + true_jons_graph.AddEdge(1, 0, -1); + true_jons_graph.AddEdge(1, 2, 2); + true_jons_graph.AddEdge(2, 0, -2); + true_jons_graph.AddEdge(2, 1, 0); - ASSERT_EQ(jons_graph, true_jons_graph); -} \ No newline at end of file + ASSERT_EQ(jons_graph, true_jons_graph); +} diff --git a/task_04/src/DeikstraAlgorithm.cpp b/task_04/src/DeikstraAlgorithm.cpp index 7b5018b..baab66b 100644 --- a/task_04/src/DeikstraAlgorithm.cpp +++ b/task_04/src/DeikstraAlgorithm.cpp @@ -1,150 +1,129 @@ #include "DeikstraAlgorithm.h" -double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id) -{ - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - pathLength[start_id] = 0; - int this_id = start_id; - int counter = 0; - for (; true; ) - { - if (counter >= n) - break; - for (int i = 0; i < n; ++i) - { - if (graph[this_id][i]) - pathLength[i] = std::min(pathLength[i], pathLength[this_id] + graph[this_id][i]); - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) - { - if (!ended[j]) - if (min > pathLength[j]) - { - min = pathLength[j]; - this_id = j; - } - } - if (this_id == end_id) - return pathLength[end_id]; - ++counter; - } - return pathLength[end_id]; +double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id) { + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + int this_id = start_id; + int counter = 0; + for (; true;) { + if (counter >= n) break; + for (int i = 0; i < n; ++i) { + if (graph[this_id][i]) + pathLength[i] = + std::min(pathLength[i], pathLength[this_id] + graph[this_id][i]); + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) { + if (!ended[j]) + if (min > pathLength[j]) { + min = pathLength[j]; + this_id = j; + } + } + if (this_id == end_id) return pathLength[end_id]; + ++counter; + } + return pathLength[end_id]; } -double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id) -{ - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - pathLength[start_id] = 0; - int this_id = start_id; - int counter = 0; - for (; true; ) - { - if (counter >= n) - break; - for (int i = 0; i < n; ++i) - { - if (graph[this_id][i]) - pathLength[i] = std::min(pathLength[i], pathLength[this_id] + graph.GetWeight(this_id, i)); - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) - { - if (!ended[j]) - if (min > pathLength[j]) - { - min = pathLength[j]; - this_id = j; - } - } - if (this_id == end_id) - return pathLength[end_id]; - ++counter; - } - return pathLength[end_id]; +double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, + int start_id, int end_id) { + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + pathLength[start_id] = 0; + int this_id = start_id; + int counter = 0; + for (; true;) { + if (counter >= n) break; + for (int i = 0; i < n; ++i) { + if (graph[this_id][i]) + pathLength[i] = std::min( + pathLength[i], pathLength[this_id] + graph.GetWeight(this_id, i)); + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) { + if (!ended[j]) + if (min > pathLength[j]) { + min = pathLength[j]; + this_id = j; + } + } + if (this_id == end_id) return pathLength[end_id]; + ++counter; + } + return pathLength[end_id]; } -DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, int end_id) -{ - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - std::vector prevs(n, -1); - pathLength[start_id] = 0; - int this_id = start_id; - for (int counter = 0; counter < n && this_id != end_id; ++counter) - { - for (int i = 0; i < n; ++i) - { - if (graph[this_id][i] && pathLength[i] > pathLength[this_id] + graph[this_id][i]) - { - pathLength[i] = pathLength[this_id] + graph[this_id][i]; - prevs[i] = this_id; - } - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) - { - if (!ended[j]) - if (min > pathLength[j]) - { - min = pathLength[j]; - this_id = j; - } - } - } - std::vector path; - for (int i = end_id; i != start_id ; i = prevs[i]) - path.push_back(prevs[i]); - for (int i = 0; i < path.size() / 2; ++i) - std::swap(path[i], path[path.size() - 1 - i]); - return DeikstraReturn(path, pathLength[end_id]); +DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, + int end_id) { + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + std::vector prevs(n, -1); + pathLength[start_id] = 0; + int this_id = start_id; + for (int counter = 0; counter < n && this_id != end_id; ++counter) { + for (int i = 0; i < n; ++i) { + if (graph[this_id][i] && + pathLength[i] > pathLength[this_id] + graph[this_id][i]) { + pathLength[i] = pathLength[this_id] + graph[this_id][i]; + prevs[i] = this_id; + } + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) { + if (!ended[j]) + if (min > pathLength[j]) { + min = pathLength[j]; + this_id = j; + } + } + } + std::vector path; + for (int i = end_id; i != start_id; i = prevs[i]) path.push_back(prevs[i]); + for (int i = 0; i < path.size() / 2; ++i) + std::swap(path[i], path[path.size() - 1 - i]); + return DeikstraReturn(path, pathLength[end_id]); } -DeikstraReturn DeikstraPathAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id) -{ - if (start_id == end_id) - return DeikstraReturn(std::vector(), 0); - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - std::vector prevs(n, -1); - pathLength[start_id] = 0; - int this_id = start_id; - for (int counter = 0; counter < n && this_id != end_id; ++counter) - { - for (int i = 0; i < n; ++i) - { - if (graph[this_id][i] && pathLength[i] > pathLength[this_id] + graph.GetWeight(this_id, i)) - { - pathLength[i] = pathLength[this_id] + graph.GetWeight(this_id, i); - prevs[i] = this_id; - } - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) - { - if (!ended[j]) - if (min > pathLength[j]) - { - min = pathLength[j]; - this_id = j; - } - } - } - std::vector path; - path.push_back(end_id); - for (int i = end_id; i != start_id; i = prevs[i]) - path.push_back(prevs[i]); - for (int i = 0; i < path.size() / 2; ++i) - std::swap(path[i], path[path.size() - 1 - i]); - return DeikstraReturn(path, pathLength[end_id]); +DeikstraReturn DeikstraPathAlgorithm( + const OrientedWeightedGraphWithZeroWeight& graph, int start_id, + int end_id) { + if (start_id == end_id) return DeikstraReturn(std::vector(), 0); + int n = graph.GetVerts(); + std::vector ended(n); + std::vector pathLength(n, DBL_MAX); + std::vector prevs(n, -1); + pathLength[start_id] = 0; + int this_id = start_id; + for (int counter = 0; counter < n && this_id != end_id; ++counter) { + for (int i = 0; i < n; ++i) { + if (graph[this_id][i] && + pathLength[i] > pathLength[this_id] + graph.GetWeight(this_id, i)) { + pathLength[i] = pathLength[this_id] + graph.GetWeight(this_id, i); + prevs[i] = this_id; + } + } + ended[this_id] = true; + double min = DBL_MAX; + for (int j = 0; j < n; ++j) { + if (!ended[j]) + if (min > pathLength[j]) { + min = pathLength[j]; + this_id = j; + } + } + } + std::vector path; + path.push_back(end_id); + for (int i = end_id; i != start_id; i = prevs[i]) path.push_back(prevs[i]); + for (int i = 0; i < path.size() / 2; ++i) + std::swap(path[i], path[path.size() - 1 - i]); + return DeikstraReturn(path, pathLength[end_id]); } diff --git a/task_04/src/DeikstraAlgorithm.h b/task_04/src/DeikstraAlgorithm.h index c44690a..61bf7d5 100644 --- a/task_04/src/DeikstraAlgorithm.h +++ b/task_04/src/DeikstraAlgorithm.h @@ -2,13 +2,15 @@ #include -struct DeikstraReturn -{ - std::vector path; - double pathLength; +struct DeikstraReturn { + std::vector path; + double pathLength; }; double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id); -double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id); -DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, int end_id); -DeikstraReturn DeikstraPathAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id); +double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, + int start_id, int end_id); +DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, + int end_id); +DeikstraReturn DeikstraPathAlgorithm( + const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id); diff --git a/task_04/src/main.cpp b/task_04/src/main.cpp index bdebb1e..7b986c1 100644 --- a/task_04/src/main.cpp +++ b/task_04/src/main.cpp @@ -1,26 +1,26 @@ #include + #include "DeikstraAlgorithm.h" -int main() -{ - WeightedNonOrientedGraph graph; - graph.AddEdge(0, 1, 10); - graph.AddEdge(0, 2, 2); - graph.AddEdge(0, 3, 7); - graph.AddEdge(0, 4, 8); - graph.AddEdge(1, 3, 1); - graph.AddEdge(1, 5, 5); - graph.AddEdge(2, 3, 3); - graph.AddEdge(2, 4, 5); - graph.AddEdge(3, 4, 1); - graph.AddEdge(3, 5, 4); - graph.AddEdge(4, 5, 2); +int main() { + WeightedNonOrientedGraph graph; + graph.AddEdge(0, 1, 10); + graph.AddEdge(0, 2, 2); + graph.AddEdge(0, 3, 7); + graph.AddEdge(0, 4, 8); + graph.AddEdge(1, 3, 1); + graph.AddEdge(1, 5, 5); + graph.AddEdge(2, 3, 3); + graph.AddEdge(2, 4, 5); + graph.AddEdge(3, 4, 1); + graph.AddEdge(3, 5, 4); + graph.AddEdge(4, 5, 2); - auto deikstra = DeikstraPathAlgorithm(graph, 0, 5); + auto deikstra = DeikstraPathAlgorithm(graph, 0, 5); - graph.Print(); - std::cout << "Deikstra: " << deikstra.pathLength << std::endl; - for (int i = 0; i < deikstra.path.size(); ++i) - std::cout << deikstra.path[i] << ", "; - std::cout << std::endl; + graph.Print(); + std::cout << "Deikstra: " << deikstra.pathLength << std::endl; + for (int i = 0; i < deikstra.path.size(); ++i) + std::cout << deikstra.path[i] << ", "; + std::cout << std::endl; } diff --git a/task_04/src/test.cpp b/task_04/src/test.cpp index 44e2b16..66ff4b2 100644 --- a/task_04/src/test.cpp +++ b/task_04/src/test.cpp @@ -1,29 +1,29 @@ -#include #include +#include + #include "DeikstraAlgorithm.h" -bool operator==(const DeikstraReturn& first, const DeikstraReturn& second) -{ - if (first.path != second.path || first.pathLength != second.pathLength) - return false; - return true; +bool operator==(const DeikstraReturn& first, const DeikstraReturn& second) { + if (first.path != second.path || first.pathLength != second.pathLength) + return false; + return true; } TEST(TopologicalSort, Simple) { - WeightedNonOrientedGraph graph; - graph.AddEdge(0, 1, 10); - graph.AddEdge(0, 2, 2); - graph.AddEdge(0, 3, 7); - graph.AddEdge(0, 4, 8); - graph.AddEdge(1, 3, 1); - graph.AddEdge(1, 5, 5); - graph.AddEdge(2, 3, 3); - graph.AddEdge(2, 4, 5); - graph.AddEdge(3, 4, 1); - graph.AddEdge(3, 5, 4); - graph.AddEdge(4, 5, 2); + WeightedNonOrientedGraph graph; + graph.AddEdge(0, 1, 10); + graph.AddEdge(0, 2, 2); + graph.AddEdge(0, 3, 7); + graph.AddEdge(0, 4, 8); + graph.AddEdge(1, 3, 1); + graph.AddEdge(1, 5, 5); + graph.AddEdge(2, 3, 3); + graph.AddEdge(2, 4, 5); + graph.AddEdge(3, 4, 1); + graph.AddEdge(3, 5, 4); + graph.AddEdge(4, 5, 2); - auto deikstra = DeikstraPathAlgorithm(graph, 0, 5); - DeikstraReturn true_deikstra({0, 2, 3, 4}, 8); - ASSERT_EQ(deikstra, true_deikstra); -} \ No newline at end of file + auto deikstra = DeikstraPathAlgorithm(graph, 0, 5); + DeikstraReturn true_deikstra({0, 2, 3, 4}, 8); + ASSERT_EQ(deikstra, true_deikstra); +} diff --git a/task_05/src/main.cpp b/task_05/src/main.cpp index ff91baa..ce77b09 100644 --- a/task_05/src/main.cpp +++ b/task_05/src/main.cpp @@ -1,10 +1,9 @@ #include // Driver code -int main() -{ - std::vector a = { 1, 3, 2, 7, 9, 11, 5, 4, 6, 8 }; - RMQ rmq(a); - rmq.Print(); - return 0; -} \ No newline at end of file +int main() { + std::vector a = {1, 3, 2, 7, 9, 11, 5, 4, 6, 8}; + RMQ rmq(a); + rmq.Print(); + return 0; +} diff --git a/task_05/src/test.cpp b/task_05/src/test.cpp index 94a87e8..2fd7fde 100644 --- a/task_05/src/test.cpp +++ b/task_05/src/test.cpp @@ -2,12 +2,12 @@ #include TEST(RMQTest, Simple) { - std::vector testArray = { 1, 3, 2, 7, 9, 11, 5, 4, 6, 8 }; - RMQ testRMQ(testArray); - ASSERT_EQ(testRMQ.get_min(0, 5), 0); - ASSERT_EQ(testRMQ.get_min(3, 7), 7); - ASSERT_EQ(testRMQ.get_min(7, 8), 7); - ASSERT_EQ(testRMQ.get_min(2, 2), 2); - ASSERT_EQ(testRMQ.get_min(3, 5), 3); - ASSERT_EQ(testRMQ.get_min(5, 9), 7); -} \ No newline at end of file + std::vector testArray = {1, 3, 2, 7, 9, 11, 5, 4, 6, 8}; + RMQ testRMQ(testArray); + ASSERT_EQ(testRMQ.get_min(0, 5), 0); + ASSERT_EQ(testRMQ.get_min(3, 7), 7); + ASSERT_EQ(testRMQ.get_min(7, 8), 7); + ASSERT_EQ(testRMQ.get_min(2, 2), 2); + ASSERT_EQ(testRMQ.get_min(3, 5), 3); + ASSERT_EQ(testRMQ.get_min(5, 9), 7); +} diff --git a/task_06/src/main.cpp b/task_06/src/main.cpp index 65a823e..863d5a3 100644 --- a/task_06/src/main.cpp +++ b/task_06/src/main.cpp @@ -1,26 +1,27 @@ -#include #include +#include + int main() { - Node* root = new Node(20); - root->left = new Node(8); - root->right = new Node(22); - root->left->left = new Node(4); - root->left->right = new Node(12); - root->left->right->left = new Node(10); - root->left->right->right = new Node(14); + Node* root = new Node(20); + root->left = new Node(8); + root->right = new Node(22); + root->left->left = new Node(4); + root->left->right = new Node(12); + root->left->right->left = new Node(10); + root->left->right->right = new Node(14); - int n1 = 10, n2 = 14; - Node* t = LCA(root, n1, n2); - std::cout << n1 << " < " << t->data << " < " << n2 << std::endl; + int n1 = 10, n2 = 14; + Node* t = LCA(root, n1, n2); + std::cout << n1 << " < " << t->data << " < " << n2 << std::endl; - n1 = 14, n2 = 8; - t = LCA(root, n1, n2); - std::cout << n1 << " < " << t->data << " < " << n2 << std::endl; + n1 = 14, n2 = 8; + t = LCA(root, n1, n2); + std::cout << n1 << " < " << t->data << " < " << n2 << std::endl; - n1 = 10, n2 = 22; - t = LCA(root, n1, n2); - std::cout<< n1 << " < " << t->data << " < " << n2 << std::endl; + n1 = 10, n2 = 22; + t = LCA(root, n1, n2); + std::cout << n1 << " < " << t->data << " < " << n2 << std::endl; - return 0; -} \ No newline at end of file + return 0; +} diff --git a/task_06/src/test.cpp b/task_06/src/test.cpp index 85683da..5efe107 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,25 +1,24 @@ -#include #include +#include TEST(LCATest, Simple) { - Node* root = new Node(20); - root->left = new Node(8); - root->right = new Node(22); - root->left->left = new Node(4); - root->left->right = new Node(12); - root->left->right->left = new Node(10); - root->left->right->right = new Node(14); - - int n1 = 10, n2 = 14; - Node* t = LCA(root, n1, n2); - ASSERT_EQ(t->data, 12); + Node* root = new Node(20); + root->left = new Node(8); + root->right = new Node(22); + root->left->left = new Node(4); + root->left->right = new Node(12); + root->left->right->left = new Node(10); + root->left->right->right = new Node(14); - n1 = 8, n2 = 14; - t = LCA(root, n1, n2); - ASSERT_EQ(t->data, 8); + int n1 = 10, n2 = 14; + Node* t = LCA(root, n1, n2); + ASSERT_EQ(t->data, 12); - n1 = 10, n2 = 22; - t = LCA(root, n1, n2); - ASSERT_EQ(t->data, 20); + n1 = 8, n2 = 14; + t = LCA(root, n1, n2); + ASSERT_EQ(t->data, 8); + n1 = 10, n2 = 22; + t = LCA(root, n1, n2); + ASSERT_EQ(t->data, 20); } From 457cd0395c3910f30f5c756478ff60daa40a3800 Mon Sep 17 00:00:00 2001 From: Vanek <123vanichka321@gmail.com> Date: Thu, 16 Jan 2025 14:09:13 +0300 Subject: [PATCH 08/11] move files to lib --- {task_03 => lib}/src/BellmanFordAlgorithm.cpp | 0 {task_03 => lib}/src/BellmanForlAlgorithm.h | 0 {task_03 => lib}/src/DeikstraAlgorithm.cpp | 0 {task_03 => lib}/src/DeikstraAlgorithm.h | 0 {task_03 => lib}/src/JonsonAlgorithm.cpp | 0 {task_03 => lib}/src/JonsonAlgorithm.h | 0 {task_02 => lib}/src/SearchWeakVE.cpp | 0 {task_02 => lib}/src/SearchWeakVE.h | 0 {task_01 => lib}/src/topologicalSort.cpp | 0 {task_01 => lib}/src/topologicalSort.h | 0 task_01/CMakeLists.txt | 4 +- task_01/src/main.cpp | 3 +- task_01/src/test.cpp | 5 +- task_02/src/main.cpp | 3 +- task_02/src/test.cpp | 5 +- task_03/src/main.cpp | 7 +- task_03/src/test.cpp | 5 +- task_04/src/DeikstraAlgorithm.cpp | 129 ------------------ task_04/src/DeikstraAlgorithm.h | 16 --- task_04/src/main.cpp | 4 +- task_04/src/test.cpp | 2 +- task_05/src/main.cpp | 1 - 22 files changed, 16 insertions(+), 168 deletions(-) rename {task_03 => lib}/src/BellmanFordAlgorithm.cpp (100%) rename {task_03 => lib}/src/BellmanForlAlgorithm.h (100%) rename {task_03 => lib}/src/DeikstraAlgorithm.cpp (100%) rename {task_03 => lib}/src/DeikstraAlgorithm.h (100%) rename {task_03 => lib}/src/JonsonAlgorithm.cpp (100%) rename {task_03 => lib}/src/JonsonAlgorithm.h (100%) rename {task_02 => lib}/src/SearchWeakVE.cpp (100%) rename {task_02 => lib}/src/SearchWeakVE.h (100%) rename {task_01 => lib}/src/topologicalSort.cpp (100%) rename {task_01 => lib}/src/topologicalSort.h (100%) delete mode 100644 task_04/src/DeikstraAlgorithm.cpp delete mode 100644 task_04/src/DeikstraAlgorithm.h diff --git a/task_03/src/BellmanFordAlgorithm.cpp b/lib/src/BellmanFordAlgorithm.cpp similarity index 100% rename from task_03/src/BellmanFordAlgorithm.cpp rename to lib/src/BellmanFordAlgorithm.cpp diff --git a/task_03/src/BellmanForlAlgorithm.h b/lib/src/BellmanForlAlgorithm.h similarity index 100% rename from task_03/src/BellmanForlAlgorithm.h rename to lib/src/BellmanForlAlgorithm.h diff --git a/task_03/src/DeikstraAlgorithm.cpp b/lib/src/DeikstraAlgorithm.cpp similarity index 100% rename from task_03/src/DeikstraAlgorithm.cpp rename to lib/src/DeikstraAlgorithm.cpp diff --git a/task_03/src/DeikstraAlgorithm.h b/lib/src/DeikstraAlgorithm.h similarity index 100% rename from task_03/src/DeikstraAlgorithm.h rename to lib/src/DeikstraAlgorithm.h diff --git a/task_03/src/JonsonAlgorithm.cpp b/lib/src/JonsonAlgorithm.cpp similarity index 100% rename from task_03/src/JonsonAlgorithm.cpp rename to lib/src/JonsonAlgorithm.cpp diff --git a/task_03/src/JonsonAlgorithm.h b/lib/src/JonsonAlgorithm.h similarity index 100% rename from task_03/src/JonsonAlgorithm.h rename to lib/src/JonsonAlgorithm.h diff --git a/task_02/src/SearchWeakVE.cpp b/lib/src/SearchWeakVE.cpp similarity index 100% rename from task_02/src/SearchWeakVE.cpp rename to lib/src/SearchWeakVE.cpp diff --git a/task_02/src/SearchWeakVE.h b/lib/src/SearchWeakVE.h similarity index 100% rename from task_02/src/SearchWeakVE.h rename to lib/src/SearchWeakVE.h diff --git a/task_01/src/topologicalSort.cpp b/lib/src/topologicalSort.cpp similarity index 100% rename from task_01/src/topologicalSort.cpp rename to lib/src/topologicalSort.cpp diff --git a/task_01/src/topologicalSort.h b/lib/src/topologicalSort.h similarity index 100% rename from task_01/src/topologicalSort.h rename to lib/src/topologicalSort.h diff --git a/task_01/CMakeLists.txt b/task_01/CMakeLists.txt index 0dd92e2..8f28021 100644 --- a/task_01/CMakeLists.txt +++ b/task_01/CMakeLists.txt @@ -17,7 +17,7 @@ list(REMOVE_ITEM source_list ${test_list}) include_directories(${PROJECT_NAME} PUBLIC src) -add_executable(${PROJECT_NAME} ${source_list} "src/topologicalSort.cpp") +add_executable(${PROJECT_NAME} ${source_list} "../lib/src/topologicalSort.cpp") # Locate GTest enable_testing() @@ -29,7 +29,7 @@ find_library(Utils ../) target_link_libraries(${PROJECT_NAME} PUBLIC Utils) # Link runTests with what we want to test and the GTest and pthread library -add_executable(${PROJECT_NAME}_tests ${test_source_list} "src/topologicalSort.cpp") +add_executable(${PROJECT_NAME}_tests ${test_source_list} "../lib/src/topologicalSort.cpp") target_link_libraries( ${PROJECT_NAME}_tests GTest::gtest_main diff --git a/task_01/src/main.cpp b/task_01/src/main.cpp index f606ee2..4171d95 100644 --- a/task_01/src/main.cpp +++ b/task_01/src/main.cpp @@ -1,6 +1,5 @@ #include - -#include "topologicalSort.h" +#include std::ostream& operator<<(std::ostream& os, const std::vector& vec) { for (int i = 0; i < vec.size(); ++i) os << vec[i] << ", "; diff --git a/task_01/src/test.cpp b/task_01/src/test.cpp index 936c720..1fd7584 100644 --- a/task_01/src/test.cpp +++ b/task_01/src/test.cpp @@ -1,9 +1,8 @@ #include #include +#include -#include "topologicalSort.h" - -TEST(TopologicalSort, Simple) { +TEST(TopologicalSortTest, Simple) { OrientedGraph graph; graph.AddEdge(0, 3); graph.AddEdge(3, 1); diff --git a/task_02/src/main.cpp b/task_02/src/main.cpp index 25087f2..00a292e 100644 --- a/task_02/src/main.cpp +++ b/task_02/src/main.cpp @@ -1,9 +1,8 @@ +#include #include #include -#include "SearchWeakVE.h" - int main() { NonOrientedGraph graph; graph.AddEdge(0, 1); diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index c7c9608..0397f0f 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -1,9 +1,8 @@ +#include #include #include -#include "SearchWeakVE.h" - -TEST(TopologicalSort, Simple) { +TEST(SearchWeakVETest, Simple) { NonOrientedGraph graph; graph.AddEdge(0, 1); graph.AddEdge(0, 2); diff --git a/task_03/src/main.cpp b/task_03/src/main.cpp index 8fc394d..9173904 100644 --- a/task_03/src/main.cpp +++ b/task_03/src/main.cpp @@ -1,11 +1,10 @@ +#include +#include +#include #include #include -#include "BellmanForlAlgorithm.h" -#include "DeikstraAlgorithm.h" -#include "JonsonAlgorithm.h" - int main() { WeightedNonOrientedGraph graph; graph.AddEdge(0, 1, 10); diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index 5ad5b61..d97de9b 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,8 +1,7 @@ +#include #include #include -#include "JonsonAlgorithm.h" - bool operator==(const OrientedWeightedGraphWithZeroWeight& first, const OrientedWeightedGraphWithZeroWeight& second) { if (first.GetVerts() != second.GetVerts()) return false; @@ -14,7 +13,7 @@ bool operator==(const OrientedWeightedGraphWithZeroWeight& first, return true; } -TEST(TopologicalSort, Simple) { +TEST(JonsonAlgorithmTest, Simple) { WeightedOrientedGraph test_graph; test_graph.AddEdge(0, 1, 2); test_graph.AddEdge(0, 2, 3); diff --git a/task_04/src/DeikstraAlgorithm.cpp b/task_04/src/DeikstraAlgorithm.cpp deleted file mode 100644 index baab66b..0000000 --- a/task_04/src/DeikstraAlgorithm.cpp +++ /dev/null @@ -1,129 +0,0 @@ -#include "DeikstraAlgorithm.h" - -double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id) { - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - pathLength[start_id] = 0; - int this_id = start_id; - int counter = 0; - for (; true;) { - if (counter >= n) break; - for (int i = 0; i < n; ++i) { - if (graph[this_id][i]) - pathLength[i] = - std::min(pathLength[i], pathLength[this_id] + graph[this_id][i]); - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) { - if (!ended[j]) - if (min > pathLength[j]) { - min = pathLength[j]; - this_id = j; - } - } - if (this_id == end_id) return pathLength[end_id]; - ++counter; - } - return pathLength[end_id]; -} - -double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, - int start_id, int end_id) { - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - pathLength[start_id] = 0; - int this_id = start_id; - int counter = 0; - for (; true;) { - if (counter >= n) break; - for (int i = 0; i < n; ++i) { - if (graph[this_id][i]) - pathLength[i] = std::min( - pathLength[i], pathLength[this_id] + graph.GetWeight(this_id, i)); - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) { - if (!ended[j]) - if (min > pathLength[j]) { - min = pathLength[j]; - this_id = j; - } - } - if (this_id == end_id) return pathLength[end_id]; - ++counter; - } - return pathLength[end_id]; -} - -DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, - int end_id) { - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - std::vector prevs(n, -1); - pathLength[start_id] = 0; - int this_id = start_id; - for (int counter = 0; counter < n && this_id != end_id; ++counter) { - for (int i = 0; i < n; ++i) { - if (graph[this_id][i] && - pathLength[i] > pathLength[this_id] + graph[this_id][i]) { - pathLength[i] = pathLength[this_id] + graph[this_id][i]; - prevs[i] = this_id; - } - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) { - if (!ended[j]) - if (min > pathLength[j]) { - min = pathLength[j]; - this_id = j; - } - } - } - std::vector path; - for (int i = end_id; i != start_id; i = prevs[i]) path.push_back(prevs[i]); - for (int i = 0; i < path.size() / 2; ++i) - std::swap(path[i], path[path.size() - 1 - i]); - return DeikstraReturn(path, pathLength[end_id]); -} - -DeikstraReturn DeikstraPathAlgorithm( - const OrientedWeightedGraphWithZeroWeight& graph, int start_id, - int end_id) { - if (start_id == end_id) return DeikstraReturn(std::vector(), 0); - int n = graph.GetVerts(); - std::vector ended(n); - std::vector pathLength(n, DBL_MAX); - std::vector prevs(n, -1); - pathLength[start_id] = 0; - int this_id = start_id; - for (int counter = 0; counter < n && this_id != end_id; ++counter) { - for (int i = 0; i < n; ++i) { - if (graph[this_id][i] && - pathLength[i] > pathLength[this_id] + graph.GetWeight(this_id, i)) { - pathLength[i] = pathLength[this_id] + graph.GetWeight(this_id, i); - prevs[i] = this_id; - } - } - ended[this_id] = true; - double min = DBL_MAX; - for (int j = 0; j < n; ++j) { - if (!ended[j]) - if (min > pathLength[j]) { - min = pathLength[j]; - this_id = j; - } - } - } - std::vector path; - path.push_back(end_id); - for (int i = end_id; i != start_id; i = prevs[i]) path.push_back(prevs[i]); - for (int i = 0; i < path.size() / 2; ++i) - std::swap(path[i], path[path.size() - 1 - i]); - return DeikstraReturn(path, pathLength[end_id]); -} diff --git a/task_04/src/DeikstraAlgorithm.h b/task_04/src/DeikstraAlgorithm.h deleted file mode 100644 index 61bf7d5..0000000 --- a/task_04/src/DeikstraAlgorithm.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include - -struct DeikstraReturn { - std::vector path; - double pathLength; -}; - -double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id); -double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph, - int start_id, int end_id); -DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id, - int end_id); -DeikstraReturn DeikstraPathAlgorithm( - const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id); diff --git a/task_04/src/main.cpp b/task_04/src/main.cpp index 7b986c1..1d5bba5 100644 --- a/task_04/src/main.cpp +++ b/task_04/src/main.cpp @@ -1,6 +1,6 @@ -#include +#include -#include "DeikstraAlgorithm.h" +#include int main() { WeightedNonOrientedGraph graph; diff --git a/task_04/src/test.cpp b/task_04/src/test.cpp index 66ff4b2..2db72f4 100644 --- a/task_04/src/test.cpp +++ b/task_04/src/test.cpp @@ -9,7 +9,7 @@ bool operator==(const DeikstraReturn& first, const DeikstraReturn& second) { return true; } -TEST(TopologicalSort, Simple) { +TEST(DeikstraAlgorithmTest, Simple) { WeightedNonOrientedGraph graph; graph.AddEdge(0, 1, 10); graph.AddEdge(0, 2, 2); diff --git a/task_05/src/main.cpp b/task_05/src/main.cpp index ce77b09..cc1c4a5 100644 --- a/task_05/src/main.cpp +++ b/task_05/src/main.cpp @@ -1,6 +1,5 @@ #include -// Driver code int main() { std::vector a = {1, 3, 2, 7, 9, 11, 5, 4, 6, 8}; RMQ rmq(a); From 5b9294cab9bc579e79ad0abea9649e54c9739dff Mon Sep 17 00:00:00 2001 From: Vanek <123vanichka321@gmail.com> Date: Thu, 16 Jan 2025 14:18:46 +0300 Subject: [PATCH 09/11] small fix --- lib/src/BellmanFordAlgorithm.cpp | 2 ++ lib/src/JonsonAlgorithm.h | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/src/BellmanFordAlgorithm.cpp b/lib/src/BellmanFordAlgorithm.cpp index 7c4254c..e5a7931 100644 --- a/lib/src/BellmanFordAlgorithm.cpp +++ b/lib/src/BellmanFordAlgorithm.cpp @@ -1,3 +1,5 @@ +#include + #include "BellmanForlAlgorithm.h" std::vector BellmanFordAlgorithm(const WeightedGraph& graph, diff --git a/lib/src/JonsonAlgorithm.h b/lib/src/JonsonAlgorithm.h index 8abcb04..71392f9 100644 --- a/lib/src/JonsonAlgorithm.h +++ b/lib/src/JonsonAlgorithm.h @@ -1,7 +1,8 @@ #pragma once #include -#include "DeikstraAlgorithm.h" + #include "BellmanForlAlgorithm.h" +#include "DeikstraAlgorithm.h" -OrientedWeightedGraphWithZeroWeight JonsonAlgorithm(const WeightedGraph& graph); \ No newline at end of file +OrientedWeightedGraphWithZeroWeight JonsonAlgorithm(const WeightedGraph& graph); From 2f4f44fd63c5e7df0d0e7accf3a53a3c40704a6f Mon Sep 17 00:00:00 2001 From: Vanek <123vanichka321@gmail.com> Date: Thu, 16 Jan 2025 14:21:15 +0300 Subject: [PATCH 10/11] add #incldue --- lib/src/DeikstraAlgorithm.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/src/DeikstraAlgorithm.cpp b/lib/src/DeikstraAlgorithm.cpp index baab66b..7828306 100644 --- a/lib/src/DeikstraAlgorithm.cpp +++ b/lib/src/DeikstraAlgorithm.cpp @@ -1,5 +1,7 @@ #include "DeikstraAlgorithm.h" +#include + double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id) { int n = graph.GetVerts(); std::vector ended(n); From 7984a8d4869be32c616620b74acd16d42b8f80e4 Mon Sep 17 00:00:00 2001 From: Vanek <123vanichka321@gmail.com> Date: Thu, 16 Jan 2025 14:27:42 +0300 Subject: [PATCH 11/11] fix #include --- task_06/src/main.cpp | 2 +- task_06/src/test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/task_06/src/main.cpp b/task_06/src/main.cpp index 863d5a3..4caec39 100644 --- a/task_06/src/main.cpp +++ b/task_06/src/main.cpp @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/task_06/src/test.cpp b/task_06/src/test.cpp index 5efe107..8bea184 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,4 +1,4 @@ -#include +#include #include TEST(LCATest, Simple) {