From 153be115ee95c635020e3f55f29944c080b590b5 Mon Sep 17 00:00:00 2001 From: "erikdervishi.edu" Date: Mon, 18 Dec 2023 22:04:37 +0100 Subject: [PATCH 1/4] added a test_8 and test_9 in DFSTest --- test/DFSTest.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/DFSTest.cpp b/test/DFSTest.cpp index 7d2cf10ef..eca134e81 100644 --- a/test/DFSTest.cpp +++ b/test/DFSTest.cpp @@ -164,3 +164,36 @@ TEST(DFSTest, test_7) { ASSERT_TRUE(std::find(res.begin(), res.end(), node3) != res.end()); ASSERT_TRUE(std::find(res.begin(), res.end(), node4) != res.end()); } + +TEST(DFSTest, test_8) { + CXXGraph::Node node1("1", 1); + CXXGraph::Node node2("2", 2); + CXXGraph::Node node3("3", 3); + CXXGraph::Node node4("4", 4); + + CXXGraph::DirectedWeightedEdge edge1(1, node1, node2, 1); + CXXGraph::DirectedWeightedEdge edge2(2, node3, node4, 1); + CXXGraph::T_EdgeSet edgeSet; + edgeSet.insert(make_shared>(edge1)); + edgeSet.insert(make_shared>(edge2)); + CXXGraph::Graph graph(edgeSet); + std::vector> res = graph.depth_first_search(node1); + ASSERT_EQ(res.size(), 2); + ASSERT_TRUE(std::find(res.begin(), res.end(), node1) != res.end()); + ASSERT_TRUE(std::find(res.begin(), res.end(), node2) != res.end()); + 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_9) { + CXXGraph::Node node1("1", 1); + std::pair *, const CXXGraph::Node *> pairNode( + &node1, &node1); + CXXGraph::UndirectedWeightedEdge edge1(1, pairNode, 1); + CXXGraph::T_EdgeSet edgeSet; + edgeSet.insert(make_shared>(edge1)); + CXXGraph::Graph graph(edgeSet); + std::vector> res = graph.depth_first_search(node1); + ASSERT_EQ(res.size(), 1); + ASSERT_TRUE(std::find(res.begin(), res.end(), node1) != res.end()); +} \ No newline at end of file From 4108fc4ab43be334cc08df5e19146967b71ab3c6 Mon Sep 17 00:00:00 2001 From: "erikdervishi.edu" Date: Mon, 18 Dec 2023 22:11:55 +0100 Subject: [PATCH 2/4] added Prim example --- examples/CMakeLists.txt | 1 + examples/PrimExample/CMakeLists.txt | 21 +++++++ examples/PrimExample/prim_example.cpp | 80 +++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 examples/PrimExample/CMakeLists.txt create mode 100644 examples/PrimExample/prim_example.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 7b3cbc33d..98dc107df 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -5,5 +5,6 @@ add_subdirectory(DialExample) add_subdirectory(DijkstraExample) add_subdirectory(NetworkDynamicsExample) add_subdirectory(PartitionExample) +add_subdirectory(PrimExample) endif(EXAMPLES) \ No newline at end of file diff --git a/examples/PrimExample/CMakeLists.txt b/examples/PrimExample/CMakeLists.txt new file mode 100644 index 000000000..6cb405ca2 --- /dev/null +++ b/examples/PrimExample/CMakeLists.txt @@ -0,0 +1,21 @@ +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..400cd57ac --- /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; +} \ No newline at end of file From 1f1b596315704c1a20f65ccac44aaf7be81ab338 Mon Sep 17 00:00:00 2001 From: "erikdervishi.edu" Date: Mon, 18 Dec 2023 22:19:19 +0100 Subject: [PATCH 3/4] added Floyd Warshall example --- examples/CMakeLists.txt | 1 + examples/FloydWarshallExample/CMakeLists.txt | 17 +++++++ .../FloydWarshallExample/floyd_warshall.cpp | 45 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 examples/FloydWarshallExample/CMakeLists.txt create mode 100644 examples/FloydWarshallExample/floyd_warshall.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 98dc107df..2a485af5d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -6,5 +6,6 @@ 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..3ada5c366 --- /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; +} \ No newline at end of file From ebe89bb39d80a421a1fb14449e1ef8e23f069b60 Mon Sep 17 00:00:00 2001 From: "erikdervishi.edu" Date: Mon, 18 Dec 2023 22:36:16 +0100 Subject: [PATCH 4/4] added a floyd warshall test --- test/CMakeLists.txt | 1 + test/FloydWarshallTest.cpp | 91 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 test/FloydWarshallTest.cpp 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/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