diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 9d3f7a1e6..a4dd88547 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -20,7 +20,8 @@ if(BENCHMARK) CPMAddPackage( NAME zlib GITHUB_REPOSITORY madler/zlib - VERSION 1.2.13 + #VERSION 1.2.13 + VERSION 1.2.12 OPTIONS "CMAKE_POSITION_INDEPENDENT_CODE True" ) @@ -40,4 +41,4 @@ if(BENCHMARK) PUBLIC benchmark::benchmark PUBLIC zlibstatic ) -endif(BENCHMARK) \ No newline at end of file +endif(BENCHMARK) diff --git a/cmake_and_make.sh b/cmake_and_make.sh new file mode 100644 index 000000000..0f9ca8299 --- /dev/null +++ b/cmake_and_make.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +#if [ -d "build" ]; then +# echo "empty directory build" +# rm -rf build +# mkdir -p build +#fi + +cd build +cmake ../ -DTEST=ON -Dgtest_disable_pthreads=OFF +make diff --git a/include/CXXGraph/Graph/Algorithm/BellmanFord_impl.hpp b/include/CXXGraph/Graph/Algorithm/BellmanFord_impl.hpp index cbb6fd036..61ed94102 100644 --- a/include/CXXGraph/Graph/Algorithm/BellmanFord_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/BellmanFord_impl.hpp @@ -32,7 +32,8 @@ const BellmanFordResult Graph::bellmanford(const Node &source, result.success = false; result.errorMessage = ""; result.result = INF_DOUBLE; - auto nodeSet = Graph::getNodeSet(); + //auto nodeSet = Graph::getNodeSet(); + auto nodeSet = Graph::getNodeVector(); auto source_node_it = std::find_if( nodeSet.begin(), nodeSet.end(), [&source](auto node) { return node->getUserId() == source.getUserId(); }); @@ -66,7 +67,8 @@ const BellmanFordResult Graph::bellmanford(const Node &source, auto earlyStopping = false; // outer loop for vertex relaxation for (int i = 0; i < n - 1; ++i) { - auto edgeSet = Graph::getEdgeSet(); + //auto edgeSet = Graph::getEdgeSet(); + auto edgeSet = Graph::getEdgeVector(); // inner loop for distance updates of // each relaxation for (const auto &edge : edgeSet) { @@ -100,7 +102,8 @@ const BellmanFordResult Graph::bellmanford(const Node &source, // check if there exists a negative cycle if (!earlyStopping) { - auto edgeSet = Graph::getEdgeSet(); + //auto edgeSet = Graph::getEdgeSet(); + auto edgeSet = Graph::getEdgeVector(); for (const auto &edge : edgeSet) { auto elem = edge->getNodePair(); auto edge_weight = @@ -126,4 +129,4 @@ const BellmanFordResult Graph::bellmanford(const Node &source, return result; } } // namespace CXXGraph -#endif // __CXXGRAPH_BELLMANFORD_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_BELLMANFORD_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/BestFirstSearch_impl.hpp b/include/CXXGraph/Graph/Algorithm/BestFirstSearch_impl.hpp index d61aed940..7aa945a40 100644 --- a/include/CXXGraph/Graph/Algorithm/BestFirstSearch_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/BestFirstSearch_impl.hpp @@ -35,7 +35,8 @@ template BestFirstSearchResult Graph::best_first_search( const Node &source, const Node &target) const { BestFirstSearchResult result; - auto &nodeSet = Graph::getNodeSet(); + //auto &nodeSet = Graph::getNodeSet(); + auto &nodeSet = Graph::getNodeVector(); using pq_type = std::pair>>; auto source_node_it = std::find_if( @@ -108,7 +109,8 @@ const std::vector> Graph::concurrency_breadth_first_search( const Node &start, size_t num_threads) const { std::vector> bfs_result; // check is exist node in the graph - auto &nodeSet = Graph::getNodeSet(); + //auto &nodeSet = Graph::getNodeSet(); + auto &nodeSet = Graph::getNodeVector(); auto start_node_it = std::find_if( nodeSet.begin(), nodeSet.end(), [&start](auto node) { return node->getUserId() == start.getUserId(); }); @@ -259,4 +261,4 @@ const std::vector> Graph::concurrency_breadth_first_search( return bfs_result; } } // namespace CXXGraph -#endif // __CXXGRAPH_BESTFIRSTSEARCH_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_BESTFIRSTSEARCH_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/Boruvka_impl.hpp b/include/CXXGraph/Graph/Algorithm/Boruvka_impl.hpp index 64b7a85a9..b317234ab 100644 --- a/include/CXXGraph/Graph/Algorithm/Boruvka_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Boruvka_impl.hpp @@ -38,7 +38,8 @@ const MstResult Graph::boruvka() const { result.errorMessage = ERR_DIR_GRAPH; return result; } - const auto nodeSet = Graph::getNodeSet(); + //const auto nodeSet = Graph::getNodeSet(); + const auto nodeSet = Graph::getNodeVector(); const auto n = nodeSet.size(); // Use std map for storing n subsets. @@ -133,7 +134,8 @@ const MstResult Graph::boruvka_deterministic() const { result.errorMessage = ERR_DIR_GRAPH; return result; } - const auto nodeSet = Graph::getNodeSet(); + //const auto nodeSet = Graph::getNodeSet(); + const auto nodeSet = Graph::getNodeVector(); const auto n = nodeSet.size(); // Use std map for storing n subsets. @@ -145,7 +147,8 @@ const MstResult Graph::boruvka_deterministic() const { // check if all edges are weighted and store the weights // in a map whose keys are the edge ids and values are the edge weights - const auto edgeSet = Graph::getEdgeSet(); + //const auto edgeSet = Graph::getEdgeSet(); + const auto edgeSet = Graph::getEdgeVector(); std::unordered_map edgeWeight; for (const auto &edge : edgeSet) { if (edge->isWeighted().has_value() && edge->isWeighted().value()) @@ -223,4 +226,4 @@ const MstResult Graph::boruvka_deterministic() const { } } // namespace CXXGraph -#endif // __CXXGRAPH_BORUVKA_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_BORUVKA_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/BreadthFirstSearch_impl.hpp b/include/CXXGraph/Graph/Algorithm/BreadthFirstSearch_impl.hpp index 82d0b33f0..a2082206f 100644 --- a/include/CXXGraph/Graph/Algorithm/BreadthFirstSearch_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/BreadthFirstSearch_impl.hpp @@ -31,7 +31,8 @@ const std::vector> Graph::breadth_first_search( const Node &start) const { // vector to keep track of visited nodes std::vector> visited; - auto &nodeSet = Graph::getNodeSet(); + //auto &nodeSet = Graph::getNodeSet(); + auto &nodeSet = Graph::getNodeVector(); // check is exist node in the graph auto start_node_it = std::find_if( nodeSet.begin(), nodeSet.end(), @@ -65,4 +66,4 @@ const std::vector> Graph::breadth_first_search( } } // namespace CXXGraph -#endif // __CXXGRAPH_BREADTHFIRSTSEARCH_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_BREADTHFIRSTSEARCH_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/Connectivity_impl.hpp b/include/CXXGraph/Graph/Algorithm/Connectivity_impl.hpp index 9783fe3ff..4cbf506b5 100644 --- a/include/CXXGraph/Graph/Algorithm/Connectivity_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Connectivity_impl.hpp @@ -31,7 +31,8 @@ bool Graph::isConnectedGraph() const { if (!isUndirectedGraph()) { return false; } else { - auto nodeSet = getNodeSet(); + //auto nodeSet = getNodeSet(); + auto nodeSet = getNodeVector(); // created visited map std::unordered_map visited; for (const auto &node : nodeSet) { @@ -70,7 +71,8 @@ bool Graph::isStronglyConnectedGraph() const { if (!isDirectedGraph()) { return false; } else { - auto nodeSet = getNodeSet(); + //auto nodeSet = getNodeSet(); + auto nodeSet = getNodeVector(); for (const auto &start_node : nodeSet) { // created visited map std::unordered_map visited; @@ -106,4 +108,4 @@ bool Graph::isStronglyConnectedGraph() const { } } } // namespace CXXGraph -#endif // __CXXGRAPH_CONNECTIVITY_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_CONNECTIVITY_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/CycleDetection_impl.hpp b/include/CXXGraph/Graph/Algorithm/CycleDetection_impl.hpp index a66f5e2a0..348291209 100644 --- a/include/CXXGraph/Graph/Algorithm/CycleDetection_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/CycleDetection_impl.hpp @@ -31,7 +31,8 @@ bool Graph::isCyclicDirectedGraphDFS() const { return false; } enum nodeStates : uint8_t { not_visited, in_stack, visited }; - auto nodeSet = Graph::getNodeSet(); + //auto nodeSet = Graph::getNodeSet(); + auto nodeSet = Graph::getNodeVector(); /* State of the node. * @@ -176,7 +177,8 @@ bool Graph::isCyclicDirectedGraphBFS() const { if (!isDirectedGraph()) { return false; } - auto nodeSet = Graph::getNodeSet(); + //auto nodeSet = Graph::getNodeSet(); + auto nodeSet = Graph::getNodeVector(); std::unordered_map indegree; for (const auto &node : nodeSet) { @@ -228,4 +230,4 @@ bool Graph::isCyclicDirectedGraphBFS() const { return !(remain == 0); } } // namespace CXXGraph -#endif // __CXXGRAPH_CYCLEDETECTION_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_CYCLEDETECTION_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/DepthFirstSearch_impl.hpp b/include/CXXGraph/Graph/Algorithm/DepthFirstSearch_impl.hpp index 6f3bcf105..faddc0889 100644 --- a/include/CXXGraph/Graph/Algorithm/DepthFirstSearch_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/DepthFirstSearch_impl.hpp @@ -31,7 +31,8 @@ const std::vector> Graph::depth_first_search( const Node &start) const { // vector to keep track of visited nodes std::vector> visited; - auto nodeSet = Graph::getNodeSet(); + //auto nodeSet = Graph::getNodeSet(); + auto nodeSet = Graph::getNodeVector(); // check is exist node in the graph auto start_node_it = std::find_if( nodeSet.begin(), nodeSet.end(), @@ -61,4 +62,4 @@ const std::vector> Graph::depth_first_search( } } // namespace CXXGraph -#endif // __CXXGRAPH_DEPTHFIRSTSEARCH_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_DEPTHFIRSTSEARCH_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/Dial_impl.hpp b/include/CXXGraph/Graph/Algorithm/Dial_impl.hpp index ffebbc370..d1317e883 100644 --- a/include/CXXGraph/Graph/Algorithm/Dial_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Dial_impl.hpp @@ -31,7 +31,8 @@ const DialResult Graph::dial(const Node &source, int maxWeight) const { DialResult result; result.success = false; - auto nodeSet = getNodeSet(); + //auto nodeSet = getNodeSet(); + auto nodeSet = getNodeVector(); auto source_node_it = std::find_if( nodeSet.begin(), nodeSet.end(), @@ -155,4 +156,4 @@ const DialResult Graph::dial(const Node &source, int maxWeight) const { return result; } } // namespace CXXGraph -#endif // __CXXGRAPH_DIAL_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_DIAL_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/Dijkstra_impl.hpp b/include/CXXGraph/Graph/Algorithm/Dijkstra_impl.hpp index 3893d1fb3..257dafa1e 100644 --- a/include/CXXGraph/Graph/Algorithm/Dijkstra_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Dijkstra_impl.hpp @@ -29,7 +29,8 @@ template const DijkstraResult Graph::dijkstra(const Node& source, const Node& target) const { DijkstraResult result; - auto nodeSet = Graph::getNodeSet(); + //auto nodeSet = Graph::getNodeSet(); + auto nodeSet = Graph::getNodeVector(); auto source_node_it = std::find_if( nodeSet.begin(), nodeSet.end(), @@ -150,19 +151,20 @@ const DijkstraResult Graph::dijkstra(const Node& source, } template -const DijkstraResult Graph::dijkstra_deterministic( - const Node& source, const Node& target) const { - DijkstraResult result; - auto nodeSet = Graph::getNodeSet(); - - auto source_node_it = std::find_if( - nodeSet.begin(), nodeSet.end(), - [&source](auto node) { return node->getUserId() == source.getUserId(); }); - if (source_node_it == nodeSet.end()) { - // check if source node exist in the graph - result.errorMessage = ERR_SOURCE_NODE_NOT_IN_GRAPH; - return result; - } +const DijkstraResult Graph::dijkstra_deterministic(const Node& source, + const Node& target) const { + DijkstraResult result; + //auto nodeSet = Graph::getNodeSet(); + auto nodeSet = Graph::getNodeVector(); + + auto source_node_it = std::find_if( + nodeSet.begin(), nodeSet.end(), + [&source](auto node) { return node->getUserId() == source.getUserId(); }); + if (source_node_it == nodeSet.end()) { + // check if source node exist in the graph + result.errorMessage = ERR_SOURCE_NODE_NOT_IN_GRAPH; + return result; + } auto target_node_it = std::find_if( nodeSet.begin(), nodeSet.end(), @@ -297,19 +299,20 @@ const DijkstraResult Graph::dijkstra_deterministic( } template -const DijkstraResult Graph::dijkstra_deterministic2( - const Node& source, const Node& target) const { - DijkstraResult result; - auto nodeSet = Graph::getNodeSet(); - - auto source_node_it = std::find_if( - nodeSet.begin(), nodeSet.end(), - [&source](auto node) { return node->getUserId() == source.getUserId(); }); - if (source_node_it == nodeSet.end()) { - // check if source node exist in the graph - result.errorMessage = ERR_SOURCE_NODE_NOT_IN_GRAPH; - return result; - } +const DijkstraResult Graph::dijkstra_deterministic2(const Node& source, + const Node& target) const { + DijkstraResult result; + //auto nodeSet = Graph::getNodeSet(); + auto nodeSet = Graph::getNodeVector(); + + auto source_node_it = std::find_if( + nodeSet.begin(), nodeSet.end(), + [&source](auto node) { return node->getUserId() == source.getUserId(); }); + if (source_node_it == nodeSet.end()) { + // check if source node exist in the graph + result.errorMessage = ERR_SOURCE_NODE_NOT_IN_GRAPH; + return result; + } auto target_node_it = std::find_if( nodeSet.begin(), nodeSet.end(), @@ -452,4 +455,4 @@ const DijkstraResult Graph::dijkstra_deterministic2( } } // namespace CXXGraph -#endif // __CXXGRAPH_DIJKSTRA_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_DIJKSTRA_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/FloydWarshall_impl.hpp b/include/CXXGraph/Graph/Algorithm/FloydWarshall_impl.hpp index 02aebf06d..8b7cec3fe 100644 --- a/include/CXXGraph/Graph/Algorithm/FloydWarshall_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/FloydWarshall_impl.hpp @@ -34,6 +34,7 @@ const FWResult Graph::floydWarshall() const { CXXGraph::pair_hash> pairwise_dist; const auto &nodeSet = Graph::getNodeSet(); + //const auto &nodeSet = Graph::getNodeVector(); // create a pairwise distance matrix with distance node distances // set to inf. Distance of node to itself is set as 0. for (const auto &elem1 : nodeSet) { @@ -47,6 +48,7 @@ const FWResult Graph::floydWarshall() const { } const auto &edgeSet = Graph::getEdgeSet(); + //const auto &edgeSet = Graph::getEdgeVector(); // update the weights of nodesfloydWarshall // connected by edges for (const auto &edge : edgeSet) { @@ -105,4 +107,4 @@ const FWResult Graph::floydWarshall() const { return result; } } // namespace CXXGraph -#endif // __CXXGRAPH_FLOYDWARSHALL_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_FLOYDWARSHALL_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/FordFulkerson_impl.hpp b/include/CXXGraph/Graph/Algorithm/FordFulkerson_impl.hpp index 1a1ad3efc..171bd1836 100644 --- a/include/CXXGraph/Graph/Algorithm/FordFulkerson_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/FordFulkerson_impl.hpp @@ -41,7 +41,8 @@ double Graph::fordFulkersonMaxFlow(const Node &source, nodeHash> weightMap; // build weight map - auto edgeSet = this->getEdgeSet(); + //auto edgeSet = this->getEdgeSet(); + auto edgeSet = this->getEdgeVector(); for (const auto &edge : edgeSet) { // The Edge are all Directed at this point because is checked at the // start @@ -57,7 +58,8 @@ double Graph::fordFulkersonMaxFlow(const Node &source, } // Constuct iterators for source and target nodes in nodeSet - auto nodeSet = getNodeSet(); + //auto nodeSet = getNodeSet(); + auto nodeSet = getNodeVector(); auto source_node_ptr = *std::find_if( nodeSet.begin(), nodeSet.end(), [&source](auto node) { return node->getUserId() == source.getUserId(); }); @@ -105,4 +107,4 @@ double Graph::fordFulkersonMaxFlow(const Node &source, return maxFlow; } } // namespace CXXGraph -#endif // __CXXGRAPH_FORDFULKERSON_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_FORDFULKERSON_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/Kahn_impl.hpp b/include/CXXGraph/Graph/Algorithm/Kahn_impl.hpp index 3194f8458..a8e4cd0af 100644 --- a/include/CXXGraph/Graph/Algorithm/Kahn_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Kahn_impl.hpp @@ -34,7 +34,8 @@ TopoSortResult Graph::kahn() const { result.errorMessage = ERR_UNDIR_GRAPH; return result; } else { - const auto nodeSet = Graph::getNodeSet(); + //const auto nodeSet = Graph::getNodeSet(); + const auto nodeSet = Graph::getNodeVector(); result.nodesInTopoOrder.reserve(cachedAdjMatrix->size()); std::unordered_map indegree; @@ -83,4 +84,4 @@ TopoSortResult Graph::kahn() const { } } } // namespace CXXGraph -#endif // __CXXGRAPH_KAHN_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_KAHN_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/Kosaraju_impl.hpp b/include/CXXGraph/Graph/Algorithm/Kosaraju_impl.hpp index faad5cb80..08811e09d 100644 --- a/include/CXXGraph/Graph/Algorithm/Kosaraju_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Kosaraju_impl.hpp @@ -37,7 +37,8 @@ SCCResult Graph::kosaraju() const { result.errorMessage = ERR_UNDIR_GRAPH; return result; } else { - auto nodeSet = getNodeSet(); + //auto nodeSet = getNodeSet(); + auto nodeSet = getNodeVector(); // created visited map std::unordered_map visited; for (const auto &node : nodeSet) { @@ -125,4 +126,4 @@ SCCResult Graph::kosaraju() const { } } } // namespace CXXGraph -#endif // __CXXGRAPH_KOSARAJU_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_KOSARAJU_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/Kruskal_impl.hpp b/include/CXXGraph/Graph/Algorithm/Kruskal_impl.hpp index 39e69096f..ff8bcf49c 100644 --- a/include/CXXGraph/Graph/Algorithm/Kruskal_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Kruskal_impl.hpp @@ -36,12 +36,14 @@ const MstResult Graph::kruskal() const { result.errorMessage = ERR_DIR_GRAPH; return result; } - const auto nodeSet = Graph::getNodeSet(); + //const auto nodeSet = Graph::getNodeSet(); + const auto nodeSet = Graph::getNodeVector(); auto n = nodeSet.size(); // check if all edges are weighted and store the weights // in a map whose keys are the edge ids and values are the edge weights - auto edgeSet = Graph::getEdgeSet(); + //auto edgeSet = Graph::getEdgeSet(); + auto edgeSet = Graph::getEdgeVector(); std::priority_queue>>, std::vector>>>, std::greater>>>> @@ -82,4 +84,4 @@ const MstResult Graph::kruskal() const { return result; } } // namespace CXXGraph -#endif // __CXXGRAPH_KRUSKAL_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_KRUSKAL_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/Prim_impl.hpp b/include/CXXGraph/Graph/Algorithm/Prim_impl.hpp index c6499eae5..f20836e8e 100644 --- a/include/CXXGraph/Graph/Algorithm/Prim_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Prim_impl.hpp @@ -40,7 +40,8 @@ const MstResult Graph::prim() const { result.errorMessage = ERR_NOT_STRONG_CONNECTED; return result; } - auto nodeSet = Graph::getNodeSet(); + //auto nodeSet = Graph::getNodeSet(); + auto nodeSet = Graph::getNodeVector(); auto n = nodeSet.size(); // setting all the distances initially to INF_DOUBLE @@ -109,4 +110,4 @@ const MstResult Graph::prim() const { return result; } } // namespace CXXGraph -#endif // __CXXGRAPH_PRIM_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_PRIM_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/Tarjan_impl.hpp b/include/CXXGraph/Graph/Algorithm/Tarjan_impl.hpp index ff9d20951..7851dc11b 100644 --- a/include/CXXGraph/Graph/Algorithm/Tarjan_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Tarjan_impl.hpp @@ -48,7 +48,8 @@ const TarjanResult Graph::tarjan(const unsigned int typeMask) const { } } - const auto &nodeSet = getNodeSet(); + //const auto &nodeSet = getNodeSet(); + const auto &nodeSet = getNodeVector(); std::unordered_map discoveryTime; // the timestamp when a node is visited std::unordered_map @@ -66,6 +67,7 @@ const TarjanResult Graph::tarjan(const unsigned int typeMask) const { &ebccNodeStack, &vbccNodeStack, &inStack, &result](const shared> curNode, const shared> prevEdge) { + result.vertexTraversalOrdering.push_back(curNode->getData()); // record the visited time of current node discoveryTime[curNode->getId()] = timestamp; lowestDisc[curNode->getId()] = timestamp; diff --git a/include/CXXGraph/Graph/Algorithm/TopologicalSort_impl.hpp b/include/CXXGraph/Graph/Algorithm/TopologicalSort_impl.hpp index 83e293fe6..0f84c0686 100644 --- a/include/CXXGraph/Graph/Algorithm/TopologicalSort_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/TopologicalSort_impl.hpp @@ -38,7 +38,8 @@ TopoSortResult Graph::topologicalSort() const { result.errorMessage = ERR_CYCLIC_GRAPH; return result; } else { - const auto &nodeSet = getNodeSet(); + //const auto &nodeSet = getNodeSet(); + const auto &nodeSet = getNodeVector(); std::unordered_map>, bool, nodeHash> visited; std::function>)> postorder_helper = @@ -75,4 +76,4 @@ TopoSortResult Graph::topologicalSort() const { } } // namespace CXXGraph -#endif // __CXXGRAPH_TOPOLOGICALSORT_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_TOPOLOGICALSORT_IMPL_H__ diff --git a/include/CXXGraph/Graph/Algorithm/TransitiveReduction_impl.hpp b/include/CXXGraph/Graph/Algorithm/TransitiveReduction_impl.hpp index 942637450..4c1c141e6 100644 --- a/include/CXXGraph/Graph/Algorithm/TransitiveReduction_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/TransitiveReduction_impl.hpp @@ -39,8 +39,9 @@ const Graph Graph::transitiveReduction() const { Graph result(this->edgeSet); CXXGraph::id_t edgeId = 0; - std::unordered_set>, nodeHash> nodes = - this->getNodeSet(); + //std::unordered_set>, nodeHash> nodes = + //this->getNodeSet(); + auto nodes = this->getNodeVector(); for (auto x : nodes) { for (auto y : nodes) { if (this->findEdge(x, y, edgeId)) { @@ -58,4 +59,4 @@ const Graph Graph::transitiveReduction() const { return result; } } // namespace CXXGraph -#endif // __CXXGRAPH_TRANSITIVEREDUCTION_IMPL_H__ \ No newline at end of file +#endif // __CXXGRAPH_TRANSITIVEREDUCTION_IMPL_H__ diff --git a/include/CXXGraph/Graph/Graph_decl.h b/include/CXXGraph/Graph/Graph_decl.h index bc5619ca5..47cdaf950 100644 --- a/include/CXXGraph/Graph/Graph_decl.h +++ b/include/CXXGraph/Graph/Graph_decl.h @@ -114,6 +114,32 @@ class Graph { Graph(); Graph(const T_EdgeSet &edgeSet); virtual ~Graph() = default; + /** + * \brief + * Function that shuffle cachedAdjMatrix + * Note: No Thread Safe + * + * @no returns + */ + virtual void shuffleAdjMatrix(); + /** + * \brief + * Function that return the Node vector of the Graph + * Note: No Thread Safe + * + * @returns a vector of Nodes of the graph + * + */ + virtual const std::vector>> getNodeVector() const; + /** + * \brief + * Function that return the Edge vector of the Graph + * Note: No Thread Safe + * + * @returns a vector of Edges of the graph + * + */ + virtual const std::vector>> getEdgeVector() const; /** * \brief * Function that return the Edge set of the Graph diff --git a/include/CXXGraph/Graph/Graph_impl.hpp b/include/CXXGraph/Graph/Graph_impl.hpp index e6ca0221b..4fd86131c 100644 --- a/include/CXXGraph/Graph/Graph_impl.hpp +++ b/include/CXXGraph/Graph/Graph_impl.hpp @@ -24,6 +24,9 @@ #include +#include +#include + #include "CXXGraph/Graph/Graph_decl.h" #include "CXXGraph/Utility/ConstString.hpp" @@ -292,6 +295,36 @@ bool Graph::findEdge(shared> v1, shared> v2, return false; } +template +void Graph::shuffleAdjMatrix() { + std::random_device rd; + std::mt19937 rng(rd()); + for (auto& p : *(this->cachedAdjMatrix)) { + std::shuffle(p.second.begin(), p.second.end(), rng); + } +} + +template +const std::vector>> Graph::getEdgeVector() const { + std::vector>> edgeVector; + edgeVector.assign(edgeSet.begin(), edgeSet.end()); + std::random_device rd; + std::mt19937 rng(rd()); + std::shuffle(edgeVector.begin(), edgeVector.end(), rng); + return edgeVector; +} + +template +const std::vector>> Graph::getNodeVector() const { + T_NodeSet nodeSet = this->getNodeSet(); + std::vector>> nodeVector; + nodeVector.assign(nodeSet.begin(), nodeSet.end()); + std::random_device rd; + std::mt19937 rng(rd()); + std::shuffle(nodeVector.begin(), nodeVector.end(), rng); + return nodeVector; +} + template const T_NodeSet Graph::getNodeSet() const { T_NodeSet nodeSet; @@ -529,6 +562,7 @@ template void Graph::cacheAdjMatrix() { const auto adj = Graph::getAdjMatrix(); this->cachedAdjMatrix = adj; + shuffleAdjMatrix(); } template diff --git a/include/CXXGraph/Utility/Typedef.hpp b/include/CXXGraph/Utility/Typedef.hpp index bc8b27755..4d116fa8a 100644 --- a/include/CXXGraph/Utility/Typedef.hpp +++ b/include/CXXGraph/Utility/Typedef.hpp @@ -204,6 +204,13 @@ struct TarjanResult_struct { bool success = false; // TRUE if the function does not return error, FALSE otherwise std::string errorMessage = ""; // message of error + std::vector vertexTraversalOrdering; + inline void showOrdering() const { + for (const auto& v : vertexTraversalOrdering) { + std::cout << v << " "; + } + std::cout << "\n"; + } Components stronglyConnectedComps; // vectors that store nodes belong to same SCC // (valid only if a graph is directed and flag @@ -222,6 +229,44 @@ struct TarjanResult_struct { std::vector> bridges; // a vector that stores bridges // (valid only is a graph is undirected and // flag TRAJAN_FIND_BRIDGES is set) + inline void sort() { + auto cmpNodeVec = [&](const auto& left, const auto& right) -> bool { + int i = 0; + while (left[i] == right[i]) { + ++i; + if (i == left.size()) { + return true; + } else if (i == right.size()) { + return false; + } + } + return left[i].getData() < right[i].getData(); + }; /// cmpNodeVec + + /// SCC + for (auto& comp : stronglyConnectedComps) { + std::sort(comp.begin(), comp.end()); + } + std::sort(stronglyConnectedComps.begin(), stronglyConnectedComps.end(), cmpNodeVec); + + /// VBCC + for (auto& comp : verticeBiconnectedComps) { + std::sort(comp.begin(), comp.end()); + } + std::sort(verticeBiconnectedComps.begin(), verticeBiconnectedComps.end(), cmpNodeVec); + + /// EBCC + for (auto& comp : edgeBiconnectedComps) { + std::sort(comp.begin(), comp.end()); + } + std::sort(edgeBiconnectedComps.begin(), edgeBiconnectedComps.end(), cmpNodeVec); + + /// CUTV + std::sort(cutVertices.begin(), cutVertices.end()); + + /// BRIDGE + std::sort(bridges.begin(), bridges.end()); + } /// sort }; template using TarjanResult = TarjanResult_struct; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4fad9e6f7..f676784fb 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -37,7 +37,8 @@ if(TEST) CPMAddPackage( NAME zlib GITHUB_REPOSITORY madler/zlib - VERSION 1.2.13 + #VERSION 1.2.13 + VERSION 1.2.12 OPTIONS "CMAKE_POSITION_INDEPENDENT_CODE True" ) diff --git a/test/TarjanTest.cpp b/test/TarjanTest.cpp index 2405609f4..0fa12a51f 100644 --- a/test/TarjanTest.cpp +++ b/test/TarjanTest.cpp @@ -345,6 +345,26 @@ TEST(TarjanTest, test_7) { CXXGraph::TarjanResult res = graph.tarjan(CXXGraph::TARJAN_FIND_CUTV | CXXGraph::TARJAN_FIND_BRIDGE | CXXGraph::TARJAN_FIND_EBCC | CXXGraph::TARJAN_FIND_VBCC); + { + cutvRes.sort(); + bridgeRes.sort(); + vbccRes.sort(); + ebccRes.sort(); + res.sort(); + std::cout << "sort...\n"; + } + { + std::cout << "cutvRes ordering:\n"; + cutvRes.showOrdering(); + std::cout << "bridgeRes ordering:\n"; + bridgeRes.showOrdering(); + std::cout << "vbccRes ordering:\n"; + vbccRes.showOrdering(); + std::cout << "ebccRes ordering:\n"; + ebccRes.showOrdering(); + std::cout << "res ordering:\n"; + res.showOrdering(); + } ASSERT_EQ(res.success, true); ASSERT_EQ(res.cutVertices.size(), cutvRes.cutVertices.size());