Skip to content

Commit

Permalink
Merge pull request #1123 from PetholzA/feature/20230825_gtests_centra…
Browse files Browse the repository at this point in the history
…lity

gtests: adds centrality tests
  • Loading branch information
fabratu committed Oct 18, 2023
2 parents 07d02ea + 9d25ed6 commit edbe47f
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 42 deletions.
4 changes: 2 additions & 2 deletions include/networkit/centrality/Sfigality.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class Sfigality : public Centrality {
void run() override;

/**
* Not implemented.
* The maximum sfigality is 1, when all neighbors of a node have a higher degree.
* Returns the node that has the most neighbours with a higher degree than itself (max
* Sfigality).
*/
double maximum() override;
};
Expand Down
7 changes: 3 additions & 4 deletions include/networkit/centrality/SpanningEdgeCentrality.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,12 @@ class SpanningEdgeCentrality : public Centrality {
void runParallelApproximation();

/**
* Only used by benchmarking. Computes an approximation by projection and solving Laplacian
* systems. Measures the time needed to compute the approximation and writes the problem vectors
* to the directory of the graph specified by @a graphPath.
* This method is deprecated and will not be supported in future releases.
* Use runApproximation() instead.
* @param directory
* @return Elapsed time in milliseconds.
*/
uint64_t runApproximationAndWriteVectors(const std::string &graphPath);
uint64_t TLX_DEPRECATED(runApproximationAndWriteVectors(const std::string &graphPath));

/**
* @return The elapsed time to setup the solver in milliseconds.
Expand Down
4 changes: 2 additions & 2 deletions networkit/cpp/centrality/Sfigality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ void Sfigality::run() {
}

double Sfigality::maximum() {
throw std::runtime_error("Not Implemented");
return G.isEmpty() ? 0. : static_cast<double>(G.numberOfNodes() - 1);
assureFinished();
return *std::max_element(scoreData.begin(), scoreData.end());
}

} /* namespace NetworKit */
37 changes: 3 additions & 34 deletions networkit/cpp/centrality/SpanningEdgeCentrality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,43 +143,12 @@ void SpanningEdgeCentrality::runParallelApproximation() {
}

uint64_t SpanningEdgeCentrality::runApproximationAndWriteVectors(const std::string &) {
WARN("SpanningEdgeCentrality::runApproximationAndWriteVectors should not be used and will be "
"deprecated in the future.");
Aux::Timer t;
const count n = G.numberOfNodes();
const count m = G.numberOfEdges();
const double epsilon2 = tol * tol;
const count k = std::ceil(std::log(n)) / epsilon2;
double randTab[3] = {1 / std::sqrt(k), -1 / std::sqrt(k)};
Vector solution(n);
scoreData.clear();
scoreData.resize(m, 0.0);

t.start();
for (index i = 0; i < k; ++i) {
Vector rhs(n, 0.0);

// rhs(v) = \sum_e=1 ^m q(e) * B(e, v)
// = +/- q(e)
G.forEdges([&](node u, node v) {
double r = randTab[Aux::Random::integer(1)];
if (u < v) {
rhs[u] += r;
rhs[v] -= r;
} else {
rhs[u] -= r;
rhs[v] += r;
}
});

lamg.solve(rhs, solution);

G.forEdges([&](node u, node v, edgeid e) {
double diff = solution[u] - solution[v];
scoreData[e] += diff * diff; // TODO: fix weighted case!
});
}
runApproximation();
t.stop();
hasRun = true;

return t.elapsedMilliseconds();
}

Expand Down
137 changes: 137 additions & 0 deletions networkit/cpp/centrality/test/CentralityGTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,13 @@
#include <networkit/centrality/KatzCentrality.hpp>
#include <networkit/centrality/LaplacianCentrality.hpp>
#include <networkit/centrality/LocalClusteringCoefficient.hpp>
#include <networkit/centrality/LocalPartitionCoverage.hpp>
#include <networkit/centrality/LocalSquareClusteringCoefficient.hpp>
#include <networkit/centrality/PageRank.hpp>
#include <networkit/centrality/PermanenceCentrality.hpp>
#include <networkit/centrality/Sfigality.hpp>
#include <networkit/centrality/SpanningEdgeCentrality.hpp>
#include <networkit/community/ClusteringGenerator.hpp>
#include <networkit/components/ConnectedComponents.hpp>
#include <networkit/distance/Dijkstra.hpp>
#include <networkit/generators/DorogovtsevMendesGenerator.hpp>
Expand Down Expand Up @@ -774,6 +777,139 @@ TEST_F(CentralityGTest, testApproxClosenessCentralityOnToyGraph) {
EXPECT_NEAR(0.2, maximum2, tol);
}

TEST_F(CentralityGTest, testApproxClosenessCentralityOnDirectedToyGraph) {
/* Graph:
0 -> 3
^ /
\ /
2 5
/ \ /
1 4
*/
Graph G(6, false, true);

G.addEdge(0, 3);
G.addEdge(2, 0);
G.addEdge(1, 2);
G.addEdge(2, 1);
G.addEdge(3, 2);
G.addEdge(2, 3);
G.addEdge(4, 2);
G.addEdge(2, 4);
G.addEdge(4, 5);
G.addEdge(5, 4);

ApproxCloseness acc(G, 6, 0.1, true);
acc.run();
std::vector<double> cc = acc.scores();
double tol = 0.01;

EXPECT_NEAR(acc.maximum(), 0.2, tol);
EXPECT_NEAR(cc[0], 0.38, tol);
EXPECT_NEAR(cc[1], 0.50, tol);
EXPECT_NEAR(cc[2], 0.83, tol);
EXPECT_NEAR(cc[3], 0.50, tol);
EXPECT_NEAR(cc[4], 0.62, tol);
EXPECT_NEAR(cc[5], 0.41, tol);
}

TEST_F(CentralityGTest, testBetweennessMaximum) {
/* Graph:
0 3
\ / \
2 5
/ \ /
1 4
*/
Graph G(6);
G.addEdge(0, 2);
G.addEdge(1, 2);
G.addEdge(2, 3);
G.addEdge(2, 4);
G.addEdge(3, 5);
G.addEdge(4, 5);
G.indexEdges();

Betweenness bet(G, false, false);
bet.run();
EXPECT_EQ(bet.maximum(), 10);
EXPECT_NEAR(bet.centralization(), 1.79, 0.01);
}

TEST_F(CentralityGTest, testBetweennessMaximumNormalized) {
/* Graph:
0 3
\ / \
2 5
/ \ /
1 4
*/
Graph G(6);
G.addEdge(0, 2);
G.addEdge(1, 2);
G.addEdge(2, 3);
G.addEdge(2, 4);
G.addEdge(3, 5);
G.addEdge(4, 5);
G.indexEdges();

Betweenness betNormalized(G, true, true);
betNormalized.run();
EXPECT_EQ(betNormalized.maximum(), 1);
EXPECT_NEAR(betNormalized.centralization(), 0.69, 0.01);
}

TEST_F(CentralityGTest, testLocalPartitionCoverage) {
/* Graph:
0 3
\ / \
2 5
/ \ /
1 4
*/
Graph G(6);

G.addEdge(0, 2);
G.addEdge(1, 2);
G.addEdge(2, 3);
G.addEdge(2, 4);
G.addEdge(3, 5);
G.addEdge(4, 5);

ClusteringGenerator clustGen;
Partition P = clustGen.makeContinuousBalancedClustering(G, 3);

LocalPartitionCoverage LPC(G, P);
LPC.run();
EXPECT_EQ(LPC.maximum(), 1);
EXPECT_NEAR(LPC.centralization(), 0.29, 0.01);
}

TEST_F(CentralityGTest, testSfigality) {
/* Graph:
0 3
\ / \
2 5
/ \ /
1 4
*/
Graph G(6);
G.addEdge(0, 2);
G.addEdge(1, 2);
G.addEdge(2, 3);
G.addEdge(2, 4);
G.addEdge(3, 5);
G.addEdge(4, 5);

Sfigality sf(G);
sf.run();
auto res = sf.scores();
vector<double> expectedRes = {1, 1, 0, 0.5, 0.5, 0};
for (index i = 0; i < res.size(); ++i)
EXPECT_EQ(res[i], expectedRes[i]);
EXPECT_EQ(sf.maximum(), 1);
}

TEST_F(CentralityGTest, testEdgeBetweennessCentrality) {
/* Graph:
0 3
Expand Down Expand Up @@ -1909,6 +2045,7 @@ TEST_P(CentralityGTest, testDegreeCentrality) {

DegreeCentrality dc(g, false, true, false);
dc.run();
EXPECT_EQ(dc.maximum(), 8);

if (isDirected()) {
std::array<int, 8> expectedResults{{2, 1, 3, 1, 1, 3, 0, 1}};
Expand Down

0 comments on commit edbe47f

Please sign in to comment.