Skip to content

Commit

Permalink
- fixing bug in the use of get_current_is_weight() after calling rest…
Browse files Browse the repository at this point in the history
…ore_global_best_solution(): latter moves global_status to status but get_current_is_weight uses global_status; fixed it by introducing public method get_is_weight() and making get_current_is_weight() private

- fixing bug in fold reductions; they added the wrong solution weight to is_weight
  • Loading branch information
jabo17 committed Aug 1, 2024
1 parent 2b2f633 commit 8a4d95d
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 31 deletions.
2 changes: 1 addition & 1 deletion wmis/app/branch_reduce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ int main(int argn, char **argv) {

branch_and_reduce_algorithm reducer(G, mis_config);
reducer.run_branch_reduce();
NodeWeight MWIS_weight = reducer.get_current_is_weight();
NodeWeight MWIS_weight = reducer.get_is_weight();

auto end = std::chrono::system_clock::now();

Expand Down
2 changes: 1 addition & 1 deletion wmis/app/weighted_ls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ NodeWeight perform_reduction(std::unique_ptr<branch_and_reduce_algorithm>& reduc
exit(1);
}

NodeWeight is_weight = reducer->get_current_is_weight();
NodeWeight is_weight = reducer->get_is_weight();

return is_weight;
}
Expand Down
15 changes: 10 additions & 5 deletions wmis/lib/mis/kernel/branch_and_reduce_algorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,19 +728,19 @@ void branch_and_reduce_algorithm::restore_best_local_solution() {

void branch_and_reduce_algorithm::restore_best_global_solution() {
status = std::move(global_status);
status.modified_queue.pop_back();
status.modified_queue.pop_back();

while (!status.modified_queue.empty()) {
NodeID node = status.modified_queue.back();
status.modified_queue.pop_back();
status.modified_queue.pop_back();

if (status.node_status[node] == IS_status::folded) {
auto type = status.folded_queue.back();
status.folded_queue.pop_back();
status.reductions[global_reduction_map[type]]->apply(this);
status.folded_queue.pop_back();
status.reductions[global_reduction_map[type]]->apply(this);
}
else {
status.graph.restore_node(node);
status.graph.restore_node(node);
}
}
}
Expand All @@ -749,6 +749,11 @@ NodeWeight branch_and_reduce_algorithm::get_current_is_weight() const {
return global_status.is_weight + global_status.reduction_offset;
}

NodeWeight branch_and_reduce_algorithm::get_is_weight() const {
// after restoring global best solution, global status was moved to status
return status.is_weight + status.reduction_offset;
}

void branch_and_reduce_algorithm::build_global_graph_access() {
global_mapping.resize(global_status.remaining_nodes, 0);
std::swap(status, global_status);
Expand Down
4 changes: 3 additions & 1 deletion wmis/lib/mis/kernel/branch_and_reduce_algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ class branch_and_reduce_algorithm {
void disable_cout();
void enable_cout();

NodeWeight get_current_is_weight() const;

public:
branch_and_reduce_algorithm(graph_access& G, const MISConfig& config, bool called_from_fold = false);

Expand All @@ -203,7 +205,7 @@ class branch_and_reduce_algorithm {
static size_t run_ils(const MISConfig& config, graph_access& G, sized_vector<NodeID>& tmp_buffer, size_t max_swaps);
static void greedy_initial_is(graph_access& G, sized_vector<NodeID>& tmp_buffer);

NodeWeight get_current_is_weight() const;
NodeWeight get_is_weight() const;
void reverse_reduction(graph_access & G, graph_access & reduced_G, std::vector<NodeID> & reverse_mapping);
void apply_branch_reduce_solution(graph_access & G);

Expand Down
66 changes: 43 additions & 23 deletions wmis/lib/mis/kernel/reductions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,24 +396,36 @@ void fold2_reduction::restore(branch_and_reduce_algorithm* br_alg) {
}

void fold2_reduction::apply(branch_and_reduce_algorithm* br_alg) {
auto& status = br_alg->status;
auto nodes = restore_vec.back().nodes;
auto main_status = status.node_status[nodes.main];
restore(br_alg);

if (main_status == IS_status::included) {
status.node_status[nodes.main] = IS_status::excluded;
status.node_status[nodes.rest[0]] = IS_status::included;
status.node_status[nodes.rest[1]] = IS_status::included;

status.is_weight += status.weights[nodes.rest[0]] + status.weights[nodes.rest[1]];
} else {
status.node_status[nodes.main] = IS_status::included;
status.node_status[nodes.rest[0]] = IS_status::excluded;
status.node_status[nodes.rest[1]] = IS_status::excluded;

status.is_weight += status.weights[nodes.main];
}
#ifndef NDEBUG
NodeWeight previous_is_weight = br_alg->status.is_weight + br_alg->status.reduction_offset;
#endif

auto& status = br_alg->status;
auto nodes = restore_vec.back().nodes;
auto main_status = status.node_status[nodes.main];
restore(br_alg);

if (main_status == IS_status::included) {
status.node_status[nodes.main] = IS_status::excluded;
status.node_status[nodes.rest[0]] = IS_status::included;
status.node_status[nodes.rest[1]] = IS_status::included;

// weight of folded vertex was added to is_weight while reducing:
// status.is_weight += status.weights[nodes.rest[0]] + status.weights[nodes.rest[1]] - status.weights[nodes.main]
// only need to add status.weights[nodes.main] to is_weight
status.is_weight += status.weights[nodes.main];
// old: status.is_weight += status.weights[nodes.rest[0]] + status.weights[nodes.rest[1]];
} else {
status.node_status[nodes.main] = IS_status::included;
status.node_status[nodes.rest[0]] = IS_status::excluded;
status.node_status[nodes.rest[1]] = IS_status::excluded;

status.is_weight += status.weights[nodes.main];
}
#ifndef NDEBUG
// invariant that has to hold
ASSERT_TRUE(br_alg->status.is_weight + br_alg->status.reduction_offset == previous_is_weight);
#endif
}

bool clique_reduction::reduce(branch_and_reduce_algorithm* br_alg) {
Expand Down Expand Up @@ -780,7 +792,7 @@ bool generalized_neighborhood_reduction::reduce(branch_and_reduce_algorithm* br_
continue;
}

if (status.weights[v] >= neighborhood_br_alg.get_current_is_weight())
if (status.weights[v] >= neighborhood_br_alg.get_is_weight())
br_alg->set(v, IS_status::included);
}
}
Expand Down Expand Up @@ -845,7 +857,7 @@ bool generalized_fold_reduction::reduce(branch_and_reduce_algorithm* br_alg) {
continue;
}

NodeWeight MWIS_weight = neighborhood_br_alg.get_current_is_weight();
NodeWeight MWIS_weight = neighborhood_br_alg.get_is_weight();
NodeWeight min_MWIS_neighbor_weight = std::numeric_limits<NodeWeight>::max();

if (status.weights[v] >= MWIS_weight) {
Expand Down Expand Up @@ -889,7 +901,7 @@ bool generalized_fold_reduction::reduce(branch_and_reduce_algorithm* br_alg) {
std::cerr << "%generalized_fold_reduction br_call loop time out" << std::endl;
check_failed = true;
}
else if (neighborhood_br_alg.get_current_is_weight() >= status.weights[v]) {
else if (neighborhood_br_alg.get_is_weight() >= status.weights[v]) {
check_failed = true;
}

Expand Down Expand Up @@ -942,7 +954,7 @@ bool generalized_fold_reduction::reduce(branch_and_reduce_algorithm* br_alg) {
}
else {
// if the weight of every MWIS in N(v) which contains "node" is smaller than w(v) then we can remove "node"
remove_node = neighborhood_br_alg.get_current_is_weight() + status.weights[node] <= status.weights[v];
remove_node = neighborhood_br_alg.get_is_weight() + status.weights[node] <= status.weights[v];
}

for (const NodeID neighbor : status.graph[node]) {
Expand Down Expand Up @@ -1058,6 +1070,9 @@ void generalized_fold_reduction::restore(branch_and_reduce_algorithm* br_alg) {
}

void generalized_fold_reduction::apply(branch_and_reduce_algorithm* br_alg) {
#ifndef NDEBUG
NodeWeight previous_is_weight = br_alg->status.is_weight + br_alg->status.reduction_offset;
#endif
auto& status = br_alg->status;
auto nodes = restore_vec.back().nodes;
auto MWIS_weight = restore_vec.back().MWIS_weight;
Expand All @@ -1071,7 +1086,8 @@ void generalized_fold_reduction::apply(branch_and_reduce_algorithm* br_alg) {
status.node_status[node] = IS_status::included;
}

status.is_weight += MWIS_weight;
status.is_weight += status.weights[nodes.main]; // for details see fold2::apply
// wrong: status.is_weight += MWIS_weight;
} else {
status.node_status[nodes.main] = IS_status::included;

Expand All @@ -1081,4 +1097,8 @@ void generalized_fold_reduction::apply(branch_and_reduce_algorithm* br_alg) {

status.is_weight += status.weights[nodes.main];
}
#ifndef NDEBUG
// invariant that has to hold
ASSERT_TRUE(br_alg->status.is_weight + br_alg->status.reduction_offset == previous_is_weight);
#endif
}

0 comments on commit 8a4d95d

Please sign in to comment.