diff --git a/query_modules/louvain/src/algorithms/algorithms.hpp b/query_modules/louvain/src/algorithms/algorithms.hpp index 63713eeb5..4aa1f4bb5 100644 --- a/query_modules/louvain/src/algorithms/algorithms.hpp +++ b/query_modules/louvain/src/algorithms/algorithms.hpp @@ -12,7 +12,7 @@ namespace algorithms { /// algorithm. The algorithm attempts to maximze the modularity of a weighted /// graph. /// - /// @param G pointer to an undirected, weighted graph which may contain - /// self-loops. - void Louvain(comdata::Graph *G); + /// @param graph pointer to an undirected, weighted graph which may contain + /// self-loops. + void Louvain(comdata::Graph *graph); } // namespace algorithms diff --git a/query_modules/louvain/src/algorithms/louvain.cpp b/query_modules/louvain/src/algorithms/louvain.cpp index c6d82959a..1d97b4019 100644 --- a/query_modules/louvain/src/algorithms/louvain.cpp +++ b/query_modules/louvain/src/algorithms/louvain.cpp @@ -9,27 +9,27 @@ namespace { -void OptimizeLocally(comdata::Graph *G) { +void OptimizeLocally(comdata::Graph *graph) { // We will consider local optimizations uniformly at random. std::random_device rd; std::mt19937 g(rd()); - std::vector p(G->Size()); + std::vector p(graph->Size()); std::iota(p.begin(), p.end(), 0); std::shuffle(p.begin(), p.end(), g); - double total_w = G->TotalWeight(); + double total_w = graph->TotalWeight(); bool stable = false; while (!stable) { stable = true; for (uint32_t node_id : p) { std::unordered_map c_contrib; - c_contrib[G->Community(node_id)] = 0; - for (const auto &neigh : G->Neighbours(node_id)) { + c_contrib[graph->Community(node_id)] = 0; + for (const auto &neigh : graph->Neighbours(node_id)) { uint32_t nxt_id = neigh.dest; double weight = neigh.weight; - double contrib = weight - G->IncidentWeight(node_id) * - G->IncidentWeight(nxt_id) / (2 * total_w); - c_contrib[G->Community(nxt_id)] += contrib; + double contrib = weight - graph->IncidentWeight(node_id) * + graph->IncidentWeight(nxt_id) / (2 * total_w); + c_contrib[graph->Community(nxt_id)] += contrib; } auto best_c = std::max_element(c_contrib.begin(), c_contrib.end(), @@ -38,8 +38,8 @@ void OptimizeLocally(comdata::Graph *G) { return p1.second < p2.second; }); - if (best_c->second - c_contrib[G->Community(node_id)] > 0) { - G->SetCommunity(node_id, best_c->first); + if (best_c->second - c_contrib[graph->Community(node_id)] > 0) { + graph->SetCommunity(node_id, best_c->first); stable = false; } } @@ -50,40 +50,43 @@ void OptimizeLocally(comdata::Graph *G) { namespace algorithms { -void Louvain(comdata::Graph *G) { - OptimizeLocally(G); +void Louvain(comdata::Graph *graph) { + OptimizeLocally(graph); // Collapse the locally optimized graph. - uint32_t collapsed_nodes = G->NormalizeCommunities(); - if (collapsed_nodes == G->Size()) return; - comdata::Graph collapsed_G(collapsed_nodes); + uint32_t collapsed_nodes = graph->NormalizeCommunities(); + if (collapsed_nodes == graph->Size()) return; + comdata::Graph collapsed_graph(collapsed_nodes); std::map, double> collapsed_edges; - for (uint32_t node_id = 0; node_id < G->Size(); ++node_id) { + for (uint32_t node_id = 0; node_id < graph->Size(); ++node_id) { std::unordered_map edges; - for (const auto &neigh : G->Neighbours(node_id)) { + for (const auto &neigh : graph->Neighbours(node_id)) { uint32_t nxt_id = neigh.dest; double weight = neigh.weight; - if (G->Community(nxt_id) < G->Community(node_id)) continue; - edges[G->Community(nxt_id)] += weight; + if (graph->Community(nxt_id) < graph->Community(node_id)) continue; + edges[graph->Community(nxt_id)] += weight; } for (const auto &neigh : edges) { - uint32_t a = std::min(G->Community(node_id), neigh.first); - uint32_t b = std::max(G->Community(node_id), neigh.first); + uint32_t a = std::min(graph->Community(node_id), neigh.first); + uint32_t b = std::max(graph->Community(node_id), neigh.first); collapsed_edges[{a, b}] += neigh.second; } } for (const auto &p : collapsed_edges) - collapsed_G.AddEdge(p.first.first, p.first.second, p.second); + collapsed_graph.AddEdge(p.first.first, p.first.second, p.second); // Repeat until no local optimizations can be found. - Louvain(&collapsed_G); + Louvain(&collapsed_graph); // Propagate results from collapsed graph. - for (uint32_t node_id = 0; node_id < G->Size(); ++node_id) - G->SetCommunity(node_id, collapsed_G.Community(G->Community(node_id))); - G->NormalizeCommunities(); + for (uint32_t node_id = 0; node_id < graph->Size(); ++node_id) { + graph->SetCommunity(node_id, + collapsed_graph.Community(graph->Community(node_id))); + } + + graph->NormalizeCommunities(); } } // namespace algorithms diff --git a/query_modules/louvain/src/data_structures/graph.hpp b/query_modules/louvain/src/data_structures/graph.hpp index 94d5a0d58..468edad5e 100644 --- a/query_modules/louvain/src/data_structures/graph.hpp +++ b/query_modules/louvain/src/data_structures/graph.hpp @@ -1,4 +1,4 @@ -/// @file graph.hpp +/// @file #pragma once @@ -21,9 +21,8 @@ public: /// Constructs a new graph with a given number of nodes and no edges between /// them. /// - /// At the moment, the implementation assumes (and enforces) that all nodes - /// are indexed from 0 to n_nodes - 1. This will be changed in the final - /// implementation. - TODO(ipaljak) + /// The implementation assumes (and enforces) that all nodes + /// are indexed from 0 to n_nodes. /// /// @param n_nodes Number of nodes in the graph. explicit Graph(uint32_t n_nodes); diff --git a/query_modules/louvain/src/main.cpp b/query_modules/louvain/src/main.cpp index 86d5d2e11..d1f96efe6 100644 --- a/query_modules/louvain/src/main.cpp +++ b/query_modules/louvain/src/main.cpp @@ -10,19 +10,19 @@ int main() { int n; int m; std::cin >> n >> m; - comdata::Graph G(n); + comdata::Graph graph(n); for (int i = 0; i < m; ++i) { int a; int b; double c; std::cin >> a >> b >> c; - G.AddEdge(a, b, c); + graph.AddEdge(a, b, c); } - algorithms::Louvain(&G); + algorithms::Louvain(&graph); for (int i = 0; i < n; ++i) - std::cout << i << G.Community(i) << "\n"; - std::cout << G.Modularity() << "\n"; + std::cout << i << graph.Community(i) << "\n"; + std::cout << graph.Modularity() << "\n"; return 0; } diff --git a/query_modules/louvain/test/unit/graph.cpp b/query_modules/louvain/test/unit/graph.cpp index 8afcbff5a..dc1c4684a 100644 --- a/query_modules/louvain/test/unit/graph.cpp +++ b/query_modules/louvain/test/unit/graph.cpp @@ -4,130 +4,135 @@ #include "data_structures/graph.hpp" #include "utils.hpp" -// Checks if commmunities of nodes in G correspond to a given community vector. -bool community_check(const comdata::Graph &G, const std::vector &c) { - if (G.Size() != c.size()) return false; - for (uint32_t node_id = 0; node_id < G.Size(); ++node_id) - if (G.Community(node_id) != c[node_id]) +// Checks if commmunities of nodes in graph correspond to a given community +// vector. +bool CommunityCheck(const comdata::Graph &graph, + const std::vector &c) { + if (graph.Size() != c.size()) return false; + for (uint32_t node_id = 0; node_id < graph.Size(); ++node_id) + if (graph.Community(node_id) != c[node_id]) return false; return true; } -// Checks if degrees of nodes in G correspond to a given degree vector. -bool degree_check(const comdata::Graph &G, const std::vector °) { - if (G.Size() != deg.size()) return false; - for (uint32_t node_id = 0; node_id < G.Size(); ++node_id) - if (G.Degree(node_id) != deg[node_id]) +// Checks if degrees of nodes in graph correspond to a given degree vector. +bool DegreeCheck(const comdata::Graph &graph, + const std::vector °) { + if (graph.Size() != deg.size()) return false; + for (uint32_t node_id = 0; node_id < graph.Size(); ++node_id) + if (graph.Degree(node_id) != deg[node_id]) return false; return true; } -// Checks if incident weights of nodes in G correspond to a given weight vector. -bool inc_w_check(const comdata::Graph &G, const std::vector &inc_w) { - if (G.Size() != inc_w.size()) return false; - for (uint32_t node_id = 0; node_id < G.Size(); ++node_id) - if (std::abs(G.IncidentWeight(node_id) - inc_w[node_id]) > 1e-6) +// Checks if incident weights of nodes in graph correspond to a given weight +// vector. +bool IncidentWeightCheck(const comdata::Graph &graph, + const std::vector &inc_w) { + if (graph.Size() != inc_w.size()) return false; + for (uint32_t node_id = 0; node_id < graph.Size(); ++node_id) + if (std::abs(graph.IncidentWeight(node_id) - inc_w[node_id]) > 1e-6) return false; return true; } -// Sets communities of nodes in G. Returns true on success. -bool set_communities(comdata::Graph *G, const std::vector &c) { - if (G->Size() != c.size()) return false; - for (uint32_t node_id = 0; node_id < G->Size(); ++node_id) - G->SetCommunity(node_id, c[node_id]); +// Sets communities of nodes in graph. Returns true on success. +bool SetCommunities(comdata::Graph *graph, const std::vector &c) { + if (graph->Size() != c.size()) return false; + for (uint32_t node_id = 0; node_id < graph->Size(); ++node_id) + graph->SetCommunity(node_id, c[node_id]); return true; } TEST(Graph, Constructor) { uint32_t nodes = 100; - comdata::Graph G(nodes); - ASSERT_EQ(G.Size(), nodes); + comdata::Graph graph(nodes); + ASSERT_EQ(graph.Size(), nodes); for (uint32_t node_id = 0; node_id < nodes; ++node_id) { - ASSERT_EQ(G.IncidentWeight(node_id), 0); - ASSERT_EQ(G.Community(node_id), node_id); + ASSERT_EQ(graph.IncidentWeight(node_id), 0); + ASSERT_EQ(graph.Community(node_id), node_id); } } TEST(Graph, Size) { - comdata::Graph G1 = GenRandomUnweightedGraph(0, 0); - comdata::Graph G2 = GenRandomUnweightedGraph(42, 41); - comdata::Graph G3 = GenRandomUnweightedGraph(100, 250); - ASSERT_EQ(G1.Size(), 0); - ASSERT_EQ(G2.Size(), 42); - ASSERT_EQ(G3.Size(), 100); + comdata::Graph graph1 = GenRandomUnweightedGraph(0, 0); + comdata::Graph graph2 = GenRandomUnweightedGraph(42, 41); + comdata::Graph graph3 = GenRandomUnweightedGraph(100, 250); + ASSERT_EQ(graph1.Size(), 0); + ASSERT_EQ(graph2.Size(), 42); + ASSERT_EQ(graph3.Size(), 100); } TEST(Graph, Communities) { - comdata::Graph G = GenRandomUnweightedGraph(100, 250); + comdata::Graph graph = GenRandomUnweightedGraph(100, 250); - for (int i = 0; i < 100; ++i) G.SetCommunity(i, i % 5); - for (int i = 0; i < 100; ++i) ASSERT_EQ(G.Community(i), i % 5); + for (int i = 0; i < 100; ++i) graph.SetCommunity(i, i % 5); + for (int i = 0; i < 100; ++i) ASSERT_EQ(graph.Community(i), i % 5); // Try to set communities on non-existing nodes - ASSERT_DEATH({ G.SetCommunity(100, 2); }, ""); - ASSERT_DEATH({ G.SetCommunity(150, 0); }, ""); + ASSERT_DEATH({ graph.SetCommunity(100, 2); }, ""); + ASSERT_DEATH({ graph.SetCommunity(150, 0); }, ""); // Try to get a the community of a non-existing node - ASSERT_DEATH({ G.Community(100); }, ""); - ASSERT_DEATH({ G.Community(150); }, ""); + ASSERT_DEATH({ graph.Community(100); }, ""); + ASSERT_DEATH({ graph.Community(150); }, ""); } TEST(Graph, CommunityNormalization) { // Communities are already normalized. - comdata::Graph G = GenRandomUnweightedGraph(5, 10); + comdata::Graph graph = GenRandomUnweightedGraph(5, 10); std::vector init_c = {0, 2, 1, 3, 4}; std::vector final_c = {0, 2, 1, 3, 4}; - ASSERT_TRUE(set_communities(&G, init_c)); - G.NormalizeCommunities(); - ASSERT_TRUE(community_check(G, final_c)); + ASSERT_TRUE(SetCommunities(&graph, init_c)); + graph.NormalizeCommunities(); + ASSERT_TRUE(CommunityCheck(graph, final_c)); // Each node in its own community. - G = GenRandomUnweightedGraph(5, 10); + graph = GenRandomUnweightedGraph(5, 10); init_c = {20, 30, 10, 40, 50}; final_c = {1, 2, 0, 3, 4}; - ASSERT_TRUE(set_communities(&G, init_c)); - G.NormalizeCommunities(); - ASSERT_TRUE(community_check(G, final_c)); + ASSERT_TRUE(SetCommunities(&graph, init_c)); + graph.NormalizeCommunities(); + ASSERT_TRUE(CommunityCheck(graph, final_c)); // Multiple nodes in the same community - G = GenRandomUnweightedGraph(7, 10); + graph = GenRandomUnweightedGraph(7, 10); init_c = {13, 99, 13, 13, 1, 99, 1}; final_c = {1, 2, 1, 1, 0, 2, 0}; - ASSERT_TRUE(set_communities(&G, init_c)); - G.NormalizeCommunities(); - ASSERT_TRUE(community_check(G, final_c)); + ASSERT_TRUE(SetCommunities(&graph, init_c)); + graph.NormalizeCommunities(); + ASSERT_TRUE(CommunityCheck(graph, final_c)); } TEST(Graph, AddEdge) { - comdata::Graph G = GenRandomUnweightedGraph(5, 0); + comdata::Graph graph = GenRandomUnweightedGraph(5, 0); // Node out of bounds. - ASSERT_DEATH({ G.AddEdge(1, 5, 7); }, ""); + ASSERT_DEATH({ graph.AddEdge(1, 5, 7); }, ""); // Repeated edge - G.AddEdge(1, 2, 1); - ASSERT_DEATH({ G.AddEdge(1, 2, 7); }, ""); + graph.AddEdge(1, 2, 1); + ASSERT_DEATH({ graph.AddEdge(1, 2, 7); }, ""); // Non-positive edge weight - ASSERT_DEATH({ G.AddEdge(2, 3, -7); }, ""); - ASSERT_DEATH({ G.AddEdge(3, 4, 0); }, ""); + ASSERT_DEATH({ graph.AddEdge(2, 3, -7); }, ""); + ASSERT_DEATH({ graph.AddEdge(3, 4, 0); }, ""); } TEST(Graph, Degrees) { // Graph without edges - comdata::Graph G = GenRandomUnweightedGraph(5, 0); + comdata::Graph graph = GenRandomUnweightedGraph(5, 0); std::vector deg = {0, 0, 0, 0, 0}; - ASSERT_TRUE(degree_check(G, deg)); + ASSERT_TRUE(DegreeCheck(graph, deg)); // Chain // (0)--(1)--(2)--(3)--(4) - G = BuildGraph(5, {{0, 1, 1}, + graph = BuildGraph(5, {{0, 1, 1}, {1, 2, 1}, {2, 3, 1}, {3, 4, 1}}); deg = {1, 2, 2, 2, 1}; - ASSERT_TRUE(degree_check(G, deg)); + ASSERT_TRUE(DegreeCheck(graph, deg)); // Tree // (0)--(3) @@ -135,21 +140,21 @@ TEST(Graph, Degrees) { // (1) (2) // | / \ // (4) (5) (6) - G = BuildGraph(7, {{0, 1, 1}, + graph = BuildGraph(7, {{0, 1, 1}, {0, 2, 1}, {0, 3, 1}, {1, 4, 1}, {2, 5, 1}, {2, 6, 1}}); deg = {3, 2, 3, 1, 1, 1, 1}; - ASSERT_TRUE(degree_check(G, deg)); + ASSERT_TRUE(DegreeCheck(graph, deg)); // Graph without self-loops // (0)--(1) // | \ | \ // | \ | \ // (2)--(3)-(4) - G = BuildGraph(5, {{0, 1, 1}, + graph = BuildGraph(5, {{0, 1, 1}, {0, 2, 1}, {0, 3, 1}, {1, 3, 1}, @@ -157,14 +162,14 @@ TEST(Graph, Degrees) { {2, 3, 1}, {3, 4, 1}}); deg = {3, 3, 2, 4, 2}; - ASSERT_TRUE(degree_check(G, deg)); + ASSERT_TRUE(DegreeCheck(graph, deg)); // Graph with self loop [*nodes have self loops] // (0)--(1*) // | \ | \ // | \ | \ // (2*)--(3)-(4*) - G = BuildGraph(5, {{0, 1, 1}, + graph = BuildGraph(5, {{0, 1, 1}, {0, 2, 1}, {0, 3, 1}, {1, 3, 1}, @@ -175,29 +180,29 @@ TEST(Graph, Degrees) { {2, 2, 2}, {4, 4, 4}}); deg = {3, 4, 3, 4, 3}; - ASSERT_TRUE(degree_check(G, deg)); + ASSERT_TRUE(DegreeCheck(graph, deg)); // Try to get degree of non-existing nodes - ASSERT_DEATH({ G.Degree(5); }, ""); - ASSERT_DEATH({ G.Degree(100); }, ""); + ASSERT_DEATH({ graph.Degree(5); }, ""); + ASSERT_DEATH({ graph.Degree(100); }, ""); } TEST(Graph, Weights) { // Graph without edges - comdata::Graph G = GenRandomUnweightedGraph(5, 0); + comdata::Graph graph = GenRandomUnweightedGraph(5, 0); std::vector inc_w = {0, 0, 0, 0, 0}; - ASSERT_TRUE(inc_w_check(G, inc_w)); - ASSERT_EQ(G.TotalWeight(), 0); + ASSERT_TRUE(IncidentWeightCheck(graph, inc_w)); + ASSERT_EQ(graph.TotalWeight(), 0); // Chain // (0)--(1)--(2)--(3)--(4) - G = BuildGraph(5, {{0, 1, 0.1}, + graph = BuildGraph(5, {{0, 1, 0.1}, {1, 2, 0.5}, {2, 3, 2.3}, {3, 4, 4.2}}); inc_w = {0.1, 0.6, 2.8, 6.5, 4.2}; - ASSERT_TRUE(inc_w_check(G, inc_w)); - ASSERT_NEAR(G.TotalWeight(), 7.1, 1e-6); + ASSERT_TRUE(IncidentWeightCheck(graph, inc_w)); + ASSERT_NEAR(graph.TotalWeight(), 7.1, 1e-6); // Tree // (0)--(3) @@ -205,22 +210,22 @@ TEST(Graph, Weights) { // (1) (2) // | / \ // (4) (5) (6) - G = BuildGraph(7, {{0, 1, 1.3}, + graph = BuildGraph(7, {{0, 1, 1.3}, {0, 2, 0.2}, {0, 3, 1}, {1, 4, 3.2}, {2, 5, 4.2}, {2, 6, 0.7}}); inc_w = {2.5, 4.5, 5.1, 1, 3.2, 4.2, 0.7}; - ASSERT_TRUE(inc_w_check(G, inc_w)); - EXPECT_NEAR(G.TotalWeight(), 10.6, 1e-6); + ASSERT_TRUE(IncidentWeightCheck(graph, inc_w)); + EXPECT_NEAR(graph.TotalWeight(), 10.6, 1e-6); // Graph without self-loops // (0)--(1) // | \ | \ // | \ | \ // (2)--(3)-(4) - G = BuildGraph(5, {{0, 1, 0.1}, + graph = BuildGraph(5, {{0, 1, 0.1}, {0, 2, 0.2}, {0, 3, 0.3}, {1, 3, 0.4}, @@ -228,15 +233,15 @@ TEST(Graph, Weights) { {2, 3, 0.6}, {3, 4, 0.7}}); inc_w = {0.6, 1, 0.8, 2, 1.2}; - ASSERT_TRUE(inc_w_check(G, inc_w)); - EXPECT_NEAR(G.TotalWeight(), 2.8, 1e-6); + ASSERT_TRUE(IncidentWeightCheck(graph, inc_w)); + EXPECT_NEAR(graph.TotalWeight(), 2.8, 1e-6); // Graph with self loop [*nodes have self loops] // (0)--(1*) // | \ | \ // | \ | \ // (2*)--(3)-(4*) - G = BuildGraph(5, {{0, 1, 0.1}, + graph = BuildGraph(5, {{0, 1, 0.1}, {0, 2, 0.2}, {0, 3, 0.3}, {1, 3, 0.4}, @@ -247,28 +252,28 @@ TEST(Graph, Weights) { {2, 2, 0.9}, {4, 4, 1}}); inc_w = {0.6, 1.8, 1.7, 2, 2.2}; - ASSERT_TRUE(inc_w_check(G, inc_w)); - EXPECT_NEAR(G.TotalWeight(), 5.5, 1e-6); + ASSERT_TRUE(IncidentWeightCheck(graph, inc_w)); + EXPECT_NEAR(graph.TotalWeight(), 5.5, 1e-6); // Try to get incident weight of non-existing node - ASSERT_DEATH({ G.IncidentWeight(5); }, ""); - ASSERT_DEATH({ G.IncidentWeight(100); }, ""); + ASSERT_DEATH({ graph.IncidentWeight(5); }, ""); + ASSERT_DEATH({ graph.IncidentWeight(100); }, ""); } TEST(Graph, Modularity) { // Graph without edges - comdata::Graph G = GenRandomUnweightedGraph(5, 0); - ASSERT_EQ(G.Modularity(), 0); + comdata::Graph graph = GenRandomUnweightedGraph(5, 0); + ASSERT_EQ(graph.Modularity(), 0); // Chain // (0)--(1)--(2)--(3)--(4) - G = BuildGraph(5, {{0, 1, 0.1}, + graph = BuildGraph(5, {{0, 1, 0.1}, {1, 2, 0.5}, {2, 3, 2.3}, {3, 4, 4.2}}); std::vector c = {0, 1, 1, 2, 2}; - set_communities(&G, c); - EXPECT_NEAR(G.Modularity(), 0.37452886332076973, 1e-6); + SetCommunities(&graph, c); + EXPECT_NEAR(graph.Modularity(), 0.37452886332076973, 1e-6); // Tree // (0)--(3) @@ -276,22 +281,22 @@ TEST(Graph, Modularity) { // (1) (2) // | / \ // (4) (5) (6) - G = BuildGraph(7, {{0, 1, 1.3}, + graph = BuildGraph(7, {{0, 1, 1.3}, {0, 2, 0.2}, {0, 3, 1}, {1, 4, 3.2}, {2, 5, 4.2}, {2, 6, 0.7}}); c = {0, 0, 1, 0, 0, 1, 2}; - set_communities(&G, c); - EXPECT_NEAR(G.Modularity(), 0.6945087219651122, 1e-6); + SetCommunities(&graph, c); + EXPECT_NEAR(graph.Modularity(), 0.6945087219651122, 1e-6); // Graph without self-loops // (0)--(1) // | \ | \ // | \ | \ // (2)--(3)-(4) - G = BuildGraph(5, {{0, 1, 0.1}, + graph = BuildGraph(5, {{0, 1, 0.1}, {0, 2, 0.2}, {0, 3, 0.3}, {1, 3, 0.4}, @@ -299,15 +304,15 @@ TEST(Graph, Modularity) { {2, 3, 0.6}, {3, 4, 0.7}}); c = {0, 1, 1, 1, 1}; - set_communities(&G, c); - EXPECT_NEAR(G.Modularity(), 0.32653061224489793, 1e-6); + SetCommunities(&graph, c); + EXPECT_NEAR(graph.Modularity(), 0.32653061224489793, 1e-6); // Graph with self loop [*nodes have self loops] // (0)--(1*) // | \ | \ // | \ | \ // (2*)--(3)-(4*) - G = BuildGraph(5, {{0, 1, 0.1}, + graph = BuildGraph(5, {{0, 1, 0.1}, {0, 2, 0.2}, {0, 3, 0.3}, {1, 3, 0.4}, @@ -318,6 +323,6 @@ TEST(Graph, Modularity) { {2, 2, 0.9}, {4, 4, 1}}); c = {0, 0, 0, 0, 1}; - set_communities(&G, c); - EXPECT_NEAR(G.Modularity(), 0.2754545454545455, 1e-6); + SetCommunities(&graph, c); + EXPECT_NEAR(graph.Modularity(), 0.2754545454545455, 1e-6); } diff --git a/query_modules/louvain/test/unit/utils.hpp b/query_modules/louvain/test/unit/utils.hpp index 2fbb16123..f7fba53b2 100644 --- a/query_modules/louvain/test/unit/utils.hpp +++ b/query_modules/louvain/test/unit/utils.hpp @@ -7,21 +7,6 @@ #include "data_structures/graph.hpp" -/// This class is threadsafe -class Timer { - public: - Timer() : start_time_(std::chrono::steady_clock::now()) {} - - template > - TDuration Elapsed() const { - return std::chrono::duration_cast( - std::chrono::steady_clock::now() - start_time_); - } - - private: - std::chrono::steady_clock::time_point start_time_; -}; - /// Builds the graph from a given number of nodes and a list of edges. /// Nodes should be 0-indexed and each edge should be provided only once. comdata::Graph BuildGraph(