From 4b732e76c2ef477505a458a3089949e17402eb5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Monta=C3=B1ana?= Date: Sat, 7 Oct 2023 19:08:13 +0200 Subject: [PATCH] MST change unordered_set to list --- Makefile | 13 ++++++++----- src/BayesNet/Mst.cc | 24 ++++++++++++++++-------- tests/TestBayesMetrics.cc | 34 +++++++++++++--------------------- 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/Makefile b/Makefile index 1a95287..0aae4a2 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,10 @@ define ClearTests rm -f $(f_debug)/tests/$$t ; \ fi ; \ done - @find . -name "*.gcda" -print0 | xargs -0 rm 2>/dev/null ; + $(eval nfiles=$(find . -name "*.gcda" -print)) + @if test "${nfiles}" != "" ; then \ + find . -name "*.gcda" -print0 | xargs -0 rm 2>/dev/null ;\ + fi ; endef @@ -61,14 +64,14 @@ debug: ## Build a debug version of the project @echo ">>> Building Debug BayesNet..."; @if [ -d ./$(f_debug) ]; then rm -rf ./$(f_debug); fi @mkdir $(f_debug); - @cmake -S . -B $(f_debug) -D CMAKE_BUILD_TYPE=Debug -D ENABLE_TESTING=ON -D CODE_COVERAGE=ON; + @cmake -S . -B $(f_debug) -D CMAKE_BUILD_TYPE=Debug -D ENABLE_TESTING=ON -D CODE_COVERAGE=ON $(n_procs) ; @echo ">>> Done"; release: ## Build a Release version of the project @echo ">>> Building Release BayesNet..."; @if [ -d ./$(f_release) ]; then rm -rf ./$(f_release); fi @mkdir $(f_release); - @cmake -S . -B $(f_release) -D CMAKE_BUILD_TYPE=Release; + @cmake -S . -B $(f_release) -D CMAKE_BUILD_TYPE=Release $(n_procs); @echo ">>> Done"; opt = "" @@ -88,7 +91,7 @@ opt = "" testp: ## Run platform tests (opt="-s") to verbose output the tests, (opt="-c='Stratified Fold Test'") to run only that section @echo ">>> Running Platform tests..."; @$(MAKE) clean - @cmake --build $(f_debug) --target unit_tests_platform ; + @cmake --build $(f_debug) --target unit_tests_platform $(n_procs) ; @if [ -f $(f_debug)/tests/unit_tests_platform ]; then cd $(f_debug)/tests ; ./unit_tests_platform $(opt) ; fi ; @echo ">>> Done"; @@ -96,7 +99,7 @@ opt = "" testb: ## Run BayesNet tests (opt="-s") to verbose output the tests, (opt="-c='Test Maximum Spanning Tree'") to run only that section @echo ">>> Running BayesNet tests..."; @$(MAKE) clean - @cmake --build $(f_debug) --target unit_tests_bayesnet ; + @cmake --build $(f_debug) --target unit_tests_bayesnet $(n_procs) ; @if [ -f $(f_debug)/tests/unit_tests_bayesnet ]; then cd $(f_debug)/tests ; ./unit_tests_bayesnet $(opt) ; fi ; @echo ">>> Done"; diff --git a/src/BayesNet/Mst.cc b/src/BayesNet/Mst.cc index 42a45c9..c618484 100644 --- a/src/BayesNet/Mst.cc +++ b/src/BayesNet/Mst.cc @@ -1,5 +1,6 @@ #include "Mst.h" #include +#include /* Based on the code from https://www.softwaretestinghelp.com/minimum-spanning-tree-tutorial/ @@ -55,15 +56,24 @@ namespace bayesnet { } } + void insertElement(list& variables, int variable) + { + if (find(variables.begin(), variables.end(), variable) == variables.end()) { + variables.push_front(variable); + } + } + vector> reorder(vector>> T, int root_original) { + // Create the edges of a DAG from the MST + // replacing unordered_set with list because unordered_set cannot guarantee the order of the elements inserted auto result = vector>(); auto visited = vector(); - auto nextVariables = unordered_set(); - nextVariables.emplace(root_original); + auto nextVariables = list(); + nextVariables.push_front(root_original); while (nextVariables.size() > 0) { - int root = *nextVariables.begin(); - nextVariables.erase(nextVariables.begin()); + int root = nextVariables.front(); + nextVariables.pop_front(); for (int i = 0; i < T.size(); ++i) { auto [weight, edge] = T[i]; auto [from, to] = edge; @@ -71,10 +81,10 @@ namespace bayesnet { visited.insert(visited.begin(), i); if (from == root) { result.push_back({ from, to }); - nextVariables.emplace(to); + insertElement(nextVariables, to); } else { result.push_back({ to, from }); - nextVariables.emplace(from); + insertElement(nextVariables, from); } } } @@ -99,7 +109,6 @@ namespace bayesnet { { auto num_features = features.size(); Graph g(num_features); - // Make a complete graph for (int i = 0; i < num_features - 1; ++i) { for (int j = i + 1; j < num_features; ++j) { @@ -108,7 +117,6 @@ namespace bayesnet { } g.kruskal_algorithm(); auto mst = g.get_mst(); - g.display_mst(); return reorder(mst, root); } diff --git a/tests/TestBayesMetrics.cc b/tests/TestBayesMetrics.cc index 87b792c..97cda9f 100644 --- a/tests/TestBayesMetrics.cc +++ b/tests/TestBayesMetrics.cc @@ -8,13 +8,7 @@ using namespace std; TEST_CASE("Metrics Test", "[BayesNet]") { - // string file_name = GENERATE("glass", "iris", "ecoli", "diabetes"); - string file_name = "glass"; - // - // - // OJO CAMBIAR - // - // + string file_name = GENERATE("glass", "iris", "ecoli", "diabetes"); map>> resultsKBest = { {"glass", {7, { 0, 1, 7, 6, 3, 5, 2 }}}, {"iris", {3, { 0, 3, 2 }} }, @@ -27,12 +21,15 @@ TEST_CASE("Metrics Test", "[BayesNet]") {"ecoli", 0.0089431099}, {"diabetes", 0.0345470614} }; - map>> resultsMST = { - //{"glass", {{0,6}, {0,5}, {0,3}, {6,2}, {6,7}, {5,1}, {5,8}, {5,4}}}, - {"glass", {{0,6}, {0,5}, {0,3}, {5,1}, {5,8}, {5,4}, {6,2}, {6,7}}}, - {"iris", {{0,1},{0,2},{1,3}}}, - {"ecoli", {{0,1}, {0,2}, {1,5}, {1,3}, {5,6}, {5,4}}}, - {"diabetes", {{0,7}, {0,2}, {0,6}, {2,3}, {3,4}, {3,5}, {4,1}}} + map, vector>> resultsMST = { + { {"glass", 0}, { {0, 6}, {0, 5}, {0, 3}, {5, 1}, {5, 8}, {5, 4}, {6, 2}, {6, 7} } }, + { {"glass", 1}, { {1, 5}, {5, 0}, {5, 8}, {5, 4}, {0, 6}, {0, 3}, {6, 2}, {6, 7} } }, + { {"iris", 0}, { {0, 1}, {0, 2}, {1, 3} } }, + { {"iris", 1}, { {1, 0}, {1, 3}, {0, 2} } }, + { {"ecoli", 0}, { {0, 1}, {0, 2}, {1, 5}, {1, 3}, {5, 6}, {5, 4} } }, + { {"ecoli", 1}, { {1, 0}, {1, 5}, {1, 3}, {5, 6}, {5, 4}, {0, 2} } }, + { {"diabetes", 0}, { {0, 7}, {0, 2}, {0, 6}, {2, 3}, {3, 4}, {3, 5}, {4, 1} } }, + { {"diabetes", 1}, { {1, 4}, {4, 3}, {3, 2}, {3, 5}, {2, 0}, {0, 7}, {0, 6} } } }; auto raw = RawDatasets(file_name, true); bayesnet::Metrics metrics(raw.dataset, raw.featurest, raw.classNamet, raw.classNumStates); @@ -58,14 +55,9 @@ TEST_CASE("Metrics Test", "[BayesNet]") SECTION("Test Maximum Spanning Tree") { auto weights_matrix = metrics.conditionalEdge(raw.weights); - cout << "Weights matrix: " << endl; - for (int i = 0; i < static_cast(raw.featurest.size()); ++i) { - for (int j = 0; j < static_cast(raw.featurest.size()); ++j) { - cout << setw(10) << setprecision(7) << fixed << weights_matrix[i][j].item() << ", "; - } - cout << endl; + for (int i = 0; i < 2; ++i) { + auto result = metrics.maximumSpanningTree(raw.featurest, weights_matrix, i); + REQUIRE(result == resultsMST.at({ file_name, i })); } - auto result = metrics.maximumSpanningTree(raw.featurest, weights_matrix, 0); - REQUIRE(result == resultsMST.at(file_name)); } } \ No newline at end of file