From e00cbbd43cb1558f5b7504a9e140f83bfad9397c Mon Sep 17 00:00:00 2001 From: Nolan Kramer Date: Mon, 22 Apr 2024 13:56:02 -0700 Subject: [PATCH 1/3] Fix Windows builds --- .../Algorithm/welshPowellColoring_impl.hpp | 4 +- include/CXXGraph/Graph/Graph_decl.h | 4 +- include/CXXGraph/Graph/Graph_impl.hpp | 8 +-- include/CXXGraph/Utility/TypeTraits.hpp | 16 ++++++ test/TypeTraitsTest.hpp | 54 +++++++++++++++++++ 5 files changed, 78 insertions(+), 8 deletions(-) diff --git a/include/CXXGraph/Graph/Algorithm/welshPowellColoring_impl.hpp b/include/CXXGraph/Graph/Algorithm/welshPowellColoring_impl.hpp index a308cea72..5e44c66b4 100644 --- a/include/CXXGraph/Graph/Algorithm/welshPowellColoring_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/welshPowellColoring_impl.hpp @@ -17,7 +17,7 @@ std::map, int> Graph::welshPowellColoring() const { std::vector>, int>> degreeOfVertexVector = {}; // Find the degree of each vertex and put them in a vector for (const auto &[nodeFrom, nodeToEdgeVec] : adjMatrix) { - degreeOfVertexVector.push_back({nodeFrom, nodeToEdgeVec.size()}); + degreeOfVertexVector.push_back({nodeFrom, (int)nodeToEdgeVec.size()}); } // Sort them based on the vertex degree @@ -42,7 +42,7 @@ std::map, int> Graph::welshPowellColoring() const { // Assign the smallest unused color to the current vertex auto it = std::find(usedColors.begin() + 1, usedColors.end(), 0); - mapOfColoring[*node] = std::distance(usedColors.begin(), it); + mapOfColoring[*node] = (int)std::distance(usedColors.begin(), it); } return mapOfColoring; diff --git a/include/CXXGraph/Graph/Graph_decl.h b/include/CXXGraph/Graph/Graph_decl.h index aed05eade..3b903b496 100644 --- a/include/CXXGraph/Graph/Graph_decl.h +++ b/include/CXXGraph/Graph/Graph_decl.h @@ -173,7 +173,7 @@ class Graph { * */ template - std::enable_if_t && (is_edge_ptr_v && ...), void> + std::enable_if_t, void> addEdges(T1 edge, Tn... edges); /** * \brief @@ -211,7 +211,7 @@ class Graph { * */ template - std::enable_if_t && (is_node_ptr_v && ...), void> + std::enable_if_t, void> addNodes(T1 node, Tn... nodes); /** * \brief diff --git a/include/CXXGraph/Graph/Graph_impl.hpp b/include/CXXGraph/Graph/Graph_impl.hpp index 41f345b7f..07aafdcec 100644 --- a/include/CXXGraph/Graph/Graph_impl.hpp +++ b/include/CXXGraph/Graph/Graph_impl.hpp @@ -152,7 +152,7 @@ void Graph::addEdges() { template template -std::enable_if_t && (is_edge_ptr_v && ...), void> +std::enable_if_t, void> Graph::addEdges(T1 edge, Tn... edges) { addEdge(edge); addEdges(edges...); @@ -177,7 +177,7 @@ void Graph::addNodes() { template template -std::enable_if_t && (is_node_ptr_v && ...), void> +std::enable_if_t, void> Graph::addNodes(T1 node, Tn... nodes) { addNode(node); addNodes(nodes...); @@ -540,7 +540,7 @@ shared> Graph::getDegreeMatrix() const { const std::vector>, shared>>> &neighbors = nodePair.second; - int degree = neighbors.size(); + int degree = (int)neighbors.size(); (*degreeMatrix)[node] = {degree}; } @@ -605,7 +605,7 @@ shared> Graph::getTransitionMatrix() const { const std::vector>, shared>>> &neighbors = nodePair.second; - int degree = neighbors.size(); + int degree = (int)neighbors.size(); double transitionProbability = 1.0 / degree; diff --git a/include/CXXGraph/Utility/TypeTraits.hpp b/include/CXXGraph/Utility/TypeTraits.hpp index b57d5471d..df5c583ee 100755 --- a/include/CXXGraph/Utility/TypeTraits.hpp +++ b/include/CXXGraph/Utility/TypeTraits.hpp @@ -65,6 +65,14 @@ struct is_node_ptr> template inline constexpr bool is_node_ptr_v = is_node_ptr::value; +template +struct all_are_node_ptrs { + static constexpr bool value = (is_node_ptr_v && ... && is_node_ptr_v); +}; + +template +inline constexpr bool all_are_node_ptrs_v = all_are_node_ptrs::value; + // is_edge type trait template struct is_edge @@ -95,6 +103,14 @@ struct is_edge_ptr> template inline constexpr bool is_edge_ptr_v = is_edge_ptr::value; +template +struct all_are_edge_ptrs { + static constexpr bool value = (is_edge_ptr_v && ... && is_edge_ptr_v); +}; + +template +inline constexpr bool all_are_edge_ptrs_v = all_are_edge_ptrs::value; + } // namespace CXXGraph #endif diff --git a/test/TypeTraitsTest.hpp b/test/TypeTraitsTest.hpp index 7cad7009c..41350c9ca 100644 --- a/test/TypeTraitsTest.hpp +++ b/test/TypeTraitsTest.hpp @@ -34,6 +34,17 @@ static_assert(CXXGraph::is_node_ptr_v*>); static_assert(CXXGraph::is_node_ptr_v>>); static_assert(CXXGraph::is_node_ptr_v>>); +// test all_are_node_ptrs +static_assert(CXXGraph::all_are_node_ptrs*, CXXGraph::Node*, CXXGraph::Node*>::value); +static_assert(CXXGraph::all_are_node_ptrs*, const CXXGraph::Node*, const CXXGraph::Node*>::value); +static_assert(CXXGraph::all_are_node_ptrs>, shared>, shared>>::value); +static_assert(CXXGraph::all_are_node_ptrs>, shared>, shared>>::value); + +static_assert(CXXGraph::all_are_node_ptrs_v*, CXXGraph::Node*, CXXGraph::Node*>); +static_assert(CXXGraph::all_are_node_ptrs_v*, const CXXGraph::Node*, const CXXGraph::Node*>); +static_assert(CXXGraph::all_are_node_ptrs_v>, shared>, shared>>); +static_assert(CXXGraph::all_are_node_ptrs_v>, shared>, shared>>); + // test is_edge static_assert(CXXGraph::is_edge>::value); static_assert(CXXGraph::is_edge>::value); @@ -140,5 +151,48 @@ static_assert(CXXGraph::is_edge_ptr_v>>); static_assert(CXXGraph::is_edge_ptr_v>>); +// test all_are_edge_ptrs +static_assert(CXXGraph::all_are_edge_ptrs*, CXXGraph::Edge*, CXXGraph::Edge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs*, CXXGraph::DirectedEdge*, CXXGraph::DirectedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs*, CXXGraph::DirectedWeightedEdge*, CXXGraph::DirectedWeightedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs*, CXXGraph::UndirectedEdge*, CXXGraph::UndirectedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs*, CXXGraph::UndirectedWeightedEdge*, CXXGraph::UndirectedWeightedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs*, const CXXGraph::Edge*, const CXXGraph::Edge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs*, const CXXGraph::DirectedEdge*, const CXXGraph::DirectedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs*, const CXXGraph::DirectedWeightedEdge*, const CXXGraph::DirectedWeightedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs*, const CXXGraph::UndirectedEdge*, const CXXGraph::UndirectedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs*, const CXXGraph::UndirectedWeightedEdge*, const CXXGraph::UndirectedWeightedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); + +static_assert(CXXGraph::all_are_edge_ptrs_v*, CXXGraph::Edge*, CXXGraph::Edge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, CXXGraph::DirectedEdge*, CXXGraph::DirectedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, CXXGraph::DirectedWeightedEdge*, CXXGraph::DirectedWeightedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, CXXGraph::UndirectedEdge*, CXXGraph::UndirectedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, CXXGraph::UndirectedWeightedEdge*, CXXGraph::UndirectedWeightedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, const CXXGraph::Edge*, const CXXGraph::Edge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, const CXXGraph::DirectedEdge*, const CXXGraph::DirectedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, const CXXGraph::DirectedWeightedEdge*, const CXXGraph::DirectedWeightedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, const CXXGraph::UndirectedEdge*, const CXXGraph::UndirectedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, const CXXGraph::UndirectedWeightedEdge*, const CXXGraph::UndirectedWeightedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); + #endif From 17b96607c43c2e14f1cfdc7c04005bd13de340b5 Mon Sep 17 00:00:00 2001 From: Nolan Kramer Date: Mon, 22 Apr 2024 14:11:39 -0700 Subject: [PATCH 2/3] Run clang-format --- include/CXXGraph/Edge/Edge_impl.hpp | 4 +- .../CXXGraph/Graph/Algorithm/Boruvka_impl.hpp | 16 +- .../Graph/Algorithm/Dijkstra_impl.hpp | 556 +++++++++--------- .../CXXGraph/Graph/Algorithm/Tarjan_impl.hpp | 4 +- .../Algorithm/welshPowellColoring_impl.hpp | 27 +- include/CXXGraph/Graph/Graph_decl.h | 32 +- include/CXXGraph/Graph/Graph_impl.hpp | 8 +- include/CXXGraph/Utility/TypeTraits.hpp | 12 +- test/DijkstraTest.cpp | 2 - test/TypeTraitsTest.hpp | 342 ++++++++--- test/welshPowellColoringTest.cpp | 101 ++-- 11 files changed, 620 insertions(+), 484 deletions(-) diff --git a/include/CXXGraph/Edge/Edge_impl.hpp b/include/CXXGraph/Edge/Edge_impl.hpp index 0c025a49e..f5ae6a30f 100644 --- a/include/CXXGraph/Edge/Edge_impl.hpp +++ b/include/CXXGraph/Edge/Edge_impl.hpp @@ -84,8 +84,8 @@ const unsigned long long Edge::getId() const { } template -const std::pair>, shared>> & -Edge::getNodePair() const { +const std::pair>, shared>> + &Edge::getNodePair() const { return nodePair; } diff --git a/include/CXXGraph/Graph/Algorithm/Boruvka_impl.hpp b/include/CXXGraph/Graph/Algorithm/Boruvka_impl.hpp index 930f1e47d..64b7a85a9 100644 --- a/include/CXXGraph/Graph/Algorithm/Boruvka_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Boruvka_impl.hpp @@ -187,16 +187,16 @@ const MstResult Graph::boruvka_deterministic() const { // Else check if current edge is closer to previous // cheapest edges of set1 and set2 if (cheapest[set1] == INT_MAX || - (edgeWeight[cheapest[set1]] > edgeWeight[edgeId]) || - (edgeWeight[cheapest[set1]] == edgeWeight[edgeId] && cheapest[set1] > edgeId) - ) - cheapest[set1] = edgeId; + (edgeWeight[cheapest[set1]] > edgeWeight[edgeId]) || + (edgeWeight[cheapest[set1]] == edgeWeight[edgeId] && + cheapest[set1] > edgeId)) + cheapest[set1] = edgeId; if (cheapest[set2] == INT_MAX || - (edgeWeight[cheapest[set2]] > edgeWeight[edgeId]) || - (edgeWeight[cheapest[set2]] == edgeWeight[edgeId] && cheapest[set2] > edgeId) - ) - cheapest[set2] = edgeId; + (edgeWeight[cheapest[set2]] > edgeWeight[edgeId]) || + (edgeWeight[cheapest[set2]] == edgeWeight[edgeId] && + cheapest[set2] > edgeId)) + cheapest[set2] = edgeId; } // iterate over all the vertices and add picked diff --git a/include/CXXGraph/Graph/Algorithm/Dijkstra_impl.hpp b/include/CXXGraph/Graph/Algorithm/Dijkstra_impl.hpp index 728146b7c..3893d1fb3 100644 --- a/include/CXXGraph/Graph/Algorithm/Dijkstra_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Dijkstra_impl.hpp @@ -26,8 +26,8 @@ namespace CXXGraph { template -const DijkstraResult Graph::dijkstra(const Node &source, - const Node &target) const { +const DijkstraResult Graph::dijkstra(const Node& source, + const Node& target) const { DijkstraResult result; auto nodeSet = Graph::getNodeSet(); @@ -54,7 +54,7 @@ const DijkstraResult Graph::dijkstra(const Node &source, // setting all the distances initially to INF_DOUBLE std::unordered_map>, double, nodeHash> dist; - for (const auto &node : nodeSet) { + for (const auto& node : nodeSet) { dist[node] = INF_DOUBLE; } @@ -86,7 +86,7 @@ const DijkstraResult Graph::dijkstra(const Node &source, // for all the reachable vertex from the currently exploring vertex // we will try to minimize the distance if (cachedAdjMatrix->find(currentNode) != cachedAdjMatrix->end()) { - for (const auto &elem : cachedAdjMatrix->at(currentNode)) { + for (const auto& elem : cachedAdjMatrix->at(currentNode)) { // minimizing distances if (elem.second->isWeighted().has_value() && elem.second->isWeighted().value()) { @@ -150,317 +150,305 @@ 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 target_node_it = std::find_if( - nodeSet.begin(), nodeSet.end(), - [&target](auto node) { return node->getUserId() == target.getUserId(); }); - if (target_node_it == nodeSet.end()) { - // check if target node exist in the graph - result.errorMessage = ERR_TARGET_NODE_NOT_IN_GRAPH; - return result; - } - // n denotes the number of vertices in graph - auto n = cachedAdjMatrix->size(); + 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; + } - // setting all the distances initially to INF_DOUBLE - std::unordered_map>, double, nodeHash> dist; - std::map>> userIds; + auto target_node_it = std::find_if( + nodeSet.begin(), nodeSet.end(), + [&target](auto node) { return node->getUserId() == target.getUserId(); }); + if (target_node_it == nodeSet.end()) { + // check if target node exist in the graph + result.errorMessage = ERR_TARGET_NODE_NOT_IN_GRAPH; + return result; + } + // n denotes the number of vertices in graph + auto n = cachedAdjMatrix->size(); - for (const auto& node : nodeSet) { - dist[node] = INF_DOUBLE; - userIds[node->getUserId()] = node; - } + // setting all the distances initially to INF_DOUBLE + std::unordered_map>, double, nodeHash> dist; + std::map>> userIds; - std::unordered_map>, size_t, nodeHash> stableIds; - size_t index(0); - for (const auto& it : userIds) - stableIds[it.second] = index++; + for (const auto& node : nodeSet) { + dist[node] = INF_DOUBLE; + userIds[node->getUserId()] = node; + } - // creating a min heap using priority queue - // first element of pair contains the distance - // second element of pair contains the vertex + std::unordered_map>, size_t, nodeHash> stableIds; + size_t index(0); + for (const auto& it : userIds) stableIds[it.second] = index++; - struct VertexInfo - { - double distance = 0; - size_t sumOfIds = 0; - shared> node; - }; + // creating a min heap using priority queue + // first element of pair contains the distance + // second element of pair contains the vertex - struct VertexInfoGreater - { - bool operator()(const VertexInfo& a, const VertexInfo& b) const - { - if (a.distance == b.distance) - return a.sumOfIds > b.sumOfIds; - return a.distance > b.distance; - }; + struct VertexInfo { + double distance = 0; + size_t sumOfIds = 0; + shared> node; + }; + + struct VertexInfoGreater { + bool operator()(const VertexInfo& a, const VertexInfo& b) const { + if (a.distance == b.distance) return a.sumOfIds > b.sumOfIds; + return a.distance > b.distance; }; - - std::priority_queue, - VertexInfoGreater> - pq; - - // pushing the source vertex 's' with 0 distance in min heap - pq.push(VertexInfo{ 0.0, stableIds[*source_node_it], *source_node_it }); - - // marking the distance of source as 0 - dist[*source_node_it] = 0; - - std::unordered_map parent; - parent[source.getUserId()] = ""; - - while (!pq.empty()) { - // second element of pair denotes the node / vertex - shared> currentNode = pq.top().node; - // first element of pair denotes the distance - double currentDist = pq.top().distance; - auto currentNodesSum = pq.top().sumOfIds; - - pq.pop(); - - // for all the reachable vertex from the currently exploring vertex - // we will try to minimize the distance - if (cachedAdjMatrix->find(currentNode) != cachedAdjMatrix->end()) { - for (const auto& elem : cachedAdjMatrix->at(currentNode)) { - // minimizing distances - if (elem.second->isWeighted().has_value() && - elem.second->isWeighted().value()) { - if (elem.second->isDirected().has_value() && - elem.second->isDirected().value()) { - shared> dw_edge = - std::static_pointer_cast>( - elem.second); - if (dw_edge->getWeight() < 0) { - result.errorMessage = ERR_NEGATIVE_WEIGHTED_EDGE; - return result; - } - else if (currentDist + dw_edge->getWeight() < dist[elem.first]) { - dist[elem.first] = currentDist + dw_edge->getWeight(); - pq.push(VertexInfo{ dist[elem.first], currentNodesSum + stableIds[elem.first], elem.first }); - parent[elem.first.get()->getUserId()] = - currentNode.get()->getUserId(); - } - } - else if (elem.second->isDirected().has_value() && - !elem.second->isDirected().value()) { - shared> udw_edge = - std::static_pointer_cast>( - elem.second); - if (udw_edge->getWeight() < 0) { - result.errorMessage = ERR_NEGATIVE_WEIGHTED_EDGE; - return result; - } - else if (currentDist + udw_edge->getWeight() < dist[elem.first]) { - dist[elem.first] = currentDist + udw_edge->getWeight(); - pq.push(VertexInfo{ dist[elem.first], currentNodesSum + stableIds[elem.first], elem.first }); - parent[elem.first.get()->getUserId()] = currentNode.get()->getUserId(); - } - } - else { - // ERROR it shouldn't never returned ( does not exist a Node - // Weighted and not Directed/Undirected) - result.errorMessage = ERR_NO_DIR_OR_UNDIR_EDGE; - return result; - } - } - else { - // No Weighted Edge - result.errorMessage = ERR_NO_WEIGHTED_EDGE; - return result; - } + }; + + std::priority_queue, VertexInfoGreater> + pq; + + // pushing the source vertex 's' with 0 distance in min heap + pq.push(VertexInfo{0.0, stableIds[*source_node_it], *source_node_it}); + + // marking the distance of source as 0 + dist[*source_node_it] = 0; + + std::unordered_map parent; + parent[source.getUserId()] = ""; + + while (!pq.empty()) { + // second element of pair denotes the node / vertex + shared> currentNode = pq.top().node; + // first element of pair denotes the distance + double currentDist = pq.top().distance; + auto currentNodesSum = pq.top().sumOfIds; + + pq.pop(); + + // for all the reachable vertex from the currently exploring vertex + // we will try to minimize the distance + if (cachedAdjMatrix->find(currentNode) != cachedAdjMatrix->end()) { + for (const auto& elem : cachedAdjMatrix->at(currentNode)) { + // minimizing distances + if (elem.second->isWeighted().has_value() && + elem.second->isWeighted().value()) { + if (elem.second->isDirected().has_value() && + elem.second->isDirected().value()) { + shared> dw_edge = + std::static_pointer_cast>( + elem.second); + if (dw_edge->getWeight() < 0) { + result.errorMessage = ERR_NEGATIVE_WEIGHTED_EDGE; + return result; + } else if (currentDist + dw_edge->getWeight() < dist[elem.first]) { + dist[elem.first] = currentDist + dw_edge->getWeight(); + pq.push(VertexInfo{dist[elem.first], + currentNodesSum + stableIds[elem.first], + elem.first}); + parent[elem.first.get()->getUserId()] = + currentNode.get()->getUserId(); + } + } else if (elem.second->isDirected().has_value() && + !elem.second->isDirected().value()) { + shared> udw_edge = + std::static_pointer_cast>( + elem.second); + if (udw_edge->getWeight() < 0) { + result.errorMessage = ERR_NEGATIVE_WEIGHTED_EDGE; + return result; + } else if (currentDist + udw_edge->getWeight() < dist[elem.first]) { + dist[elem.first] = currentDist + udw_edge->getWeight(); + pq.push(VertexInfo{dist[elem.first], + currentNodesSum + stableIds[elem.first], + elem.first}); + parent[elem.first.get()->getUserId()] = + currentNode.get()->getUserId(); } + } else { + // ERROR it shouldn't never returned ( does not exist a Node + // Weighted and not Directed/Undirected) + result.errorMessage = ERR_NO_DIR_OR_UNDIR_EDGE; + return result; + } + } else { + // No Weighted Edge + result.errorMessage = ERR_NO_WEIGHTED_EDGE; + return result; } + } } - if (dist[*target_node_it] != INF_DOUBLE) { - result.success = true; - result.errorMessage = ""; - result.result = dist[*target_node_it]; - std::string id = target.getUserId(); - while (parent[id] != "") { - result.path.push_back(id); - id = parent[id]; - } - result.path.push_back(source.getUserId()); - std::reverse(result.path.begin(), result.path.end()); - return result; + } + if (dist[*target_node_it] != INF_DOUBLE) { + result.success = true; + result.errorMessage = ""; + result.result = dist[*target_node_it]; + std::string id = target.getUserId(); + while (parent[id] != "") { + result.path.push_back(id); + id = parent[id]; } - result.errorMessage = ERR_TARGET_NODE_NOT_REACHABLE; + result.path.push_back(source.getUserId()); + std::reverse(result.path.begin(), result.path.end()); return result; + } + result.errorMessage = ERR_TARGET_NODE_NOT_REACHABLE; + return result; } 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 target_node_it = std::find_if( - nodeSet.begin(), nodeSet.end(), - [&target](auto node) { return node->getUserId() == target.getUserId(); }); - if (target_node_it == nodeSet.end()) { - // check if target node exist in the graph - result.errorMessage = ERR_TARGET_NODE_NOT_IN_GRAPH; - return result; - } - // n denotes the number of vertices in graph - auto n = cachedAdjMatrix->size(); + 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; + } - // setting all the distances initially to INF_DOUBLE - std::unordered_map>, double, nodeHash> dist; - std::map>> userIds; + auto target_node_it = std::find_if( + nodeSet.begin(), nodeSet.end(), + [&target](auto node) { return node->getUserId() == target.getUserId(); }); + if (target_node_it == nodeSet.end()) { + // check if target node exist in the graph + result.errorMessage = ERR_TARGET_NODE_NOT_IN_GRAPH; + return result; + } + // n denotes the number of vertices in graph + auto n = cachedAdjMatrix->size(); - for (const auto& node : nodeSet) { - dist[node] = INF_DOUBLE; - userIds[node->getUserId()] = node; - } + // setting all the distances initially to INF_DOUBLE + std::unordered_map>, double, nodeHash> dist; + std::map>> userIds; - std::unordered_map>, uint64_t, nodeHash> stableIds; - size_t index(0); - for (const auto& it : userIds) - stableIds[it.second] = index++; + for (const auto& node : nodeSet) { + dist[node] = INF_DOUBLE; + userIds[node->getUserId()] = node; + } - // creating a min heap using priority queue - // first element of pair contains the distance - // second element of pair contains the vertex + std::unordered_map>, uint64_t, nodeHash> stableIds; + size_t index(0); + for (const auto& it : userIds) stableIds[it.second] = index++; - struct VertexInfo - { - double distance = 0; - std::vector pathToVertex; - shared> node; - }; + // creating a min heap using priority queue + // first element of pair contains the distance + // second element of pair contains the vertex - struct VertexInfoGreater - { - bool operator()(const VertexInfo& a, const VertexInfo& b) const - { - if (a.distance == b.distance) - return std::lexicographical_compare(begin(b.pathToVertex), end(b.pathToVertex), begin(a.pathToVertex), end(a.pathToVertex)); - return a.distance > b.distance; - }; + struct VertexInfo { + double distance = 0; + std::vector pathToVertex; + shared> node; + }; + + struct VertexInfoGreater { + bool operator()(const VertexInfo& a, const VertexInfo& b) const { + if (a.distance == b.distance) + return std::lexicographical_compare( + begin(b.pathToVertex), end(b.pathToVertex), begin(a.pathToVertex), + end(a.pathToVertex)); + return a.distance > b.distance; }; + }; - auto addNode = [&](std::vector v, const shared> &node) - { - v.push_back(stableIds[node]); - return v; - }; + auto addNode = [&](std::vector v, const shared>& node) { + v.push_back(stableIds[node]); + return v; + }; + + std::priority_queue, VertexInfoGreater> + pq; + + // pushing the source vertex 's' with 0 distance in min heap + pq.push(VertexInfo{0.0, addNode({}, *source_node_it), *source_node_it}); + + // marking the distance of source as 0 + dist[*source_node_it] = 0; + + std::unordered_map parent; + parent[source.getUserId()] = ""; - std::priority_queue, - VertexInfoGreater> - pq; - - // pushing the source vertex 's' with 0 distance in min heap - pq.push(VertexInfo{ 0.0, addNode({},*source_node_it), *source_node_it }); - - // marking the distance of source as 0 - dist[*source_node_it] = 0; - - std::unordered_map parent; - parent[source.getUserId()] = ""; - - while (!pq.empty()) { - // second element of pair denotes the node / vertex - shared> currentNode = pq.top().node; - // first element of pair denotes the distance - double currentDist = pq.top().distance; - auto currentNodesPath = pq.top().pathToVertex; - - pq.pop(); - - // for all the reachable vertex from the currently exploring vertex - // we will try to minimize the distance - if (cachedAdjMatrix->find(currentNode) != cachedAdjMatrix->end()) { - for (const auto& elem : cachedAdjMatrix->at(currentNode)) { - // minimizing distances - if (elem.second->isWeighted().has_value() && - elem.second->isWeighted().value()) { - if (elem.second->isDirected().has_value() && - elem.second->isDirected().value()) { - shared> dw_edge = - std::static_pointer_cast>( - elem.second); - if (dw_edge->getWeight() < 0) { - result.errorMessage = ERR_NEGATIVE_WEIGHTED_EDGE; - return result; - } - else if (currentDist + dw_edge->getWeight() < dist[elem.first]) { - dist[elem.first] = currentDist + dw_edge->getWeight(); - pq.push(VertexInfo{ dist[elem.first], addNode(currentNodesPath,elem.first), elem.first }); - parent[elem.first.get()->getUserId()] = - currentNode.get()->getUserId(); - } - } - else if (elem.second->isDirected().has_value() && - !elem.second->isDirected().value()) { - shared> udw_edge = - std::static_pointer_cast>( - elem.second); - if (udw_edge->getWeight() < 0) { - result.errorMessage = ERR_NEGATIVE_WEIGHTED_EDGE; - return result; - } - else if (currentDist + udw_edge->getWeight() < dist[elem.first]) { - dist[elem.first] = currentDist + udw_edge->getWeight(); - pq.push(VertexInfo{ dist[elem.first], addNode(currentNodesPath,elem.first), elem.first }); - parent[elem.first.get()->getUserId()] = currentNode.get()->getUserId(); - } - } - else { - // ERROR it shouldn't never returned ( does not exist a Node - // Weighted and not Directed/Undirected) - result.errorMessage = ERR_NO_DIR_OR_UNDIR_EDGE; - return result; - } - } - else { - // No Weighted Edge - result.errorMessage = ERR_NO_WEIGHTED_EDGE; - return result; - } + while (!pq.empty()) { + // second element of pair denotes the node / vertex + shared> currentNode = pq.top().node; + // first element of pair denotes the distance + double currentDist = pq.top().distance; + auto currentNodesPath = pq.top().pathToVertex; + + pq.pop(); + + // for all the reachable vertex from the currently exploring vertex + // we will try to minimize the distance + if (cachedAdjMatrix->find(currentNode) != cachedAdjMatrix->end()) { + for (const auto& elem : cachedAdjMatrix->at(currentNode)) { + // minimizing distances + if (elem.second->isWeighted().has_value() && + elem.second->isWeighted().value()) { + if (elem.second->isDirected().has_value() && + elem.second->isDirected().value()) { + shared> dw_edge = + std::static_pointer_cast>( + elem.second); + if (dw_edge->getWeight() < 0) { + result.errorMessage = ERR_NEGATIVE_WEIGHTED_EDGE; + return result; + } else if (currentDist + dw_edge->getWeight() < dist[elem.first]) { + dist[elem.first] = currentDist + dw_edge->getWeight(); + pq.push(VertexInfo{dist[elem.first], + addNode(currentNodesPath, elem.first), + elem.first}); + parent[elem.first.get()->getUserId()] = + currentNode.get()->getUserId(); + } + } else if (elem.second->isDirected().has_value() && + !elem.second->isDirected().value()) { + shared> udw_edge = + std::static_pointer_cast>( + elem.second); + if (udw_edge->getWeight() < 0) { + result.errorMessage = ERR_NEGATIVE_WEIGHTED_EDGE; + return result; + } else if (currentDist + udw_edge->getWeight() < dist[elem.first]) { + dist[elem.first] = currentDist + udw_edge->getWeight(); + pq.push(VertexInfo{dist[elem.first], + addNode(currentNodesPath, elem.first), + elem.first}); + parent[elem.first.get()->getUserId()] = + currentNode.get()->getUserId(); } + } else { + // ERROR it shouldn't never returned ( does not exist a Node + // Weighted and not Directed/Undirected) + result.errorMessage = ERR_NO_DIR_OR_UNDIR_EDGE; + return result; + } + } else { + // No Weighted Edge + result.errorMessage = ERR_NO_WEIGHTED_EDGE; + return result; } + } } - if (dist[*target_node_it] != INF_DOUBLE) { - result.success = true; - result.errorMessage = ""; - result.result = dist[*target_node_it]; - std::string id = target.getUserId(); - while (parent[id] != "") { - result.path.push_back(id); - id = parent[id]; - } - result.path.push_back(source.getUserId()); - std::reverse(result.path.begin(), result.path.end()); - return result; + } + if (dist[*target_node_it] != INF_DOUBLE) { + result.success = true; + result.errorMessage = ""; + result.result = dist[*target_node_it]; + std::string id = target.getUserId(); + while (parent[id] != "") { + result.path.push_back(id); + id = parent[id]; } - result.errorMessage = ERR_TARGET_NODE_NOT_REACHABLE; + result.path.push_back(source.getUserId()); + std::reverse(result.path.begin(), result.path.end()); return result; + } + result.errorMessage = ERR_TARGET_NODE_NOT_REACHABLE; + return result; } } // namespace CXXGraph diff --git a/include/CXXGraph/Graph/Algorithm/Tarjan_impl.hpp b/include/CXXGraph/Graph/Algorithm/Tarjan_impl.hpp index f6e17a16f..ff9d20951 100644 --- a/include/CXXGraph/Graph/Algorithm/Tarjan_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/Tarjan_impl.hpp @@ -148,7 +148,9 @@ const TarjanResult Graph::tarjan(const unsigned int typeMask) const { // it's not allowed to go through the previous edge back // for a directed graph, it's also not allowed to visit // a node that is not in stack - lowestDisc[curNode->getId()] = std::min(lowestDisc[curNode->getId()], discoveryTime[neighborNode->getId()]); + lowestDisc[curNode->getId()] = + std::min(lowestDisc[curNode->getId()], + discoveryTime[neighborNode->getId()]); } } } diff --git a/include/CXXGraph/Graph/Algorithm/welshPowellColoring_impl.hpp b/include/CXXGraph/Graph/Algorithm/welshPowellColoring_impl.hpp index 5e44c66b4..2ebcd974a 100644 --- a/include/CXXGraph/Graph/Algorithm/welshPowellColoring_impl.hpp +++ b/include/CXXGraph/Graph/Algorithm/welshPowellColoring_impl.hpp @@ -14,20 +14,23 @@ template std::map, int> Graph::welshPowellColoring() const { auto adjMatrix = *getAdjMatrix(); - std::vector>, int>> degreeOfVertexVector = {}; + std::vector>, int>> + degreeOfVertexVector = {}; // Find the degree of each vertex and put them in a vector - for (const auto &[nodeFrom, nodeToEdgeVec] : adjMatrix) { + for (const auto& [nodeFrom, nodeToEdgeVec] : adjMatrix) { degreeOfVertexVector.push_back({nodeFrom, (int)nodeToEdgeVec.size()}); } // Sort them based on the vertex degree - std::sort(degreeOfVertexVector.begin(), degreeOfVertexVector.end(), [](const auto& left, const auto& right) { - return left.second > right.second; - }); + std::sort(degreeOfVertexVector.begin(), degreeOfVertexVector.end(), + [](const auto& left, const auto& right) { + return left.second > right.second; + }); - // Create a new map of coloring, where the keys a re the nodes, and the value is the color order (assigned by integer) + // Create a new map of coloring, where the keys a re the nodes, and the + // value is the color order (assigned by integer) std::map, int> mapOfColoring; - for (const auto &[nodeFrom, _] : adjMatrix) { + for (const auto& [nodeFrom, _] : adjMatrix) { mapOfColoring[*nodeFrom] = 0; } @@ -35,17 +38,17 @@ std::map, int> Graph::welshPowellColoring() const { std::vector usedColors(degreeOfVertexVector.size() + 1, 0); for (const auto& [node, _] : degreeOfVertexVector) { // Find the smallest unused color for the current vertex - std::fill(usedColors.begin(), usedColors.end(), 0); - for (const auto &[neighbor, _] : adjMatrix[node]) { + std::fill(usedColors.begin(), usedColors.end(), 0); + for (const auto& [neighbor, _] : adjMatrix[node]) { usedColors[mapOfColoring[*neighbor]] = 1; } // Assign the smallest unused color to the current vertex - auto it = std::find(usedColors.begin() + 1, usedColors.end(), 0); - mapOfColoring[*node] = (int)std::distance(usedColors.begin(), it); + auto it = std::find(usedColors.begin() + 1, usedColors.end(), 0); + mapOfColoring[*node] = (int)std::distance(usedColors.begin(), it); } return mapOfColoring; } -} +} // namespace CXXGraph #endif // CXXGRAPH_WELSHPOWELLCOLORING_IMPL_H__ diff --git a/include/CXXGraph/Graph/Graph_decl.h b/include/CXXGraph/Graph/Graph_decl.h index 3b903b496..bc5619ca5 100644 --- a/include/CXXGraph/Graph/Graph_decl.h +++ b/include/CXXGraph/Graph/Graph_decl.h @@ -173,8 +173,8 @@ class Graph { * */ template - std::enable_if_t, void> - addEdges(T1 edge, Tn... edges); + std::enable_if_t, void> addEdges(T1 edge, + Tn... edges); /** * \brief * Function to add a Node to the Graph Node Set @@ -211,8 +211,8 @@ class Graph { * */ template - std::enable_if_t, void> - addNodes(T1 node, Tn... nodes); + std::enable_if_t, void> addNodes(T1 node, + Tn... nodes); /** * \brief * Function remove an Edge from the Graph Edge Set @@ -495,10 +495,10 @@ class Graph { */ virtual const DijkstraResult dijkstra(const Node &source, const Node &target) const; - virtual const DijkstraResult dijkstra_deterministic(const Node &source, - const Node &target) const; - virtual const DijkstraResult dijkstra_deterministic2(const Node &source, - const Node &target) const; + virtual const DijkstraResult dijkstra_deterministic( + const Node &source, const Node &target) const; + virtual const DijkstraResult dijkstra_deterministic2( + const Node &source, const Node &target) const; /** * @brief This function runs the tarjan algorithm and returns different types * of results depending on the input parameter typeMask. @@ -801,15 +801,15 @@ class Graph { const Node &target) const; /** - * @brief Welsh-Powell Coloring algorithm - * @return a std::map of keys being the nodes and the values being the color - * order (by integer) starting from 1. - * Source : - * https://www.youtube.com/watch?v=SLkyDuG1Puw&ab_channel=TheLogicalLearning - * https://www.geeksforgeeks.org/welsh-powell-graph-colouring-algorithm/ - * https://www.tutorialspoint.com/de-powell-graph-colouring-algorithm + * @brief Welsh-Powell Coloring algorithm + * @return a std::map of keys being the nodes and the values being the color + * order (by integer) starting from 1. + * Source : + * https://www.youtube.com/watch?v=SLkyDuG1Puw&ab_channel=TheLogicalLearning + * https://www.geeksforgeeks.org/welsh-powell-graph-colouring-algorithm/ + * https://www.tutorialspoint.com/de-powell-graph-colouring-algorithm */ - virtual std::map, int> welshPowellColoring() const; + virtual std::map, int> welshPowellColoring() const; /** * \brief diff --git a/include/CXXGraph/Graph/Graph_impl.hpp b/include/CXXGraph/Graph/Graph_impl.hpp index 07aafdcec..e6ca0221b 100644 --- a/include/CXXGraph/Graph/Graph_impl.hpp +++ b/include/CXXGraph/Graph/Graph_impl.hpp @@ -152,8 +152,8 @@ void Graph::addEdges() { template template -std::enable_if_t, void> -Graph::addEdges(T1 edge, Tn... edges) { +std::enable_if_t, void> Graph::addEdges( + T1 edge, Tn... edges) { addEdge(edge); addEdges(edges...); } @@ -177,8 +177,8 @@ void Graph::addNodes() { template template -std::enable_if_t, void> -Graph::addNodes(T1 node, Tn... nodes) { +std::enable_if_t, void> Graph::addNodes( + T1 node, Tn... nodes) { addNode(node); addNodes(nodes...); } diff --git a/include/CXXGraph/Utility/TypeTraits.hpp b/include/CXXGraph/Utility/TypeTraits.hpp index df5c583ee..a60b86b5f 100755 --- a/include/CXXGraph/Utility/TypeTraits.hpp +++ b/include/CXXGraph/Utility/TypeTraits.hpp @@ -65,12 +65,12 @@ struct is_node_ptr> template inline constexpr bool is_node_ptr_v = is_node_ptr::value; -template +template struct all_are_node_ptrs { - static constexpr bool value = (is_node_ptr_v && ... && is_node_ptr_v); + static constexpr bool value = (is_node_ptr_v && ... && is_node_ptr_v); }; -template +template inline constexpr bool all_are_node_ptrs_v = all_are_node_ptrs::value; // is_edge type trait @@ -103,12 +103,12 @@ struct is_edge_ptr> template inline constexpr bool is_edge_ptr_v = is_edge_ptr::value; -template +template struct all_are_edge_ptrs { - static constexpr bool value = (is_edge_ptr_v && ... && is_edge_ptr_v); + static constexpr bool value = (is_edge_ptr_v && ... && is_edge_ptr_v); }; -template +template inline constexpr bool all_are_edge_ptrs_v = all_are_edge_ptrs::value; } // namespace CXXGraph diff --git a/test/DijkstraTest.cpp b/test/DijkstraTest.cpp index 9d04f54fc..326a771d4 100644 --- a/test/DijkstraTest.cpp +++ b/test/DijkstraTest.cpp @@ -862,8 +862,6 @@ TEST(DijkstraDeterministicTest, target_not_connected_test) { ASSERT_EQ(res.result, CXXGraph::INF_DOUBLE); } - - TEST(DijkstraDeterministic2Test, correct_example_1) { CXXGraph::Node node1("1", 1); CXXGraph::Node node2("2", 2); diff --git a/test/TypeTraitsTest.hpp b/test/TypeTraitsTest.hpp index 41350c9ca..7565a7486 100644 --- a/test/TypeTraitsTest.hpp +++ b/test/TypeTraitsTest.hpp @@ -2,9 +2,10 @@ #ifndef test_type_traits_hpp #define test_type_traits_hpp -#include "CXXGraph/CXXGraph.hpp" #include +#include "CXXGraph/CXXGraph.hpp" + template using shared = std::shared_ptr; @@ -35,15 +36,32 @@ static_assert(CXXGraph::is_node_ptr_v>>); static_assert(CXXGraph::is_node_ptr_v>>); // test all_are_node_ptrs -static_assert(CXXGraph::all_are_node_ptrs*, CXXGraph::Node*, CXXGraph::Node*>::value); -static_assert(CXXGraph::all_are_node_ptrs*, const CXXGraph::Node*, const CXXGraph::Node*>::value); -static_assert(CXXGraph::all_are_node_ptrs>, shared>, shared>>::value); -static_assert(CXXGraph::all_are_node_ptrs>, shared>, shared>>::value); +static_assert( + CXXGraph::all_are_node_ptrs*, CXXGraph::Node*, + CXXGraph::Node*>::value); +static_assert(CXXGraph::all_are_node_ptrs*, + const CXXGraph::Node*, + const CXXGraph::Node*>::value); +static_assert(CXXGraph::all_are_node_ptrs>, + shared>, + shared>>::value); +static_assert( + CXXGraph::all_are_node_ptrs>, + shared>, + shared>>::value); -static_assert(CXXGraph::all_are_node_ptrs_v*, CXXGraph::Node*, CXXGraph::Node*>); -static_assert(CXXGraph::all_are_node_ptrs_v*, const CXXGraph::Node*, const CXXGraph::Node*>); -static_assert(CXXGraph::all_are_node_ptrs_v>, shared>, shared>>); -static_assert(CXXGraph::all_are_node_ptrs_v>, shared>, shared>>); +static_assert( + CXXGraph::all_are_node_ptrs_v*, CXXGraph::Node*, + CXXGraph::Node*>); +static_assert(CXXGraph::all_are_node_ptrs_v*, + const CXXGraph::Node*, + const CXXGraph::Node*>); +static_assert(CXXGraph::all_are_node_ptrs_v>, + shared>, + shared>>); +static_assert(CXXGraph::all_are_node_ptrs_v>, + shared>, + shared>>); // test is_edge static_assert(CXXGraph::is_edge>::value); @@ -53,29 +71,40 @@ static_assert(CXXGraph::is_edge>::value); static_assert(CXXGraph::is_edge>::value); static_assert(CXXGraph::is_edge>::value); static_assert(CXXGraph::is_edge>::value); -static_assert(CXXGraph::is_edge>::value); +static_assert( + CXXGraph::is_edge>::value); static_assert(CXXGraph::is_edge>::value); -static_assert(CXXGraph::is_edge>::value); +static_assert( + CXXGraph::is_edge>::value); static_assert(!CXXGraph::is_edge*>::value); static_assert(!CXXGraph::is_edge*>::value); static_assert(!CXXGraph::is_edge*>::value); static_assert(!CXXGraph::is_edge*>::value); -static_assert(!CXXGraph::is_edge*>::value); +static_assert( + !CXXGraph::is_edge*>::value); static_assert(!CXXGraph::is_edge*>::value); static_assert(!CXXGraph::is_edge*>::value); -static_assert(!CXXGraph::is_edge*>::value); +static_assert( + !CXXGraph::is_edge*>::value); static_assert(!CXXGraph::is_edge*>::value); -static_assert(!CXXGraph::is_edge*>::value); +static_assert( + !CXXGraph::is_edge*>::value); static_assert(!CXXGraph::is_edge>>::value); static_assert(!CXXGraph::is_edge>>::value); -static_assert(!CXXGraph::is_edge>>::value); +static_assert( + !CXXGraph::is_edge>>::value); static_assert(!CXXGraph::is_edge>>::value); -static_assert(!CXXGraph::is_edge>>::value); +static_assert( + !CXXGraph::is_edge>>::value); static_assert(!CXXGraph::is_edge>>::value); -static_assert(!CXXGraph::is_edge>>::value); -static_assert(!CXXGraph::is_edge>>::value); -static_assert(!CXXGraph::is_edge>>::value); -static_assert(!CXXGraph::is_edge>>::value); +static_assert( + !CXXGraph::is_edge>>::value); +static_assert(!CXXGraph::is_edge< + shared>>::value); +static_assert( + !CXXGraph::is_edge>>::value); +static_assert(!CXXGraph::is_edge< + shared>>::value); static_assert(CXXGraph::is_edge_v>); static_assert(CXXGraph::is_edge_v>); @@ -96,39 +125,58 @@ static_assert(!CXXGraph::is_edge_v*>); static_assert(!CXXGraph::is_edge_v*>); static_assert(!CXXGraph::is_edge_v*>); static_assert(!CXXGraph::is_edge_v*>); -static_assert(!CXXGraph::is_edge_v*>); +static_assert( + !CXXGraph::is_edge_v*>); static_assert(!CXXGraph::is_edge_v>>); static_assert(!CXXGraph::is_edge_v>>); -static_assert(!CXXGraph::is_edge_v>>); +static_assert( + !CXXGraph::is_edge_v>>); static_assert(!CXXGraph::is_edge_v>>); -static_assert(!CXXGraph::is_edge_v>>); +static_assert( + !CXXGraph::is_edge_v>>); static_assert(!CXXGraph::is_edge_v>>); static_assert(!CXXGraph::is_edge_v>>); -static_assert(!CXXGraph::is_edge_v>>); -static_assert(!CXXGraph::is_edge_v>>); -static_assert(!CXXGraph::is_edge_v>>); +static_assert( + !CXXGraph::is_edge_v>>); +static_assert( + !CXXGraph::is_edge_v>>); +static_assert( + !CXXGraph::is_edge_v>>); // test is_edge_ptr static_assert(CXXGraph::is_edge_ptr*>::value); static_assert(CXXGraph::is_edge_ptr*>::value); -static_assert(CXXGraph::is_edge_ptr*>::value); +static_assert( + CXXGraph::is_edge_ptr*>::value); static_assert(CXXGraph::is_edge_ptr*>::value); -static_assert(CXXGraph::is_edge_ptr*>::value); +static_assert( + CXXGraph::is_edge_ptr*>::value); static_assert(CXXGraph::is_edge_ptr*>::value); static_assert(CXXGraph::is_edge_ptr*>::value); -static_assert(CXXGraph::is_edge_ptr*>::value); -static_assert(CXXGraph::is_edge_ptr*>::value); -static_assert(CXXGraph::is_edge_ptr*>::value); +static_assert( + CXXGraph::is_edge_ptr*>::value); +static_assert( + CXXGraph::is_edge_ptr*>::value); +static_assert( + CXXGraph::is_edge_ptr*>::value); static_assert(CXXGraph::is_edge_ptr>>::value); -static_assert(CXXGraph::is_edge_ptr>>::value); -static_assert(CXXGraph::is_edge_ptr>>::value); -static_assert(CXXGraph::is_edge_ptr>>::value); -static_assert(CXXGraph::is_edge_ptr>>::value); +static_assert( + CXXGraph::is_edge_ptr>>::value); +static_assert( + CXXGraph::is_edge_ptr>>::value); +static_assert( + CXXGraph::is_edge_ptr>>::value); +static_assert(CXXGraph::is_edge_ptr< + shared>>::value); static_assert(CXXGraph::is_edge_ptr>>::value); -static_assert(CXXGraph::is_edge_ptr>>::value); -static_assert(CXXGraph::is_edge_ptr>>::value); -static_assert(CXXGraph::is_edge_ptr>>::value); -static_assert(CXXGraph::is_edge_ptr>>::value); +static_assert( + CXXGraph::is_edge_ptr>>::value); +static_assert(CXXGraph::is_edge_ptr< + shared>>::value); +static_assert( + CXXGraph::is_edge_ptr>>::value); +static_assert(CXXGraph::is_edge_ptr< + shared>>::value); static_assert(CXXGraph::is_edge_ptr_v*>); static_assert(CXXGraph::is_edge_ptr_v*>); @@ -137,62 +185,178 @@ static_assert(CXXGraph::is_edge_ptr_v*>); static_assert(CXXGraph::is_edge_ptr_v*>); static_assert(CXXGraph::is_edge_ptr_v*>); static_assert(CXXGraph::is_edge_ptr_v*>); -static_assert(CXXGraph::is_edge_ptr_v*>); +static_assert( + CXXGraph::is_edge_ptr_v*>); static_assert(CXXGraph::is_edge_ptr_v*>); -static_assert(CXXGraph::is_edge_ptr_v*>); +static_assert( + CXXGraph::is_edge_ptr_v*>); static_assert(CXXGraph::is_edge_ptr_v>>); static_assert(CXXGraph::is_edge_ptr_v>>); -static_assert(CXXGraph::is_edge_ptr_v>>); +static_assert( + CXXGraph::is_edge_ptr_v>>); static_assert(CXXGraph::is_edge_ptr_v>>); -static_assert(CXXGraph::is_edge_ptr_v>>); +static_assert( + CXXGraph::is_edge_ptr_v>>); static_assert(CXXGraph::is_edge_ptr_v>>); -static_assert(CXXGraph::is_edge_ptr_v>>); -static_assert(CXXGraph::is_edge_ptr_v>>); -static_assert(CXXGraph::is_edge_ptr_v>>); -static_assert(CXXGraph::is_edge_ptr_v>>); +static_assert( + CXXGraph::is_edge_ptr_v>>); +static_assert( + CXXGraph::is_edge_ptr_v>>); +static_assert( + CXXGraph::is_edge_ptr_v>>); +static_assert(CXXGraph::is_edge_ptr_v< + shared>>); // test all_are_edge_ptrs -static_assert(CXXGraph::all_are_edge_ptrs*, CXXGraph::Edge*, CXXGraph::Edge*>::value); -static_assert(CXXGraph::all_are_edge_ptrs*, CXXGraph::DirectedEdge*, CXXGraph::DirectedEdge*>::value); -static_assert(CXXGraph::all_are_edge_ptrs*, CXXGraph::DirectedWeightedEdge*, CXXGraph::DirectedWeightedEdge*>::value); -static_assert(CXXGraph::all_are_edge_ptrs*, CXXGraph::UndirectedEdge*, CXXGraph::UndirectedEdge*>::value); -static_assert(CXXGraph::all_are_edge_ptrs*, CXXGraph::UndirectedWeightedEdge*, CXXGraph::UndirectedWeightedEdge*>::value); -static_assert(CXXGraph::all_are_edge_ptrs*, const CXXGraph::Edge*, const CXXGraph::Edge*>::value); -static_assert(CXXGraph::all_are_edge_ptrs*, const CXXGraph::DirectedEdge*, const CXXGraph::DirectedEdge*>::value); -static_assert(CXXGraph::all_are_edge_ptrs*, const CXXGraph::DirectedWeightedEdge*, const CXXGraph::DirectedWeightedEdge*>::value); -static_assert(CXXGraph::all_are_edge_ptrs*, const CXXGraph::UndirectedEdge*, const CXXGraph::UndirectedEdge*>::value); -static_assert(CXXGraph::all_are_edge_ptrs*, const CXXGraph::UndirectedWeightedEdge*, const CXXGraph::UndirectedWeightedEdge*>::value); -static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); -static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); -static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); -static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); -static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); -static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); -static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); -static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); -static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); -static_assert(CXXGraph::all_are_edge_ptrs>, shared>, shared>>::value); - -static_assert(CXXGraph::all_are_edge_ptrs_v*, CXXGraph::Edge*, CXXGraph::Edge*>); -static_assert(CXXGraph::all_are_edge_ptrs_v*, CXXGraph::DirectedEdge*, CXXGraph::DirectedEdge*>); -static_assert(CXXGraph::all_are_edge_ptrs_v*, CXXGraph::DirectedWeightedEdge*, CXXGraph::DirectedWeightedEdge*>); -static_assert(CXXGraph::all_are_edge_ptrs_v*, CXXGraph::UndirectedEdge*, CXXGraph::UndirectedEdge*>); -static_assert(CXXGraph::all_are_edge_ptrs_v*, CXXGraph::UndirectedWeightedEdge*, CXXGraph::UndirectedWeightedEdge*>); -static_assert(CXXGraph::all_are_edge_ptrs_v*, const CXXGraph::Edge*, const CXXGraph::Edge*>); -static_assert(CXXGraph::all_are_edge_ptrs_v*, const CXXGraph::DirectedEdge*, const CXXGraph::DirectedEdge*>); -static_assert(CXXGraph::all_are_edge_ptrs_v*, const CXXGraph::DirectedWeightedEdge*, const CXXGraph::DirectedWeightedEdge*>); -static_assert(CXXGraph::all_are_edge_ptrs_v*, const CXXGraph::UndirectedEdge*, const CXXGraph::UndirectedEdge*>); -static_assert(CXXGraph::all_are_edge_ptrs_v*, const CXXGraph::UndirectedWeightedEdge*, const CXXGraph::UndirectedWeightedEdge*>); -static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); -static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); -static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); -static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); -static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); -static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); -static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); -static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); -static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); -static_assert(CXXGraph::all_are_edge_ptrs_v>, shared>, shared>>); +static_assert( + CXXGraph::all_are_edge_ptrs*, CXXGraph::Edge*, + CXXGraph::Edge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs*, + CXXGraph::DirectedEdge*, + CXXGraph::DirectedEdge*>::value); +static_assert( + CXXGraph::all_are_edge_ptrs*, + CXXGraph::DirectedWeightedEdge*, + CXXGraph::DirectedWeightedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs< + CXXGraph::UndirectedEdge*, CXXGraph::UndirectedEdge*, + CXXGraph::UndirectedEdge*>::value); +static_assert( + CXXGraph::all_are_edge_ptrs*, + CXXGraph::UndirectedWeightedEdge*, + CXXGraph::UndirectedWeightedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs*, + const CXXGraph::Edge*, + const CXXGraph::Edge*>::value); +static_assert( + CXXGraph::all_are_edge_ptrs*, + const CXXGraph::DirectedEdge*, + const CXXGraph::DirectedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs< + const CXXGraph::DirectedWeightedEdge*, + const CXXGraph::DirectedWeightedEdge*, + const CXXGraph::DirectedWeightedEdge*>::value); +static_assert( + CXXGraph::all_are_edge_ptrs*, + const CXXGraph::UndirectedEdge*, + const CXXGraph::UndirectedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs< + const CXXGraph::UndirectedWeightedEdge*, + const CXXGraph::UndirectedWeightedEdge*, + const CXXGraph::UndirectedWeightedEdge*>::value); +static_assert(CXXGraph::all_are_edge_ptrs>, + shared>, + shared>>::value); +static_assert( + CXXGraph::all_are_edge_ptrs>, + shared>, + shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs< + shared>, + shared>, + shared>>::value); +static_assert( + CXXGraph::all_are_edge_ptrs>, + shared>, + shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs< + shared>, + shared>, + shared>>::value); +static_assert( + CXXGraph::all_are_edge_ptrs>, + shared>, + shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs< + shared>, + shared>, + shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs< + shared>, + shared>, + shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs< + shared>, + shared>, + shared>>::value); +static_assert(CXXGraph::all_are_edge_ptrs< + shared>, + shared>, + shared>>::value); -#endif +static_assert( + CXXGraph::all_are_edge_ptrs_v*, CXXGraph::Edge*, + CXXGraph::Edge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, + CXXGraph::DirectedEdge*, + CXXGraph::DirectedEdge*>); +static_assert( + CXXGraph::all_are_edge_ptrs_v*, + CXXGraph::DirectedWeightedEdge*, + CXXGraph::DirectedWeightedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, + CXXGraph::UndirectedEdge*, + CXXGraph::UndirectedEdge*>); +static_assert( + CXXGraph::all_are_edge_ptrs_v*, + CXXGraph::UndirectedWeightedEdge*, + CXXGraph::UndirectedWeightedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v*, + const CXXGraph::Edge*, + const CXXGraph::Edge*>); +static_assert( + CXXGraph::all_are_edge_ptrs_v*, + const CXXGraph::DirectedEdge*, + const CXXGraph::DirectedEdge*>); +static_assert( + CXXGraph::all_are_edge_ptrs_v*, + const CXXGraph::DirectedWeightedEdge*, + const CXXGraph::DirectedWeightedEdge*>); +static_assert( + CXXGraph::all_are_edge_ptrs_v*, + const CXXGraph::UndirectedEdge*, + const CXXGraph::UndirectedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v< + const CXXGraph::UndirectedWeightedEdge*, + const CXXGraph::UndirectedWeightedEdge*, + const CXXGraph::UndirectedWeightedEdge*>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, + shared>, + shared>>); +static_assert( + CXXGraph::all_are_edge_ptrs_v>, + shared>, + shared>>); +static_assert( + CXXGraph::all_are_edge_ptrs_v>, + shared>, + shared>>); +static_assert( + CXXGraph::all_are_edge_ptrs_v>, + shared>, + shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v< + shared>, + shared>, + shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v>, + shared>, + shared>>); +static_assert( + CXXGraph::all_are_edge_ptrs_v>, + shared>, + shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v< + shared>, + shared>, + shared>>); +static_assert( + CXXGraph::all_are_edge_ptrs_v>, + shared>, + shared>>); +static_assert(CXXGraph::all_are_edge_ptrs_v< + shared>, + shared>, + shared>>); +#endif diff --git a/test/welshPowellColoringTest.cpp b/test/welshPowellColoringTest.cpp index ad8ebd9b6..3d44a1e38 100644 --- a/test/welshPowellColoringTest.cpp +++ b/test/welshPowellColoringTest.cpp @@ -5,21 +5,23 @@ TEST(welshPowellColoring, one_edge_two_nodes_undirected) { CXXGraph::Node node1("1", 1); CXXGraph::Node node2("2", 2); - CXXGraph::UndirectedWeightedEdge edge12(3, node1, node2,4); + CXXGraph::UndirectedWeightedEdge edge12(3, node1, node2, 4); CXXGraph::T_EdgeSet edgeSet; - edgeSet.insert(std::make_shared>(edge12)); + edgeSet.insert( + std::make_shared>(edge12)); CXXGraph::Graph graph(edgeSet); auto result = graph.welshPowellColoring(); // get the highest coloring order - auto highest_coloring_order = std::max_element(result.begin(), result.end(), - [](const auto& lhs, const auto& rhs) { - return lhs.second < rhs.second; - } - )->second; + auto highest_coloring_order = + std::max_element(result.begin(), result.end(), + [](const auto& lhs, const auto& rhs) { + return lhs.second < rhs.second; + }) + ->second; ASSERT_EQ(graph.isUndirectedGraph(), true); // Asserts that the chromatic color of the graph is 2 @@ -40,75 +42,53 @@ TEST(welshPowellColoring, undirected_simon_james) { CXXGraph::Node nodeJ("j", 1); CXXGraph::Node nodeK("k", 1); - CXXGraph::UndirectedEdge edgeAB(1, nodeA, nodeB), - edgeBA(1, nodeB, nodeA), // + edgeBA(1, nodeB, nodeA), // - edgeAC(1, nodeA, nodeC), - edgeCA(1, nodeC, nodeA), // + edgeAC(1, nodeA, nodeC), edgeCA(1, nodeC, nodeA), // - edgeAD(1, nodeA, nodeD), - edgeDA(1, nodeD, nodeA), // + edgeAD(1, nodeA, nodeD), edgeDA(1, nodeD, nodeA), // - edgeAK(1, nodeA, nodeK), - edgeKA(1, nodeK, nodeA), + edgeAK(1, nodeA, nodeK), edgeKA(1, nodeK, nodeA), - edgeAH(1, nodeA, nodeH), - edgeHA(1, nodeA, nodeH), // + edgeAH(1, nodeA, nodeH), edgeHA(1, nodeA, nodeH), // - edgeAE(1, nodeA, nodeE), - edgeEA(1, nodeA, nodeH), // + edgeAE(1, nodeA, nodeE), edgeEA(1, nodeA, nodeH), // - edgeAG(1, nodeA, nodeG), - edgeGA(1, nodeA, nodeG), // + edgeAG(1, nodeA, nodeG), edgeGA(1, nodeA, nodeG), // - edgeBK(1, nodeB, nodeK), - edgeKB(1, nodeK, nodeB), // + edgeBK(1, nodeB, nodeK), edgeKB(1, nodeK, nodeB), // - edgeBI(1, nodeB, nodeI), - edgeIB(1, nodeI, nodeB), // + edgeBI(1, nodeB, nodeI), edgeIB(1, nodeI, nodeB), // - edgeBJ(1, nodeB, nodeJ), - edgeJB(1, nodeJ, nodeB), + edgeBJ(1, nodeB, nodeJ), edgeJB(1, nodeJ, nodeB), - edgeBF(1, nodeB, nodeF), - edgeFB(1, nodeF, nodeB), // + edgeBF(1, nodeB, nodeF), edgeFB(1, nodeF, nodeB), // - edgeBD(1, nodeB, nodeD), - edgeDB(1, nodeD, nodeB), // + edgeBD(1, nodeB, nodeD), edgeDB(1, nodeD, nodeB), // - edgeCE(1, nodeC, nodeE), - edgeEC(1, nodeE, nodeC), // + edgeCE(1, nodeC, nodeE), edgeEC(1, nodeE, nodeC), // - edgeCD(1, nodeC, nodeD), - edgeDC(1, nodeD, nodeC), // + edgeCD(1, nodeC, nodeD), edgeDC(1, nodeD, nodeC), // - edgeCH(1, nodeC, nodeH), - edgeHC(1, nodeH, nodeC), // + edgeCH(1, nodeC, nodeH), edgeHC(1, nodeH, nodeC), // - edgeCG(1, nodeC, nodeG), - edgeGC(1, nodeG, nodeC), // + edgeCG(1, nodeC, nodeG), edgeGC(1, nodeG, nodeC), // - edgeDE(1, nodeD, nodeE), - edgeED(1, nodeD, nodeE), // + edgeDE(1, nodeD, nodeE), edgeED(1, nodeD, nodeE), // - edgeEK(1, nodeE, nodeK), - edgeKE(1, nodeK, nodeE), // + edgeEK(1, nodeE, nodeK), edgeKE(1, nodeK, nodeE), // - edgeFI(1, nodeF, nodeI), - edgeIF(1, nodeI, nodeF), + edgeFI(1, nodeF, nodeI), edgeIF(1, nodeI, nodeF), - edgeFJ(1, nodeF, nodeJ), - edgeJF(1, nodeJ, nodeF), + edgeFJ(1, nodeF, nodeJ), edgeJF(1, nodeJ, nodeF), - edgeFG(1, nodeF, nodeG), - edgeGF(1, nodeG, nodeF), + edgeFG(1, nodeF, nodeG), edgeGF(1, nodeG, nodeF), - edgeGH(1, nodeG, nodeH), - edgeHG(1, nodeH, nodeG), + edgeGH(1, nodeG, nodeH), edgeHG(1, nodeH, nodeG), - edgeIJ(1, nodeI, nodeJ), // - edgeJI(1, nodeJ, nodeI); // + edgeIJ(1, nodeI, nodeJ), // + edgeJI(1, nodeJ, nodeI); // CXXGraph::T_EdgeSet edgeSet; @@ -158,17 +138,18 @@ TEST(welshPowellColoring, undirected_simon_james) { edgeSet.insert(std::make_shared>(edgeIJ)); - CXXGraph::Graph graph(edgeSet); auto result = graph.welshPowellColoring(); - auto highest_coloring_order = std::max_element(result.begin(), result.end(), - [](const auto& lhs, const auto& rhs) { - return lhs.second < rhs.second; - } - )->second; + auto highest_coloring_order = + std::max_element(result.begin(), result.end(), + [](const auto& lhs, const auto& rhs) { + return lhs.second < rhs.second; + }) + ->second; ASSERT_EQ(graph.isUndirectedGraph(), true); - // Asserts that the chromatic color of the graph is 4, as indicated in 2:30 of video + // Asserts that the chromatic color of the graph is 4, as indicated in 2:30 of + // video ASSERT_EQ(highest_coloring_order, 4); } \ No newline at end of file From 717f8336ee758e5bffd71678da8776cf99429179 Mon Sep 17 00:00:00 2001 From: Nolan Kramer Date: Mon, 22 Apr 2024 14:28:02 -0700 Subject: [PATCH 3/3] Run clang-format-16 --- include/CXXGraph/Edge/Edge_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/CXXGraph/Edge/Edge_impl.hpp b/include/CXXGraph/Edge/Edge_impl.hpp index f5ae6a30f..0c025a49e 100644 --- a/include/CXXGraph/Edge/Edge_impl.hpp +++ b/include/CXXGraph/Edge/Edge_impl.hpp @@ -84,8 +84,8 @@ const unsigned long long Edge::getId() const { } template -const std::pair>, shared>> - &Edge::getNodePair() const { +const std::pair>, shared>> & +Edge::getNodePair() const { return nodePair; }