From 058ae9d006b104f86f0fabbe2b0fdccf332f5113 Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Mon, 11 Nov 2024 00:28:44 +0530 Subject: [PATCH 1/6] feature: ham cycle initial draft Initial code commit for Hamiltonian Cycle finding --- .../0003_Graph/0005_HamiltonianPathAndCycle.h | 28 +++++++++++++++++++ .../0005_HamiltonianPathAndCycle.cc | 0 SourceCodes/0003_Graph/CMakeLists.txt | 1 + .../0005_HamiltonianPathAndCycleTest.cc | 0 Tests/0003_Graph/CMakeLists.txt | 1 + 5 files changed, 30 insertions(+) create mode 100644 Headers/0003_Graph/0005_HamiltonianPathAndCycle.h create mode 100644 SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc create mode 100644 Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc diff --git a/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h b/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h new file mode 100644 index 0000000..023a5dd --- /dev/null +++ b/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +using namespace std; + +class HamiltonianNode +{ +public: + int data; + bool isVisited; + HamiltonianNode(int value); +}; + +class HamiltonianGraph +{ +private: + bool isHamiltonianCyclePresent; + bool isHamiltonianPathPresent; + map> _adjlist; + map _nodeMap; + HamiltonianNode* MakeOrFindNode(int value); + +public: + void PushUndirectedEdge(int valueU, int valueV); + void PushSingleNode(int valueU); +}; \ No newline at end of file diff --git a/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc b/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc new file mode 100644 index 0000000..e69de29 diff --git a/SourceCodes/0003_Graph/CMakeLists.txt b/SourceCodes/0003_Graph/CMakeLists.txt index 9df817b..39f75fb 100644 --- a/SourceCodes/0003_Graph/CMakeLists.txt +++ b/SourceCodes/0003_Graph/CMakeLists.txt @@ -4,6 +4,7 @@ set(0003GRAPH_SOURCES 0002_DepthFirstSearch.cc 0003_TopologicalSort.cc 0004_StronglyConnectedComponents.cc + 0005_HamiltonianPathAndCycle.cc ) # Create a library target diff --git a/Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc b/Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc new file mode 100644 index 0000000..e69de29 diff --git a/Tests/0003_Graph/CMakeLists.txt b/Tests/0003_Graph/CMakeLists.txt index b43d3d3..e58a3c7 100644 --- a/Tests/0003_Graph/CMakeLists.txt +++ b/Tests/0003_Graph/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable( 0002_DepthFirstSearchTest.cc 0003_TopologicalSortTest.cc 0004_StronglyConnectedComponentsTest.cc + 0005_HamiltonianPathAndCycleTest.cc ) target_link_libraries( From d9a526eea2e9895e707fd539dc4f470a0008bfca Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Tue, 26 Nov 2024 23:28:00 +0530 Subject: [PATCH 2/6] feature: ham cycle logic added --- .../0003_Graph/0005_HamiltonianPathAndCycle.h | 9 +- .../0005_HamiltonianPathAndCycle.cc | 93 +++++++++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h b/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h index 023a5dd..fb79577 100644 --- a/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h +++ b/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include using namespace std; @@ -18,11 +18,16 @@ class HamiltonianGraph private: bool isHamiltonianCyclePresent; bool isHamiltonianPathPresent; - map> _adjlist; + int visitedNodeCount; + map> _adjlist; map _nodeMap; + vector _hamiltonianPath; HamiltonianNode* MakeOrFindNode(int value); + bool IsSafe(HamiltonianNode* nodeU, HamiltonianNode* nodeV); + bool HamiltonianCycleAndPathUtil(HamiltonianNode* node); public: void PushUndirectedEdge(int valueU, int valueV); void PushSingleNode(int valueU); + void FindHamiltonianCycleAndPath(); }; \ No newline at end of file diff --git a/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc b/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc index e69de29..7824cae 100644 --- a/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc +++ b/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc @@ -0,0 +1,93 @@ +#include "../Headers/0003_Graph/0005_HamiltonianPathAndCycle.h" + +using namespace std; + +HamiltonianNode::HamiltonianNode(int value) +{ + this->data = value; + this->isVisited = false; +} + +// HamiltonianGraph Private Member Methods +HamiltonianNode* HamiltonianGraph::MakeOrFindNode(int value) +{ + HamiltonianNode* node = nullptr; + if (this->_nodeMap.find(value) == this->_nodeMap.end()) + { + node = new HamiltonianNode(value); + this->_nodeMap[value] = node; + } + else + { + node = this->_nodeMap[value]; + } + return node; +} + +bool HamiltonianGraph::IsSafe(HamiltonianNode* nodeU, HamiltonianNode* nodeV) +{ + if (this->_adjlist[nodeU].find(nodeV) == this->_adjlist[nodeU].end()) + { + return false; + } + if (nodeV->isVisited == true) + { + return false; + } + return true; +} + +bool HamiltonianGraph::HamiltonianCycleAndPathUtil(HamiltonianNode* nodeU) +{ + if (this->visitedNodeCount == this->_nodeMap.size()-1) + { + if (this->_adjlist[nodeU].find(this->_hamiltonianPath[0]) != this->_adjlist[nodeU].end()) + { + this->isHamiltonianCyclePresent = true; + return true; + } + this->isHamiltonianPathPresent = true; + return false; + } + for (auto& iterator : this->_nodeMap) + { + if (this->IsSafe(nodeU, iterator.second)) + { + this->_hamiltonianPath.push_back(iterator.second); + iterator.second->isVisited = true; + this->visitedNodeCount++; + if (this->HamiltonianCycleAndPathUtil(iterator.second)) + { + return true; + } + this->_hamiltonianPath.pop_back(); + iterator.second->isVisited = false; + this->visitedNodeCount--; + } + } + return false; +} + +// HamiltonianGraph Public Member Methods +void HamiltonianGraph::PushUndirectedEdge(int valueU, int valueV) +{ + HamiltonianNode* nodeU = this->MakeOrFindNode(valueU); + HamiltonianNode* nodeV = this->MakeOrFindNode(valueV); + + this->_adjlist[nodeU].insert(nodeV); + this->_adjlist[nodeV].insert(nodeU); +} + +void HamiltonianGraph::PushSingleNode(int valueU) +{ + HamiltonianNode* nodeU = this->MakeOrFindNode(valueU); +} + +void HamiltonianGraph::FindHamiltonianCycleAndPath() +{ + HamiltonianNode* node = this->_nodeMap[0]; + this->_hamiltonianPath.push_back(node); + node->isVisited = true; + this->visitedNodeCount = 1; + this->HamiltonianCycleAndPathUtil(node); +} \ No newline at end of file From 33c90a7ca936d75f5146450541f4edadc081c129 Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Wed, 27 Nov 2024 00:15:18 +0530 Subject: [PATCH 3/6] feature: hamcycle - return output added --- .../0003_Graph/0005_HamiltonianPathAndCycle.h | 4 +++ .../0005_HamiltonianPathAndCycle.cc | 31 +++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h b/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h index fb79577..24ca589 100644 --- a/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h +++ b/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h @@ -30,4 +30,8 @@ class HamiltonianGraph void PushUndirectedEdge(int valueU, int valueV); void PushSingleNode(int valueU); void FindHamiltonianCycleAndPath(); + bool IsHamiltonianCyclePresent(); + bool IsHamiltonianPathPresent(); + vector GetHamiltonianCycle(); + vector GetHamiltonianPath(); }; \ No newline at end of file diff --git a/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc b/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc index 7824cae..3326ead 100644 --- a/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc +++ b/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc @@ -60,9 +60,9 @@ bool HamiltonianGraph::HamiltonianCycleAndPathUtil(HamiltonianNode* nodeU) { return true; } - this->_hamiltonianPath.pop_back(); - iterator.second->isVisited = false; this->visitedNodeCount--; + iterator.second->isVisited = false; + this->_hamiltonianPath.pop_back(); } } return false; @@ -85,9 +85,36 @@ void HamiltonianGraph::PushSingleNode(int valueU) void HamiltonianGraph::FindHamiltonianCycleAndPath() { + this->isHamiltonianCyclePresent = false; + this->isHamiltonianPathPresent = false; + this->_hamiltonianPath = {}; HamiltonianNode* node = this->_nodeMap[0]; this->_hamiltonianPath.push_back(node); node->isVisited = true; this->visitedNodeCount = 1; this->HamiltonianCycleAndPathUtil(node); +} + +bool HamiltonianGraph::IsHamiltonianCyclePresent() +{ + return this->isHamiltonianCyclePresent; +} + +bool HamiltonianGraph::IsHamiltonianPathPresent() +{ + return this->isHamiltonianPathPresent; +} + +vector HamiltonianGraph::GetHamiltonianCycle() +{ + if (this->isHamiltonianCyclePresent) + { + this->_hamiltonianPath.push_back(this->_nodeMap[0]); + } + return this->_hamiltonianPath; +} + +vector HamiltonianGraph::GetHamiltonianPath() +{ + return this->_hamiltonianPath; } \ No newline at end of file From df4def9ceb074c1ad25f1eef9b912099ca597360 Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Thu, 28 Nov 2024 02:57:18 +0530 Subject: [PATCH 4/6] core-test-feature: ham cycle, unitest helper --- .../0003_Graph/0005_HamiltonianPathAndCycle.h | 12 ++--- .../0005_HamiltonianPathAndCycle.cc | 54 ++++++++----------- Tests/0000_CommonUtilities/UnitTestHelper.h | 23 ++++++-- Tests/0002_Tree/0001_BinarySearchTreeTest.cc | 12 ++--- .../0003_Graph/0001_BreadthFirstSearchTest.cc | 4 +- Tests/0003_Graph/0002_DepthFirstSearchTest.cc | 18 +++---- Tests/0003_Graph/0003_TopologicalSortTest.cc | 10 ++-- .../0005_HamiltonianPathAndCycleTest.cc | 33 ++++++++++++ 8 files changed, 103 insertions(+), 63 deletions(-) diff --git a/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h b/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h index 24ca589..b6f2f50 100644 --- a/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h +++ b/Headers/0003_Graph/0005_HamiltonianPathAndCycle.h @@ -16,12 +16,13 @@ class HamiltonianNode class HamiltonianGraph { private: - bool isHamiltonianCyclePresent; - bool isHamiltonianPathPresent; - int visitedNodeCount; + bool _isHamiltonianCyclePresent; + bool _isHamiltonianPathPresent; + int _visitedNodeCount; + HamiltonianNode* _startingNode; map> _adjlist; map _nodeMap; - vector _hamiltonianPath; + vector _hamiltonianPath; HamiltonianNode* MakeOrFindNode(int value); bool IsSafe(HamiltonianNode* nodeU, HamiltonianNode* nodeV); bool HamiltonianCycleAndPathUtil(HamiltonianNode* node); @@ -32,6 +33,5 @@ class HamiltonianGraph void FindHamiltonianCycleAndPath(); bool IsHamiltonianCyclePresent(); bool IsHamiltonianPathPresent(); - vector GetHamiltonianCycle(); - vector GetHamiltonianPath(); + vector GetHamiltonianPath(); }; \ No newline at end of file diff --git a/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc b/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc index 3326ead..80c3309 100644 --- a/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc +++ b/SourceCodes/0003_Graph/0005_HamiltonianPathAndCycle.cc @@ -39,29 +39,30 @@ bool HamiltonianGraph::IsSafe(HamiltonianNode* nodeU, HamiltonianNode* nodeV) bool HamiltonianGraph::HamiltonianCycleAndPathUtil(HamiltonianNode* nodeU) { - if (this->visitedNodeCount == this->_nodeMap.size()-1) + if (this->_visitedNodeCount == this->_nodeMap.size()) { - if (this->_adjlist[nodeU].find(this->_hamiltonianPath[0]) != this->_adjlist[nodeU].end()) + if (this->_adjlist[nodeU].find(this->_startingNode) != this->_adjlist[nodeU].end()) { - this->isHamiltonianCyclePresent = true; + this->_isHamiltonianCyclePresent = true; + this->_isHamiltonianPathPresent = true; return true; } - this->isHamiltonianPathPresent = true; + this->_isHamiltonianPathPresent = true; return false; } - for (auto& iterator : this->_nodeMap) + for (auto& nodeV : this->_adjlist[nodeU]) { - if (this->IsSafe(nodeU, iterator.second)) + if (this->IsSafe(nodeU, nodeV)) { - this->_hamiltonianPath.push_back(iterator.second); - iterator.second->isVisited = true; - this->visitedNodeCount++; - if (this->HamiltonianCycleAndPathUtil(iterator.second)) + this->_hamiltonianPath.push_back(nodeV->data); + nodeV->isVisited = true; + this->_visitedNodeCount++; + if (this->HamiltonianCycleAndPathUtil(nodeV)) { return true; } - this->visitedNodeCount--; - iterator.second->isVisited = false; + this->_visitedNodeCount--; + nodeV->isVisited = false; this->_hamiltonianPath.pop_back(); } } @@ -85,36 +86,27 @@ void HamiltonianGraph::PushSingleNode(int valueU) void HamiltonianGraph::FindHamiltonianCycleAndPath() { - this->isHamiltonianCyclePresent = false; - this->isHamiltonianPathPresent = false; + this->_isHamiltonianCyclePresent = false; + this->_isHamiltonianPathPresent = false; this->_hamiltonianPath = {}; - HamiltonianNode* node = this->_nodeMap[0]; - this->_hamiltonianPath.push_back(node); - node->isVisited = true; - this->visitedNodeCount = 1; - this->HamiltonianCycleAndPathUtil(node); + this->_startingNode = this->_nodeMap[0]; + this->_hamiltonianPath.push_back(this->_startingNode->data); + this->_startingNode->isVisited = true; + this->_visitedNodeCount = 1; + this->HamiltonianCycleAndPathUtil(this->_startingNode); } bool HamiltonianGraph::IsHamiltonianCyclePresent() { - return this->isHamiltonianCyclePresent; + return this->_isHamiltonianCyclePresent; } bool HamiltonianGraph::IsHamiltonianPathPresent() { - return this->isHamiltonianPathPresent; + return this->_isHamiltonianPathPresent; } -vector HamiltonianGraph::GetHamiltonianCycle() -{ - if (this->isHamiltonianCyclePresent) - { - this->_hamiltonianPath.push_back(this->_nodeMap[0]); - } - return this->_hamiltonianPath; -} - -vector HamiltonianGraph::GetHamiltonianPath() +vector HamiltonianGraph::GetHamiltonianPath() { return this->_hamiltonianPath; } \ No newline at end of file diff --git a/Tests/0000_CommonUtilities/UnitTestHelper.h b/Tests/0000_CommonUtilities/UnitTestHelper.h index 8e32a97..b745248 100644 --- a/Tests/0000_CommonUtilities/UnitTestHelper.h +++ b/Tests/0000_CommonUtilities/UnitTestHelper.h @@ -10,7 +10,7 @@ class UnitTestHelper { public: template - string VerifyVectorResult(vector vector) + string SerializeVectorToString(vector vector) { string result = ""; for (auto& iterator : vector) @@ -22,7 +22,7 @@ class UnitTestHelper } template - string VerifyVectorResult(vector> vector) + string SerializeVectorToString(vector> vector) { string result = ""; for (auto& iterator : vector) @@ -38,7 +38,7 @@ class UnitTestHelper } template - string VerifyVectorResult(vector>> vector) + string SerializeVectorToString(vector>> vector) { string result = ""; for (auto& iterator : vector) @@ -54,7 +54,7 @@ class UnitTestHelper } template - string VerifyVectorResult(vector> vector) + string SerializeVectorToString(vector> vector) { string result = ""; for (auto& iterator : vector) @@ -107,4 +107,19 @@ class UnitTestHelper return data; } + + template + vector NormalizeCycle(vector data) + { + if (data.empty()) + { + return {}; + } + auto minimumElementIterator = min_element(data.begin(), data.end()); + long long startIndex = distance(data.begin(), minimumElementIterator); + vector normalizedCycle; + normalizedCycle.insert(normalizedCycle.begin(), data.begin() + startIndex, data.end()); + normalizedCycle.insert(normalizedCycle.end(), data.begin(), data.begin() + startIndex); + return normalizedCycle; + } }; \ No newline at end of file diff --git a/Tests/0002_Tree/0001_BinarySearchTreeTest.cc b/Tests/0002_Tree/0001_BinarySearchTreeTest.cc index 65a5090..58bd385 100644 --- a/Tests/0002_Tree/0001_BinarySearchTreeTest.cc +++ b/Tests/0002_Tree/0001_BinarySearchTreeTest.cc @@ -15,7 +15,7 @@ namespace BinarySearchTreeTest bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetRecursiveInorderTravesalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetRecursiveInorderTravesalResult()); string expectedResult = "30 50 60"; EXPECT_EQ(actualResult, expectedResult); @@ -28,7 +28,7 @@ namespace BinarySearchTreeTest bst.InsertNode(30); bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetRecursivePreorderTravesalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetRecursivePreorderTravesalResult()); string expectedResult = "50 30 60"; EXPECT_EQ(actualResult, expectedResult); @@ -41,7 +41,7 @@ namespace BinarySearchTreeTest bst.InsertNode(30); bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetRecursivePostorderTravesalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetRecursivePostorderTravesalResult()); string expectedResult = "30 60 50"; EXPECT_EQ(actualResult, expectedResult); @@ -55,7 +55,7 @@ namespace BinarySearchTreeTest bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetMorrisInorderTraversalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetMorrisInorderTraversalResult()); string expectedResult = "30 50 60"; EXPECT_EQ(actualResult, expectedResult); @@ -69,7 +69,7 @@ namespace BinarySearchTreeTest bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetMorrisPreorderTraversalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetMorrisPreorderTraversalResult()); string expectedResult = "50 30 60"; EXPECT_EQ(actualResult, expectedResult); @@ -83,7 +83,7 @@ namespace BinarySearchTreeTest bst.InsertNode(60); - string actualResult = unitTestHelper.VerifyVectorResult(bst.GetMorrisPostorderTraversalResult()); + string actualResult = unitTestHelper.SerializeVectorToString(bst.GetMorrisPostorderTraversalResult()); string expectedResult = "30 60 50"; EXPECT_EQ(actualResult, expectedResult); diff --git a/Tests/0003_Graph/0001_BreadthFirstSearchTest.cc b/Tests/0003_Graph/0001_BreadthFirstSearchTest.cc index e24870f..bcc0650 100644 --- a/Tests/0003_Graph/0001_BreadthFirstSearchTest.cc +++ b/Tests/0003_Graph/0001_BreadthFirstSearchTest.cc @@ -25,7 +25,7 @@ namespace BreadthFirstSearchTest graph.BFS(1); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowBFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowBFSResult()); string expectedResult = "1(0) 2(1) 3(1) 4(2) 5(2) 6(2) 7(3) 8(3)"; EXPECT_EQ(actualResult, expectedResult); } @@ -38,7 +38,7 @@ namespace BreadthFirstSearchTest graph.BFS(1); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowBFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowBFSResult()); string expectedResult = "1(0) 2(1)"; EXPECT_EQ(actualResult, expectedResult); } diff --git a/Tests/0003_Graph/0002_DepthFirstSearchTest.cc b/Tests/0003_Graph/0002_DepthFirstSearchTest.cc index 3fd7841..c5bba61 100644 --- a/Tests/0003_Graph/0002_DepthFirstSearchTest.cc +++ b/Tests/0003_Graph/0002_DepthFirstSearchTest.cc @@ -21,7 +21,7 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); string expectedResult = "1(1,8) 2(2,7) 3(9,12) 4(4,5) 5(3,6) 6(10,11)"; EXPECT_EQ(actualResult, expectedResult); } @@ -35,7 +35,7 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); string expectedResult = "1(1,2)"; EXPECT_EQ(actualResult, expectedResult); } @@ -49,7 +49,7 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); string expectedResult = "1(1,4) 2(2,3) 3(5,8) 4(6,7)"; EXPECT_EQ(actualResult, expectedResult); } @@ -64,7 +64,7 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); string expectedResult = "1(1,6) 2(2,5) 3(3,4)"; EXPECT_EQ(actualResult, expectedResult); } @@ -92,7 +92,7 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); string expectedResult = "1(1,32) 2(2,29) 3(30,31) 4(3,28) 5(4,27) 6(5,26) 7(6,25) 8(7,24) 9(8,23) 10(9,22) 11(10,21) 12(11,20) 13(12,19) 14(13,18) 15(14,17) 16(15,16)"; EXPECT_EQ(actualResult, expectedResult); } @@ -108,7 +108,7 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); string expectedResult = "1(1,2) 2(3,4) 3(5,6)"; EXPECT_EQ(actualResult, expectedResult); } @@ -125,7 +125,7 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); string expectedResult = "1(1,8) 2(2,7) 3(3,4) 4(5,6)"; EXPECT_EQ(actualResult, expectedResult); } @@ -150,7 +150,7 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); string expectedResult = "1(1,8) 2(2,7) 3(3,6) 4(4,5)"; EXPECT_EQ(actualResult, expectedResult); } @@ -169,7 +169,7 @@ namespace DepthFirstSearchTest graph.DFS(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowDFSResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowDFSResult()); string expectedResult = "1(1,6) 2(2,5) 3(3,4)"; EXPECT_EQ(actualResult, expectedResult); } diff --git a/Tests/0003_Graph/0003_TopologicalSortTest.cc b/Tests/0003_Graph/0003_TopologicalSortTest.cc index 4eea735..b717108 100644 --- a/Tests/0003_Graph/0003_TopologicalSortTest.cc +++ b/Tests/0003_Graph/0003_TopologicalSortTest.cc @@ -23,7 +23,7 @@ namespace TopologicalSortTest graph.TopologicalSort(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowTopologicalSortResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); string expectedResult = "9(17,18) 6(11,16) 7(12,15) 8(13,14) 5(9,10) 1(1,8) 4(6,7) 2(2,5) 3(3,4)"; EXPECT_EQ(actualResult, expectedResult); @@ -42,7 +42,7 @@ namespace TopologicalSortTest graph.PushDirectedEdge(6, 7); graph.TopologicalSort(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowTopologicalSortResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); string expectedResult = "1(1,14) 3(12,13) 2(2,11) 4(3,10) 5(4,9) 6(5,8) 7(6,7)"; EXPECT_EQ(actualResult, expectedResult); @@ -57,7 +57,7 @@ namespace TopologicalSortTest graph.PushDirectedEdge(5, 6); graph.TopologicalSort(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowTopologicalSortResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); string expectedResult = "5(9,12) 6(10,11) 3(5,8) 4(6,7) 1(1,4) 2(2,3)"; EXPECT_EQ(actualResult, expectedResult); @@ -72,7 +72,7 @@ namespace TopologicalSortTest graph.PushDirectedEdge(3, 4); graph.TopologicalSort(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowTopologicalSortResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); string expectedResult = "2(7,8) 1(1,6) 3(2,5) 4(3,4)"; EXPECT_EQ(actualResult, expectedResult); @@ -85,7 +85,7 @@ namespace TopologicalSortTest graph.PushSingleNode(1); graph.TopologicalSort(); - string actualResult = unitTestHelper.VerifyVectorResult(graph.ShowTopologicalSortResult()); + string actualResult = unitTestHelper.SerializeVectorToString(graph.ShowTopologicalSortResult()); string expectedResult = "1(1,2)"; EXPECT_EQ(actualResult, expectedResult); diff --git a/Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc b/Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc index e69de29..b830884 100644 --- a/Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc +++ b/Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc @@ -0,0 +1,33 @@ +#include +#include "../Headers/0003_Graph/0005_HamiltonianPathAndCycle.h" +#include "../0000_CommonUtilities/UnitTestHelper.h" + +namespace HamiltonianPathAndCycleTest +{ + UnitTestHelper unitTestHelper; + + TEST(HamiltonianCycleAndPathTest, ShowResult) + { + HamiltonianGraph graph; + + graph.PushUndirectedEdge(0, 1); + graph.PushUndirectedEdge(0, 3); + graph.PushUndirectedEdge(1, 2); + graph.PushUndirectedEdge(1, 3); + graph.PushUndirectedEdge(1, 4); + graph.PushUndirectedEdge(2, 4); + graph.PushUndirectedEdge(3, 4); + + graph.FindHamiltonianCycleAndPath(); + + bool isHamiltonianCyclePresent = graph.IsHamiltonianCyclePresent(); + bool isHamiltonianPathPresent = graph.IsHamiltonianPathPresent(); + + vector hamiltonianPathActualResult = graph.GetHamiltonianPath(); + vector hamiltonianPathExpectedResult = { 2, 4, 3, 0, 1 }; + + ASSERT_TRUE(isHamiltonianCyclePresent); + ASSERT_TRUE(isHamiltonianPathPresent); + EXPECT_EQ(unitTestHelper.NormalizeCycle(hamiltonianPathActualResult), unitTestHelper.NormalizeCycle(hamiltonianPathExpectedResult)); + } +} \ No newline at end of file From 933558829ee9ab7c0be077840b56246c6d35d575 Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Thu, 28 Nov 2024 03:09:15 +0530 Subject: [PATCH 5/6] fix: small fix in unit test helper --- Tests/0000_CommonUtilities/UnitTestHelper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/0000_CommonUtilities/UnitTestHelper.h b/Tests/0000_CommonUtilities/UnitTestHelper.h index b745248..23370e8 100644 --- a/Tests/0000_CommonUtilities/UnitTestHelper.h +++ b/Tests/0000_CommonUtilities/UnitTestHelper.h @@ -118,7 +118,7 @@ class UnitTestHelper auto minimumElementIterator = min_element(data.begin(), data.end()); long long startIndex = distance(data.begin(), minimumElementIterator); vector normalizedCycle; - normalizedCycle.insert(normalizedCycle.begin(), data.begin() + startIndex, data.end()); + normalizedCycle.insert(normalizedCycle.end(), data.begin() + startIndex, data.end()); normalizedCycle.insert(normalizedCycle.end(), data.begin(), data.begin() + startIndex); return normalizedCycle; } From 5f95bc223c524a3ce83d68281605e9ff0fe45f43 Mon Sep 17 00:00:00 2001 From: Debashis Nandi Date: Thu, 28 Nov 2024 22:00:38 +0530 Subject: [PATCH 6/6] fix: cycle check in test util --- Tests/0000_CommonUtilities/UnitTestHelper.h | 32 +++++++++++++------ .../0005_HamiltonianPathAndCycleTest.cc | 4 +-- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/Tests/0000_CommonUtilities/UnitTestHelper.h b/Tests/0000_CommonUtilities/UnitTestHelper.h index 23370e8..6faf4e5 100644 --- a/Tests/0000_CommonUtilities/UnitTestHelper.h +++ b/Tests/0000_CommonUtilities/UnitTestHelper.h @@ -109,17 +109,31 @@ class UnitTestHelper } template - vector NormalizeCycle(vector data) + bool NormalizeCyclesAnCompare(vector data1, vector data2) { - if (data.empty()) + if (data1.size() != data2.size()) { - return {}; + return false; } - auto minimumElementIterator = min_element(data.begin(), data.end()); - long long startIndex = distance(data.begin(), minimumElementIterator); - vector normalizedCycle; - normalizedCycle.insert(normalizedCycle.end(), data.begin() + startIndex, data.end()); - normalizedCycle.insert(normalizedCycle.end(), data.begin(), data.begin() + startIndex); - return normalizedCycle; + + // Normalized rotation of cycle 1 + vector normalizedCycle1(data1); + auto minIterator1 = min_element(normalizedCycle1.begin(), normalizedCycle1.end()); + rotate(normalizedCycle1.begin(), minIterator1, normalizedCycle1.end()); + + // Normalized rotation of cycle 2 + vector normalizedCycle2(data2); + auto minIterator2 = min_element(normalizedCycle2.begin(), normalizedCycle2.end()); + rotate(normalizedCycle2.begin(), minIterator2, normalizedCycle2.end()); + + // Check clock wise + if (normalizedCycle1 == normalizedCycle2) + { + return true; + } + + // Check counter clock wise + reverse(normalizedCycle2.begin() + 1, normalizedCycle2.end()); + return (normalizedCycle1 == normalizedCycle2); } }; \ No newline at end of file diff --git a/Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc b/Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc index b830884..3dda0b4 100644 --- a/Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc +++ b/Tests/0003_Graph/0005_HamiltonianPathAndCycleTest.cc @@ -24,10 +24,10 @@ namespace HamiltonianPathAndCycleTest bool isHamiltonianPathPresent = graph.IsHamiltonianPathPresent(); vector hamiltonianPathActualResult = graph.GetHamiltonianPath(); - vector hamiltonianPathExpectedResult = { 2, 4, 3, 0, 1 }; + vector hamiltonianPathExpectedResult = { 4, 3, 0, 1, 2 }; ASSERT_TRUE(isHamiltonianCyclePresent); ASSERT_TRUE(isHamiltonianPathPresent); - EXPECT_EQ(unitTestHelper.NormalizeCycle(hamiltonianPathActualResult), unitTestHelper.NormalizeCycle(hamiltonianPathExpectedResult)); + ASSERT_TRUE(unitTestHelper.NormalizeCyclesAnCompare(hamiltonianPathActualResult, hamiltonianPathExpectedResult)); } } \ No newline at end of file