diff --git a/include/Edge/Edge.hpp b/include/Edge/Edge.hpp old mode 100755 new mode 100644 index 73a073d0d..d2be9594c --- a/include/Edge/Edge.hpp +++ b/include/Edge/Edge.hpp @@ -46,6 +46,7 @@ class Edge { virtual ~Edge() = default; const unsigned long long &getId() const; const std::pair *, const Node *> &getNodePair() const; + const Node *getOtherNode(const Node *node) const; virtual const std::optional isDirected() const; virtual const std::optional isWeighted() const; // operator @@ -83,6 +84,15 @@ const std::pair *, const Node *> &Edge::getNodePair() return nodePair; } +template +const Node *Edge::getOtherNode(const Node *node) const { + if (this->getNodePair().first == node) { + return this->getNodePair().second; + } else { + return this->getNodePair().first; + } +} + template const std::optional Edge::isDirected() const { return std::nullopt; @@ -112,4 +122,4 @@ std::ostream &operator<<(std::ostream &os, const Edge &edge) { } } // namespace CXXGraph -#endif // __CXXGRAPH_EDGE_H__ \ No newline at end of file +#endif // __CXXGRAPH_EDGE_H__ diff --git a/include/Edge/UndirectedEdge.hpp b/include/Edge/UndirectedEdge.hpp index 5b2026fa5..e67124e5c 100755 --- a/include/Edge/UndirectedEdge.hpp +++ b/include/Edge/UndirectedEdge.hpp @@ -99,4 +99,4 @@ std::ostream &operator<<(std::ostream &os, const UndirectedEdge &edge) { } } // namespace CXXGraph -#endif // __CXXGRAPH_UNDIRECTEDEDGE_H__ \ No newline at end of file +#endif // __CXXGRAPH_UNDIRECTEDEDGE_H__ diff --git a/include/Graph/Graph.hpp b/include/Graph/Graph.hpp index 61899aa03..d304d77e0 100644 --- a/include/Graph/Graph.hpp +++ b/include/Graph/Graph.hpp @@ -1150,18 +1150,32 @@ template std::shared_ptr>> Graph::eulerianPath() const { const auto nodeSet = Graph::getNodeSet(); const auto adj = Graph::getAdjMatrix(); + std::shared_ptr>> eulerPath = std::make_shared>>(); + + bool undirected = this->isUndirectedGraph(); + std::vector *> currentPath; - auto currentNode = *(nodeSet.begin()); + // The starting node is the only node which has more outgoing than ingoing + // links + auto firstNodeIt = + std::max_element(nodeSet.begin(), nodeSet.end(), [adj](auto n1, auto n2) { + return adj->at(n1).size() < adj->at(n2).size(); + }); + auto currentNode = *(firstNodeIt); currentPath.push_back(currentNode); + while (currentPath.size() > 0) { auto &edges = adj->at(currentNode); // we keep removing the edges that // have been traversed from the adjacency list if (edges.size()) { auto firstEdge = edges.back().second; - auto nextNodeId = firstEdge->getNodePair().second; + + const Node *nextNodeId; + nextNodeId = firstEdge->getOtherNode(currentNode); + currentPath.push_back(nextNodeId); currentNode = nextNodeId; edges.pop_back(); diff --git a/test/EulerPathTest.cpp b/test/EulerPathTest.cpp index 49b2c0760..92f213b1f 100644 --- a/test/EulerPathTest.cpp +++ b/test/EulerPathTest.cpp @@ -104,4 +104,41 @@ TEST(EulerPathTest, test_3) { ASSERT_FALSE(check); } -} \ No newline at end of file +} + +TEST(EulerPathTest, test_4) { + CXXGraph::Node node_a("a", 0); + CXXGraph::Node node_b("b", 1); + CXXGraph::Node node_c("c", 2); + CXXGraph::Node node_d("d", 3); + CXXGraph::Node node_e("e", 4); + CXXGraph::Node node_f("f", 5); + + CXXGraph::UndirectedEdge edge1(1, node_a, node_b); + CXXGraph::UndirectedEdge edge2(2, node_b, node_e); + CXXGraph::UndirectedEdge edge3(3, node_e, node_f); + CXXGraph::UndirectedEdge edge4(4, node_f, node_a); + CXXGraph::UndirectedEdge edge5(5, node_b, node_c); + CXXGraph::UndirectedEdge edge6(6, node_b, node_d); + CXXGraph::UndirectedEdge edge7(7, node_c, node_d); + + CXXGraph::T_EdgeSet edgeSet; + edgeSet.insert(&edge1); + edgeSet.insert(&edge2); + edgeSet.insert(&edge3); + edgeSet.insert(&edge4); + edgeSet.insert(&edge5); + edgeSet.insert(&edge6); + edgeSet.insert(&edge7); + + CXXGraph::Graph graph(edgeSet); + auto res = graph.eulerianPath(); + auto nodeSet = graph.getNodeSet(); + for (const auto& node : nodeSet) { + auto check = std::find_if(res->begin(), res->end(), [node](auto it) { + return (node->getUserId() == it.getUserId()); + }) == res->end(); + + ASSERT_FALSE(check); + } +}