Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions include/algorithm/partition.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef PROJECT_X_ALGORITHM_PARTITION_HPP_
#define PROJECT_X_ALGORITHM_PARTITION_HPP_

#include "graph/forward_star.hpp"

#include <cstdint>
#include <vector>

namespace project_x {
namespace algorithm {

// recursive bisection of a forward star graph, following a fixed balance
// constraint for cells
class Partition {
public:
using PartitionID = std::uint64_t;

Partition(ForwardStar const &graph, std::uint32_t const max_cell_size);

private:
// compute a set of base-cells
std::vector<PartitionID> compute_cells(std::uint32_t const max_cell_size);

graph::ForwardStar const &graph;
};

} // namespace algorithm
} // namespace project_x

#endif // PROJECT_X_ALGORITHM_PARTITION_HPP_
27 changes: 27 additions & 0 deletions include/algorithm/union_find.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef PROJECT_X_ALGORITHM_UNION_FIND_HPP_
#define PROJECT_X_ALGORITHM_UNION_FIND_HPP_

#include <cstdint>
#include <vector>

namespace project_x {
namespace algorithm {
// implementaiton of the classic union-find algorithm, allowing combination of
// entries into groups and finding representatives of these groups
class UnionFind {
public:
UnionFind(std::uint64_t const universe_size);

// combine two groups into a single one
void unite(std::uint64_t const lhs, std::uint64_t const rhs);

// find the representative of a group
std::uint64_t find(std::uint64_t rep);

private:
std::vector<std::int64_t> reps;
};
} // namespace algorithm
} // namespace project_x

#endif // PROJECT_X_ALGORITHM_UNION_FIND_HPP_
3 changes: 2 additions & 1 deletion src/algorithm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
set (algorithm_SOURCES
"scc.cpp")
"scc.cpp"
"union_find.cpp")

add_library(Xalgorithm STATIC
${algorithm_SOURCES})
Expand Down
33 changes: 33 additions & 0 deletions src/algorithm/partition.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "algorithm/partition.hpp"
#include "algorithm/union_find.hpp"
#include "graph/id.hpp"

#include <queue>

namespace project_x {
namespace algorithm {

namespace {
std::vector<NodeID> close_nodes(graph::ForwardStar const &graph,
NodeID const to_node,
std::uint32_t node_count) {
std::vector<NodeID> nodes;
nodes.push_back(to_node);

return nodes;
}
} // namespace

Partition::Partition(graph::ForwardStar const &graph,
std::uint32_t const max_cell_size)
: graph(graph) {
auto cells = compute_cells(max_cell_size);
}

std::vector<std::uint32_t>
Partition::compute_cells(std::uint32_t max_cell_size) {
algorithm::UnionFind uf(graph.number_of_nodes());
}

} // namespace algorithm
} // namespace project_x
43 changes: 43 additions & 0 deletions src/algorithm/union_find.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "algorithm/union_find.hpp"

#include <algorithm>

namespace project_x {
namespace algorithm {

UnionFind::UnionFind(std::uint64_t const universe_size)
: reps(universe_size, -1) {}

void UnionFind::unite(std::uint64_t const lhs, std::uint64_t const rhs) {
// union by size
auto const lhs_rep = find(lhs);
auto const rhs_rep = find(rhs);

if (lhs_rep == rhs_rep)
return;

auto const lhs_size = std::abs(reps[lhs_rep]);
auto const rhs_size = std::abs(reps[rhs_rep]);

if (lhs_size < rhs_size) {
reps[lhs_rep] -= rhs_size;
reps[rhs_rep] = lhs_rep;
} else {
reps[rhs_rep] -= lhs_size;
reps[lhs_rep] = rhs_rep;
}
}

// find the representative of a group
std::uint64_t UnionFind::find(std::uint64_t rep) {
if (reps[rep] < 0)
return rep;
else {
// path compression
reps[rep] = find(reps[rep]);
return reps[rep];
}
}

} // namespace algorithm
} // namespace project_x
1 change: 1 addition & 0 deletions test/algorithm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ set(testINCLUDES

add_unit_test(scc scc.cpp "${testLIBS}" "${testINCLUDES}")
add_unit_test(dijkstra dijkstra.cpp "${testLIBS}" "${testINCLUDES}")
add_unit_test(union_find union_find.cpp "${testLIBS}" "${testINCLUDES}")
36 changes: 36 additions & 0 deletions test/algorithm/union_find.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "algorithm/union_find.hpp"

// make sure we get a new main function here
#define BOOST_TEST_MODULE UnionFind
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

using namespace project_x;

// test a construction of an undirected graph from a set of edges
BOOST_AUTO_TEST_CASE(uf_algo) {
algorithm::UnionFind uf(10);
BOOST_CHECK_EQUAL(uf.find(0), 0);
BOOST_CHECK_EQUAL(uf.find(1), 1);
BOOST_CHECK_EQUAL(uf.find(2), 2);
BOOST_CHECK_EQUAL(uf.find(3), 3);
BOOST_CHECK_EQUAL(uf.find(4), 4);
BOOST_CHECK_EQUAL(uf.find(5), 5);
BOOST_CHECK_EQUAL(uf.find(6), 6);
BOOST_CHECK_EQUAL(uf.find(7), 7);
BOOST_CHECK_EQUAL(uf.find(8), 8);
BOOST_CHECK_EQUAL(uf.find(9), 9);

uf.unite(0, 1);
uf.unite(0, 2);

BOOST_CHECK_EQUAL(uf.find(1), uf.find(2));

uf.unite(4, 4);
BOOST_CHECK(uf.find(4) != uf.find(0));
uf.unite(uf.find(0), uf.find(5));
BOOST_CHECK(uf.find(4) != uf.find(5));
BOOST_CHECK_EQUAL(uf.find(0), uf.find(5));
uf.unite(uf.find(6), uf.find(0));
BOOST_CHECK_EQUAL(uf.find(6), uf.find(5));
}