Skip to content

Commit

Permalink
wff with segment tree
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominik Rosch committed Jun 25, 2024
1 parent bcb6481 commit a0be11e
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 30 deletions.
9 changes: 6 additions & 3 deletions kaminpar-common/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@ class Random {

std::size_t
random_index(const std::size_t inclusive_lower_bound, const std::size_t exclusive_upper_bound) {
return std::uniform_int_distribution<std::size_t>(
inclusive_lower_bound, exclusive_upper_bound - 1
)(_generator);
return std::uniform_int_distribution<
std::size_t>(inclusive_lower_bound, exclusive_upper_bound - 1)(_generator);
}

double random_double() {
return _real_dist(_generator);
}

bool random_bool() {
Expand Down
3 changes: 2 additions & 1 deletion kaminpar-shm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ add_library(kaminpar_shm ${KAMINPAR_SHM_SOURCE_FILES}
coarsening/sparsification/EffectiveResistanceScore.cpp
coarsening/sparsification/WeightedForestFireScore.hpp
coarsening/sparsification/WeightedForestFireScore.cpp
coarsening/sparsification/FiniteRandomDistribution.h)
coarsening/sparsification/FiniteRandomDistribution.h
coarsening/sparsification/DistributionWithoutReplacement.h)
target_include_directories(kaminpar_shm PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../" ${JL_SHARE}/../../include/julia/)
target_link_libraries(kaminpar_shm PUBLIC kaminpar_common networkit ${JL_SHARE}/../../lib/libjulia.so)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#pragma once

#include "kaminpar-common/random.h"

namespace kaminpar::shm::sparsification {
template <typename Object> class DistributionWithoutReplacement {
public:
DistributionWithoutReplacement(std::vector<Object> objects, std::vector<double> values)
: objects(objects),
remaining_objects(values.size()) {
if (values.size() == 0)
return;

// size of a complete binary tree, where all values can be in the leaves
size_t size = 1;
while (size <= 2 * values.size()) {
size *= 2;
}
size -= 1;
segment_tree.resize(size, 0);

// initalize leafs
const size_t first_leaf = firstLeaf();
for (size_t leaf = first_leaf; leaf < first_leaf + values.size(); leaf++) {
segment_tree[leaf] = values[leaf - first_leaf];
}

// calculate sum of subtrees
for (size_t node = segment_tree.size() - 1; node != 0; node--) {
segment_tree[parent(node)] += segment_tree[node];
}
}

Object operator()() {
double r = Random::instance().random_double() * segment_tree[0];

size_t current_subtree = 0;
while (not isLeaf(current_subtree)) {
if (r <= segment_tree[leftChild(current_subtree)]) {
current_subtree = leftChild(current_subtree);
} else {
r -= segment_tree[leftChild(current_subtree)];
current_subtree = rightChild(current_subtree);
}
}

Object obj = to_object(current_subtree);
double value = segment_tree[current_subtree];

// delete
while (current_subtree != 0) {
segment_tree[current_subtree] -= value;
current_subtree = parent(current_subtree);
}
segment_tree[0] -= value;

remaining_objects--;
return obj;
}

size_t size() {
return remaining_objects;
}
bool empty() {
return remaining_objects == 0;
}

private:
bool isLeaf(size_t i) {
return i >= firstLeaf();
}
size_t parent(size_t i) {
return (i - 1) / 2;
}
size_t leftChild(size_t i) {
return 2 * i + 1;
}
size_t rightChild(size_t i) {
return 2 * i + 2;
}
size_t firstLeaf() {
return segment_tree.size() / 2;
}
Object to_object(size_t leaf) {
size_t index = leaf - firstLeaf();
return objects[index];
}
std::vector<double> segment_tree;
std::vector<Object> objects;
size_t remaining_objects;
};
} // namespace kaminpar::shm::sparsification
38 changes: 12 additions & 26 deletions kaminpar-shm/coarsening/sparsification/WeightedForestFireScore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <networkit/auxiliary/Parallel.hpp>
#include <networkit/graph/GraphTools.hpp>

#include "DistributionWithoutReplacement.h"
#include "FiniteRandomDistribution.h"

namespace kaminpar::shm::sparsification {
Expand All @@ -41,14 +42,17 @@ void WeightedForestFireScore::run() {
std::vector<bool> visited(G->upperNodeIdBound(), false);
activeNodes.push(GraphTools::randomNode(*G));

auto forwardNeighbors = [&](node u) {
std::vector<edgetriple> validEdges;
auto forwardNeighborDistribution = [&](node u) {
std::vector<std::pair<node, edgeid>> validEdges;
std::vector<edgeweight> weights;
for (count i = 0; i < G->degree(u); i++) {
auto [v, e] = G->getIthNeighborWithId(u, i);
auto weight = G->getIthNeighborWeight(u, i);
validEdges.emplace_back(v, e, weight);
if (visited[v])
continue;
weights.push_back(G->getIthNeighborWeight(u, i));
validEdges.emplace_back(v, e);
}
return validEdges;
return DistributionWithoutReplacement<std::pair<node, edgeid>>(validEdges, weights);
};

count localEdgesBurnt = 0;
Expand All @@ -57,40 +61,22 @@ void WeightedForestFireScore::run() {
node v = activeNodes.front();
activeNodes.pop();

auto validNeighbors = forwardNeighbors(v);


edgeweight validNeighboursWeightSum = std::accumulate(
validNeighbors.begin(),
validNeighbors.end(),
0,
[](edgeweight accumulator, edgetriple edge) { return accumulator + std::get<2>(edge); }
);
auto validNeighborDistribution = forwardNeighborDistribution(v);

while (true) {
double q = Aux::Random::real(1.0);
if (q > pf || validNeighbors.empty()) {
if (q > pf || validNeighborDistribution.empty()) {
break;
}
edgeweight r = Aux::Random::real(validNeighboursWeightSum);
count index = 0;
edgeweight prefix_sum = std::get<2>(validNeighbors[0]);
while ((prefix_sum += std::get<2>(validNeighbors[index])) < r) {
index++;
}

{ // mark node as visited, burn edge
auto [x, eid, weight] = validNeighbors[index];
auto [x, eid] = validNeighborDistribution();
activeNodes.push(x);
#pragma omp atomic
burnt[eid]++;
localEdgesBurnt++;
visited[x] = true;
validNeighboursWeightSum -= weight;
}

validNeighbors[index] = validNeighbors.back();
validNeighbors.pop_back();
}
}

Expand Down

0 comments on commit a0be11e

Please sign in to comment.