-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create isBipartiteGraph.hpp #465
base: master
Are you sure you want to change the base?
Changes from all commits
4ffaba1
0e5c5d1
fd37784
1922ba2
db00eef
204975e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/***********************************************************/ | ||
/*** ______ ____ ______ _ ***/ | ||
/*** / ___\ \/ /\ \/ / ___|_ __ __ _ _ __ | |__ ***/ | ||
/*** | | \ / \ / | _| '__/ _` | '_ \| '_ \ ***/ | ||
/*** | |___ / \ / \ |_| | | | (_| | |_) | | | | ***/ | ||
/*** \____/_/\_\/_/\_\____|_| \__,_| .__/|_| |_| ***/ | ||
/*** |_| ***/ | ||
/***********************************************************/ | ||
/*** Header-Only C++ Library for Graph ***/ | ||
/*** Representation and Algorithms ***/ | ||
/***********************************************************/ | ||
/*** Author: ZigRazor ***/ | ||
/*** E-Mail: [email protected] ***/ | ||
/***********************************************************/ | ||
/*** Collaboration: ----------- ***/ | ||
/***********************************************************/ | ||
/*** License: AGPL v3.0 ***/ | ||
/***********************************************************/ | ||
|
||
#ifndef __CXXGRAPH_CHECK_ODD_NODES_CYCLE_H__ | ||
#define __CXXGRAPH_CHECK_ODD_NODES_CYCLE_H__ | ||
|
||
#pragma once | ||
|
||
#include "CXXGraph/Graph/Graph_decl.h" | ||
|
||
namespace CXXGraph { | ||
|
||
template <typename T> | ||
class Graph { | ||
public: | ||
TopoSortResult<T> checkOddNodesCycleDir() const; | ||
|
||
private: | ||
void checkOddNodesCycleUtil(std::vector<int>& visited, | ||
std::vector<int>& chainNo, int root, | ||
int cycleLength, bool& isBiPartite) const; | ||
}; | ||
Comment on lines
+30
to
+38
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can't re-declare the class here. Declare the methods in the Graph_decl.hpp file, possibly adding method descriptions like you see there, and in this file you only define them |
||
|
||
template <typename T> | ||
TopoSortResult<T> Graph<T>::checkOddNodesCycleDir() const { | ||
TopoSortResult<T> result; | ||
|
||
// Check if the graph is undirected | ||
if (isDirectedGraph()) { | ||
result.errorMessage = ERR_UNDIR_GRAPH; // Error: Graph is directed | ||
return result; | ||
} | ||
|
||
const auto nodeSet = Graph<T>::getNodeSet(); | ||
std::vector<int> visited(nodeSet.size(), 0); | ||
std::vector<int> chainNo(nodeSet.size(), -1); | ||
bool isBiPartite = true; | ||
|
||
for (const auto& node : nodeSet) { | ||
if (!visited[node->getId()]) { | ||
visited[node->getId()] = 1; | ||
checkOddNodesCycleUtil(visited, chainNo, node->getId(), 0, isBiPartite); | ||
if (!isBiPartite) { | ||
result.errorMessage = "The graph contains an odd-length cycle."; | ||
return result; | ||
} | ||
} | ||
} | ||
|
||
result.success = true; | ||
return result; | ||
} | ||
|
||
template <typename T> | ||
void Graph<T>::checkOddNodesCycleUtil(std::vector<int>& visited, | ||
std::vector<int>& chainNo, int root, | ||
int cycleLength, | ||
bool& isBiPartite) const { | ||
chainNo[root] = cycleLength; | ||
for (const auto& child : cachedAdjMatrix->find(root)) { | ||
if (!visited[std::get<0>(child)->getId()]) { | ||
visited[std::get<0>(child)->getId()] = 1; | ||
checkOddNodesCycleUtil(visited, chainNo, std::get<0>(child)->getId(), | ||
cycleLength + 1, isBiPartite); | ||
if (!isBiPartite) return; | ||
} else if (chainNo[root] == chainNo[std::get<0>(child)->getId()]) { | ||
isBiPartite = false; | ||
return; | ||
} | ||
} | ||
} | ||
|
||
} // namespace CXXGraph | ||
|
||
#endif // __CXXGRAPH_CHECK_ODD_NODES_CYCLE_H__ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#include <memory> | ||
|
||
#include "CXXGraph/CXXGraph.hpp" | ||
#include "gtest/gtest.h" | ||
|
||
// Smart pointers alias | ||
template <typename T> | ||
using unique = std::unique_ptr<T>; | ||
template <typename T> | ||
using shared = std::shared_ptr<T>; | ||
|
||
using std::make_shared; | ||
using std::make_unique; | ||
|
||
TEST(IsBipartiteTest, bipartite_graph) { | ||
// Bipartite graph | ||
CXXGraph::Node<int> node1("1", 1); | ||
CXXGraph::Node<int> node2("2", 2); | ||
CXXGraph::Node<int> node3("3", 3); | ||
CXXGraph::Node<int> node4("4", 4); | ||
|
||
CXXGraph::UndirectedEdge<int> edge1(1, node1, node2); | ||
CXXGraph::UndirectedEdge<int> edge2(2, node1, node3); | ||
CXXGraph::UndirectedEdge<int> edge3(3, node3, node4); | ||
CXXGraph::UndirectedEdge<int> edge4(4, node2, node4); | ||
|
||
CXXGraph::T_EdgeSet<int> edgeSet; | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge1)); | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge2)); | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge3)); | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge4)); | ||
|
||
CXXGraph::Graph<int> graph(edgeSet); | ||
|
||
bool isBipartite = graph.isBipartite(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method doesn't exist, you didn't define it. Maybe you'd want to rename the methods in the header file. |
||
ASSERT_EQ(isBipartite, true); // This graph is bipartite | ||
} | ||
|
||
TEST(IsBipartiteTest, non_bipartite_graph) { | ||
// Non-bipartite graph with odd cycle | ||
CXXGraph::Node<int> node1("1", 1); | ||
CXXGraph::Node<int> node2("2", 2); | ||
CXXGraph::Node<int> node3("3", 3); | ||
|
||
CXXGraph::UndirectedEdge<int> edge1(1, node1, node2); | ||
CXXGraph::UndirectedEdge<int> edge2(2, node2, node3); | ||
CXXGraph::UndirectedEdge<int> edge3(3, node3, | ||
node1); // Forms a cycle of 3 nodes | ||
|
||
CXXGraph::T_EdgeSet<int> edgeSet; | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge1)); | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge2)); | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge3)); | ||
|
||
CXXGraph::Graph<int> graph(edgeSet); | ||
|
||
bool isBipartite = graph.isBipartite(); | ||
ASSERT_EQ( | ||
isBipartite, | ||
false); // This graph has an odd-length cycle, so it's not bipartite | ||
} | ||
|
||
TEST(IsBipartiteTest, empty_graph) { | ||
// Empty graph | ||
CXXGraph::T_EdgeSet<int> edgeSet; | ||
CXXGraph::Graph<int> graph(edgeSet); | ||
|
||
bool isBipartite = graph.isBipartite(); | ||
ASSERT_EQ(isBipartite, true); // An empty graph is trivially bipartite | ||
} | ||
|
||
TEST(IsBipartiteTest, single_node_graph) { | ||
// Single node graph (trivially bipartite) | ||
CXXGraph::Node<int> node1("1", 1); | ||
CXXGraph::T_EdgeSet<int> edgeSet; | ||
CXXGraph::Graph<int> graph(edgeSet); | ||
|
||
bool isBipartite = graph.isBipartite(); | ||
ASSERT_EQ(isBipartite, true); // A graph with a single node is bipartite | ||
} | ||
|
||
TEST(IsBipartiteTest, complex_bipartite_graph) { | ||
// More complex bipartite graph | ||
CXXGraph::Node<int> node1("1", 1); | ||
CXXGraph::Node<int> node2("2", 2); | ||
CXXGraph::Node<int> node3("3", 3); | ||
CXXGraph::Node<int> node4("4", 4); | ||
CXXGraph::Node<int> node5("5", 5); | ||
CXXGraph::Node<int> node6("6", 6); | ||
|
||
CXXGraph::UndirectedEdge<int> edge1(1, node1, node2); | ||
CXXGraph::UndirectedEdge<int> edge2(2, node1, node3); | ||
CXXGraph::UndirectedEdge<int> edge3(3, node4, node5); | ||
CXXGraph::UndirectedEdge<int> edge4(4, node4, node6); | ||
CXXGraph::UndirectedEdge<int> edge5(5, node2, node4); | ||
CXXGraph::UndirectedEdge<int> edge6(6, node3, node5); | ||
|
||
CXXGraph::T_EdgeSet<int> edgeSet; | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge1)); | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge2)); | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge3)); | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge4)); | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge5)); | ||
edgeSet.insert(make_shared<CXXGraph::UndirectedEdge<int>>(edge6)); | ||
|
||
CXXGraph::Graph<int> graph(edgeSet); | ||
|
||
bool isBipartite = graph.isBipartite(); | ||
ASSERT_EQ(isBipartite, true); // This graph is bipartite | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests are failing. You need to include this file in
CXXGraph/include/Graph/Graph.h