48 const std::vector<int>& stick_weights,
50 dimension_1_ = dimension_1;
51 dimension_2_ = dimension_2;
53 std::size_t stick_count =
static_cast<std::size_t
>(dimension_1) * dimension_2;
55 weight_per_rank_.assign(
static_cast<std::size_t
>(number_of_ranks_), 0);
68 std::vector<StickPair> pairs;
69 pairs.reserve(stick_count);
70 std::vector<bool> taken(stick_count,
false);
71 for (
int first = 0; first < dimension_1; ++first) {
72 for (
int second = 0; second < dimension_2; ++second) {
73 std::size_t index = stick_index(first, second);
74 if (taken[index] || stick_weights[index] == 0) {
77 int mirror_first = (dimension_1 - first) % dimension_1;
78 int mirror_second = (dimension_2 - second) % dimension_2;
79 std::size_t mirror_index = stick_index(mirror_first, mirror_second);
81 long long weight = stick_weights[index];
82 if (mirror_index != index) {
83 taken[mirror_index] =
true;
84 weight += stick_weights[mirror_index];
86 pairs.push_back({
static_cast<int>(index),
static_cast<int>(mirror_index), weight});
95 std::sort(pairs.begin(), pairs.end(), [](
const StickPair& left,
const StickPair& right) {
96 if (left.weight != right.weight) {
97 return left.weight > right.weight;
99 return left.first_index < right.first_index;
101 for (
const auto& pair : pairs) {
103 for (
int rank = 1; rank < number_of_ranks_; ++rank) {
104 if (weight_per_rank_[
static_cast<std::size_t
>(rank)] <
105 weight_per_rank_[
static_cast<std::size_t
>(target)]) {
109 owner_[
static_cast<std::size_t
>(pair.first_index)] = target;
110 owner_[
static_cast<std::size_t
>(pair.second_index)] = target;
111 weight_per_rank_[
static_cast<std::size_t
>(target)] += pair.weight;