From 20d818c8ca882af127ca5b9dbe89db114e9001fb Mon Sep 17 00:00:00 2001 From: Erik Dervishi <132947518+ErikDervishi03@users.noreply.github.com> Date: Tue, 19 Dec 2023 10:53:29 +0100 Subject: [PATCH] Added tests and examples (#376) * added a new DFStest * added a test_8 and test_9 in DFSTest * added Prim example * added Floyd Warshall example * added source of my example * changed to a more comprehensible floyd warshall example * added a floyd warshall test --- examples/CMakeLists.txt | 2 + examples/FloydWarshallExample/CMakeLists.txt | 17 ++++ .../FloydWarshallExample/floyd_warshall.cpp | 45 +++++++++ examples/PrimExample/CMakeLists.txt | 17 ++++ examples/PrimExample/prim_example.cpp | 80 ++++++++++++++++ test/CMakeLists.txt | 1 + test/DFSTest.cpp | 25 ----- test/FloydWarshallTest.cpp | 91 +++++++++++++++++++ 8 files changed, 253 insertions(+), 25 deletions(-) create mode 100644 examples/FloydWarshallExample/CMakeLists.txt create mode 100644 examples/FloydWarshallExample/floyd_warshall.cpp create mode 100644 examples/PrimExample/CMakeLists.txt create mode 100644 examples/PrimExample/prim_example.cpp create mode 100644 test/FloydWarshallTest.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7b3cbc33d..2a485af5d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -5,5 +5,7 @@ add_subdirectory(DialExample) add_subdirectory(DijkstraExample) add_subdirectory(NetworkDynamicsExample) add_subdirectory(PartitionExample) +add_subdirectory(PrimExample) +add_subdirectory(FloydWarshallExample) endif(EXAMPLES) \ No newline at end of file diff --git a/examples/FloydWarshallExample/CMakeLists.txt b/examples/FloydWarshallExample/CMakeLists.txt new file mode 100644 index 000000000..8987bd25d --- /dev/null +++ b/examples/FloydWarshallExample/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.9) +project(floydWarshallExample) + +# specify the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES /usr/local/lib ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}) + +add_executable(floyd_warshall floyd_warshall.cpp) +target_include_directories(floyd_warshall PUBLIC "${CMAKE_SOURCE_DIR}/include") + +target_link_libraries(floyd_warshall + pthread + ssl + crypto + z) \ No newline at end of file diff --git a/examples/FloydWarshallExample/floyd_warshall.cpp b/examples/FloydWarshallExample/floyd_warshall.cpp new file mode 100644 index 000000000..d535a376c --- /dev/null +++ b/examples/FloydWarshallExample/floyd_warshall.cpp @@ -0,0 +1,45 @@ +#include +#include + +using std::make_shared; +// example taken from +// https://www.youtube.com/watch?v=B06q2yjr-Cc +int main() { + CXXGraph::Node node0("0", 0); + CXXGraph::Node node1("1", 1); + CXXGraph::Node node2("2", 2); + CXXGraph::Node node3("3", 3); + CXXGraph::Node node4("4", 4); + + CXXGraph::UndirectedWeightedEdge edge1(1, node0, node1, 1); + CXXGraph::UndirectedWeightedEdge edge2(2, node0, node2, 2); + CXXGraph::UndirectedWeightedEdge edge3(3, node1, node2, 6); + CXXGraph::UndirectedWeightedEdge edge4(4, node1, node3, 4); + CXXGraph::UndirectedWeightedEdge edge5(5, node2, node3, 5); + CXXGraph::UndirectedWeightedEdge edge6(6, node3, node4, 3); + + CXXGraph::T_EdgeSet edgeSet; + edgeSet.insert(make_shared>(edge1)); + edgeSet.insert(make_shared>(edge2)); + edgeSet.insert(make_shared>(edge3)); + edgeSet.insert(make_shared>(edge4)); + edgeSet.insert(make_shared>(edge5)); + edgeSet.insert(make_shared>(edge6)); + // Can print out the edges for debugging + std::cout << edge1 << "\n"; + std::cout << edge2 << "\n"; + std::cout << edge3 << "\n"; + std::cout << edge4 << "\n"; + std::cout << edge5 << "\n"; + std::cout << edge6 << "\n"; + + CXXGraph::Graph graph(edgeSet); + CXXGraph::FWResult res = graph.floydWarshall(); + std::cout << "floyd Warshall Result: " + << "\n"; + for (auto i : res.result) { + std::cout << "distance of: " << i.first.first << " " << i.first.second + << " = " << i.second << "\n"; + } + return 0; +} diff --git a/examples/PrimExample/CMakeLists.txt b/examples/PrimExample/CMakeLists.txt new file mode 100644 index 000000000..8908be132 --- /dev/null +++ b/examples/PrimExample/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.9) +project(PrimExample) + +# specify the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES /usr/local/lib ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}) + +add_executable(prim_example prim_example.cpp) +target_include_directories(prim_example PUBLIC "${CMAKE_SOURCE_DIR}/include") + +target_link_libraries(prim_example + pthread + ssl + crypto + z) \ No newline at end of file diff --git a/examples/PrimExample/prim_example.cpp b/examples/PrimExample/prim_example.cpp new file mode 100644 index 000000000..308421422 --- /dev/null +++ b/examples/PrimExample/prim_example.cpp @@ -0,0 +1,80 @@ +#include +#include + +using std::make_shared; + +// example taken from +// https://www.geeksforgeeks.org/prims-mst-for-adjacency-list-representation-greedy-algo-6/TEST(FWTest, +// test_1) +int main() { + CXXGraph::Node node0("0", 0); + CXXGraph::Node node1("1", 1); + CXXGraph::Node node2("2", 2); + CXXGraph::Node node3("3", 3); + CXXGraph::Node node4("4", 4); + CXXGraph::Node node5("5", 5); + CXXGraph::Node node6("6", 6); + CXXGraph::Node node7("7", 7); + CXXGraph::Node node8("8", 8); + + CXXGraph::UndirectedWeightedEdge edge1(1, node0, node1, 4); + CXXGraph::UndirectedWeightedEdge edge2(2, node0, node7, 8); + CXXGraph::UndirectedWeightedEdge edge3(3, node1, node7, 11); + CXXGraph::UndirectedWeightedEdge edge4(4, node1, node2, 8); + CXXGraph::UndirectedWeightedEdge edge5(5, node2, node8, 2); + CXXGraph::UndirectedWeightedEdge edge6(6, node2, node5, 4); + CXXGraph::UndirectedWeightedEdge edge7(7, node2, node3, 7); + CXXGraph::UndirectedWeightedEdge edge8(8, node3, node3, 1); + CXXGraph::UndirectedWeightedEdge edge9(9, node3, node4, 9); + CXXGraph::UndirectedWeightedEdge edge10(10, node3, node5, 14); + CXXGraph::UndirectedWeightedEdge edge11(11, node4, node5, 10); + CXXGraph::UndirectedWeightedEdge edge12(12, node5, node6, 2); + CXXGraph::UndirectedWeightedEdge edge13(13, node6, node8, 6); + CXXGraph::UndirectedWeightedEdge edge14(14, node6, node7, 1); + CXXGraph::UndirectedWeightedEdge edge15(15, node7, node8, 7); + + CXXGraph::T_EdgeSet edgeSet; + edgeSet.insert(make_shared>(edge1)); + edgeSet.insert(make_shared>(edge2)); + edgeSet.insert(make_shared>(edge3)); + edgeSet.insert(make_shared>(edge4)); + edgeSet.insert(make_shared>(edge5)); + edgeSet.insert(make_shared>(edge6)); + edgeSet.insert(make_shared>(edge7)); + edgeSet.insert(make_shared>(edge8)); + edgeSet.insert(make_shared>(edge9)); + edgeSet.insert(make_shared>(edge10)); + edgeSet.insert(make_shared>(edge11)); + edgeSet.insert(make_shared>(edge12)); + edgeSet.insert(make_shared>(edge13)); + edgeSet.insert(make_shared>(edge14)); + edgeSet.insert(make_shared>(edge15)); + + // Can print out the edges for debugging + std::cout << edge1 << "\n"; + std::cout << edge2 << "\n"; + std::cout << edge3 << "\n"; + std::cout << edge4 << "\n"; + std::cout << edge5 << "\n"; + std::cout << edge6 << "\n"; + std::cout << edge7 << "\n"; + std::cout << edge8 << "\n"; + std::cout << edge9 << "\n"; + std::cout << edge10 << "\n"; + std::cout << edge11 << "\n"; + std::cout << edge12 << "\n"; + std::cout << edge13 << "\n"; + std::cout << edge14 << "\n"; + std::cout << edge15 << "\n"; + + CXXGraph::Graph graph(edgeSet); + auto res = graph.prim(); + std::cout << "Prim Result: " + << "\n"; + for (auto edge : res.mst) { + std::cout << edge.first << " " << edge.second << "\n"; + } + std::cout << "mstCost: " << res.mstCost << "\n"; + + return 0; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d55b6bc9a..31abf0e0c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -97,4 +97,5 @@ if(TEST) add_test(test_topological_sort test_exe --gtest_filter=TopologicalSort*) add_test(test_transitive_reductiono test_exe --gtest_filter=TransitiveReduction*) add_test(test_union_find test_exe --gtest_filter=UnionFind*) + add_test(test_floyd_warshall test_exe --gtest_filter=FloydWarshall*) endif(TEST) diff --git a/test/DFSTest.cpp b/test/DFSTest.cpp index 7d2cf10ef..795c75253 100644 --- a/test/DFSTest.cpp +++ b/test/DFSTest.cpp @@ -139,28 +139,3 @@ TEST(DFSTest, test_6) { ASSERT_FALSE(std::find(res.begin(), res.end(), node3) != res.end()); ASSERT_FALSE(std::find(res.begin(), res.end(), node4) != res.end()); } - -TEST(DFSTest, test_7) { - CXXGraph::Node node1("1", 1); - CXXGraph::Node node2("2", 2); - CXXGraph::Node node3("3", 3); - CXXGraph::Node node4("4", 4); - std::pair *, const CXXGraph::Node *> pairNode( - &node1, &node2); - CXXGraph::DirectedWeightedEdge edge1(1, pairNode, 1); - CXXGraph::DirectedWeightedEdge edge2(2, node2, node3, 1); - CXXGraph::DirectedWeightedEdge edge3(3, node3, node4, 1); - CXXGraph::DirectedWeightedEdge edge4(4, node4, node1, 1); - CXXGraph::T_EdgeSet edgeSet; - edgeSet.insert(make_shared>(edge1)); - edgeSet.insert(make_shared>(edge2)); - edgeSet.insert(make_shared>(edge3)); - edgeSet.insert(make_shared>(edge4)); - CXXGraph::Graph graph(edgeSet); - std::vector> res = graph.depth_first_search(node1); - ASSERT_EQ(res.size(), 4); - ASSERT_TRUE(std::find(res.begin(), res.end(), node1) != res.end()); - ASSERT_TRUE(std::find(res.begin(), res.end(), node2) != res.end()); - ASSERT_TRUE(std::find(res.begin(), res.end(), node3) != res.end()); - ASSERT_TRUE(std::find(res.begin(), res.end(), node4) != res.end()); -} diff --git a/test/FloydWarshallTest.cpp b/test/FloydWarshallTest.cpp new file mode 100644 index 000000000..799b9bdc5 --- /dev/null +++ b/test/FloydWarshallTest.cpp @@ -0,0 +1,91 @@ +#include + +#include "CXXGraph/CXXGraph.hpp" +#include "gtest/gtest.h" + +// Smart pointers alias +template +using unique = std::unique_ptr; +template +using shared = std::shared_ptr; + +using std::make_shared; +using std::make_unique; + +// minimum spanning tree can differ so instead of checking +// the exact order of elements, we can check some properties +// like the length & cost of mst which must remain the same + +// example taken from +// https://www.geeksforgeeks.org/prims-mst-for-adjacency-list-representation-greedy-algo-6/TEST(FWTest, +// test_1) +TEST(FloydWarshallTest, test_1) { + CXXGraph::Node node0("0", 0); + CXXGraph::Node node1("1", 1); + CXXGraph::Node node2("2", 2); + CXXGraph::Node node3("3", 3); + CXXGraph::Node node4("4", 4); + CXXGraph::Node node5("5", 5); + CXXGraph::Node node6("6", 6); + CXXGraph::Node node7("7", 7); + CXXGraph::Node node8("8", 8); + + CXXGraph::UndirectedWeightedEdge edge1(1, node0, node1, 4); + CXXGraph::UndirectedWeightedEdge edge2(2, node0, node7, 8); + CXXGraph::UndirectedWeightedEdge edge3(3, node1, node7, 11); + CXXGraph::UndirectedWeightedEdge edge4(3, node1, node2, 8); + CXXGraph::UndirectedWeightedEdge edge5(4, node7, node8, 7); + CXXGraph::UndirectedWeightedEdge edge6(3, node7, node6, 1); + CXXGraph::UndirectedWeightedEdge edge7(3, node8, node2, 2); + CXXGraph::UndirectedWeightedEdge edge8(3, node8, node6, 6); + CXXGraph::UndirectedWeightedEdge edge9(3, node2, node5, 4); + CXXGraph::UndirectedWeightedEdge edge10(3, node2, node3, 7); + CXXGraph::UndirectedWeightedEdge edge11(3, node6, node5, 2); + CXXGraph::UndirectedWeightedEdge edge12(3, node3, node4, 9); + CXXGraph::UndirectedWeightedEdge edge13(3, node3, node5, 14); + CXXGraph::UndirectedWeightedEdge edge14(3, node5, node4, 10); + + CXXGraph::T_EdgeSet edgeSet; + edgeSet.insert(make_shared>(edge1)); + edgeSet.insert(make_shared>(edge5)); + edgeSet.insert(make_shared>(edge3)); + edgeSet.insert(make_shared>(edge4)); + edgeSet.insert(make_shared>(edge5)); + edgeSet.insert(make_shared>(edge6)); + edgeSet.insert(make_shared>(edge7)); + edgeSet.insert(make_shared>(edge8)); + edgeSet.insert(make_shared>(edge9)); + edgeSet.insert(make_shared>(edge10)); + edgeSet.insert(make_shared>(edge11)); + edgeSet.insert(make_shared>(edge12)); + edgeSet.insert(make_shared>(edge13)); + edgeSet.insert(make_shared>(edge14)); + + CXXGraph::Graph graph(edgeSet); + CXXGraph::FWResult res = graph.floydWarshall(); + + ASSERT_TRUE(res.success); + ASSERT_FALSE(res.negativeCycle); + ASSERT_EQ(res.errorMessage, ""); +} + +TEST(FloydWarshallTest, test_2) { + CXXGraph::Node node0("0", 0); + CXXGraph::Node node1("1", 1); + + CXXGraph::UndirectedWeightedEdge edge1(1, node0, node1, 1); + + CXXGraph::T_EdgeSet edgeSet; + edgeSet.insert(make_shared>(edge1)); + + CXXGraph::Graph graph(edgeSet); + CXXGraph::FWResult res = graph.floydWarshall(); + + auto distance_0_1 = res.result.find(std::make_pair("0", "1")); + auto distance_1_0 = res.result.find(std::make_pair("1", "0")); + + ASSERT_TRUE(res.success); + ASSERT_FALSE(res.negativeCycle); + ASSERT_EQ(res.errorMessage, ""); + ASSERT_EQ(distance_0_1->second, distance_1_0->second); +} \ No newline at end of file