Skip to content

Commit 147f3a2

Browse files
Merge pull request #40 from jabo17/fixing_wmis_bnr_errors
fix two bugs in weighted branch and reduce
2 parents 0a78668 + 8a4d95d commit 147f3a2

File tree

5 files changed

+58
-31
lines changed

5 files changed

+58
-31
lines changed

wmis/app/branch_reduce.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ int main(int argn, char **argv) {
9393

9494
branch_and_reduce_algorithm reducer(G, mis_config);
9595
reducer.run_branch_reduce();
96-
NodeWeight MWIS_weight = reducer.get_current_is_weight();
96+
NodeWeight MWIS_weight = reducer.get_is_weight();
9797

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

wmis/app/weighted_ls.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ NodeWeight perform_reduction(std::unique_ptr<branch_and_reduce_algorithm>& reduc
8181
exit(1);
8282
}
8383

84-
NodeWeight is_weight = reducer->get_current_is_weight();
84+
NodeWeight is_weight = reducer->get_is_weight();
8585

8686
return is_weight;
8787
}

wmis/lib/mis/kernel/branch_and_reduce_algorithm.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -728,19 +728,19 @@ void branch_and_reduce_algorithm::restore_best_local_solution() {
728728

729729
void branch_and_reduce_algorithm::restore_best_global_solution() {
730730
status = std::move(global_status);
731-
status.modified_queue.pop_back();
731+
status.modified_queue.pop_back();
732732

733733
while (!status.modified_queue.empty()) {
734734
NodeID node = status.modified_queue.back();
735-
status.modified_queue.pop_back();
735+
status.modified_queue.pop_back();
736736

737737
if (status.node_status[node] == IS_status::folded) {
738738
auto type = status.folded_queue.back();
739-
status.folded_queue.pop_back();
740-
status.reductions[global_reduction_map[type]]->apply(this);
739+
status.folded_queue.pop_back();
740+
status.reductions[global_reduction_map[type]]->apply(this);
741741
}
742742
else {
743-
status.graph.restore_node(node);
743+
status.graph.restore_node(node);
744744
}
745745
}
746746
}
@@ -749,6 +749,11 @@ NodeWeight branch_and_reduce_algorithm::get_current_is_weight() const {
749749
return global_status.is_weight + global_status.reduction_offset;
750750
}
751751

752+
NodeWeight branch_and_reduce_algorithm::get_is_weight() const {
753+
// after restoring global best solution, global status was moved to status
754+
return status.is_weight + status.reduction_offset;
755+
}
756+
752757
void branch_and_reduce_algorithm::build_global_graph_access() {
753758
global_mapping.resize(global_status.remaining_nodes, 0);
754759
std::swap(status, global_status);

wmis/lib/mis/kernel/branch_and_reduce_algorithm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ class branch_and_reduce_algorithm {
194194
void disable_cout();
195195
void enable_cout();
196196

197+
NodeWeight get_current_is_weight() const;
198+
197199
public:
198200
branch_and_reduce_algorithm(graph_access& G, const MISConfig& config, bool called_from_fold = false);
199201

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

206-
NodeWeight get_current_is_weight() const;
208+
NodeWeight get_is_weight() const;
207209
void reverse_reduction(graph_access & G, graph_access & reduced_G, std::vector<NodeID> & reverse_mapping);
208210
void apply_branch_reduce_solution(graph_access & G);
209211

wmis/lib/mis/kernel/reductions.cpp

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -396,24 +396,36 @@ void fold2_reduction::restore(branch_and_reduce_algorithm* br_alg) {
396396
}
397397

398398
void fold2_reduction::apply(branch_and_reduce_algorithm* br_alg) {
399-
auto& status = br_alg->status;
400-
auto nodes = restore_vec.back().nodes;
401-
auto main_status = status.node_status[nodes.main];
402-
restore(br_alg);
403-
404-
if (main_status == IS_status::included) {
405-
status.node_status[nodes.main] = IS_status::excluded;
406-
status.node_status[nodes.rest[0]] = IS_status::included;
407-
status.node_status[nodes.rest[1]] = IS_status::included;
408-
409-
status.is_weight += status.weights[nodes.rest[0]] + status.weights[nodes.rest[1]];
410-
} else {
411-
status.node_status[nodes.main] = IS_status::included;
412-
status.node_status[nodes.rest[0]] = IS_status::excluded;
413-
status.node_status[nodes.rest[1]] = IS_status::excluded;
414-
415-
status.is_weight += status.weights[nodes.main];
416-
}
399+
#ifndef NDEBUG
400+
NodeWeight previous_is_weight = br_alg->status.is_weight + br_alg->status.reduction_offset;
401+
#endif
402+
403+
auto& status = br_alg->status;
404+
auto nodes = restore_vec.back().nodes;
405+
auto main_status = status.node_status[nodes.main];
406+
restore(br_alg);
407+
408+
if (main_status == IS_status::included) {
409+
status.node_status[nodes.main] = IS_status::excluded;
410+
status.node_status[nodes.rest[0]] = IS_status::included;
411+
status.node_status[nodes.rest[1]] = IS_status::included;
412+
413+
// weight of folded vertex was added to is_weight while reducing:
414+
// status.is_weight += status.weights[nodes.rest[0]] + status.weights[nodes.rest[1]] - status.weights[nodes.main]
415+
// only need to add status.weights[nodes.main] to is_weight
416+
status.is_weight += status.weights[nodes.main];
417+
// old: status.is_weight += status.weights[nodes.rest[0]] + status.weights[nodes.rest[1]];
418+
} else {
419+
status.node_status[nodes.main] = IS_status::included;
420+
status.node_status[nodes.rest[0]] = IS_status::excluded;
421+
status.node_status[nodes.rest[1]] = IS_status::excluded;
422+
423+
status.is_weight += status.weights[nodes.main];
424+
}
425+
#ifndef NDEBUG
426+
// invariant that has to hold
427+
ASSERT_TRUE(br_alg->status.is_weight + br_alg->status.reduction_offset == previous_is_weight);
428+
#endif
417429
}
418430

419431
bool clique_reduction::reduce(branch_and_reduce_algorithm* br_alg) {
@@ -780,7 +792,7 @@ bool generalized_neighborhood_reduction::reduce(branch_and_reduce_algorithm* br_
780792
continue;
781793
}
782794

783-
if (status.weights[v] >= neighborhood_br_alg.get_current_is_weight())
795+
if (status.weights[v] >= neighborhood_br_alg.get_is_weight())
784796
br_alg->set(v, IS_status::included);
785797
}
786798
}
@@ -845,7 +857,7 @@ bool generalized_fold_reduction::reduce(branch_and_reduce_algorithm* br_alg) {
845857
continue;
846858
}
847859

848-
NodeWeight MWIS_weight = neighborhood_br_alg.get_current_is_weight();
860+
NodeWeight MWIS_weight = neighborhood_br_alg.get_is_weight();
849861
NodeWeight min_MWIS_neighbor_weight = std::numeric_limits<NodeWeight>::max();
850862

851863
if (status.weights[v] >= MWIS_weight) {
@@ -889,7 +901,7 @@ bool generalized_fold_reduction::reduce(branch_and_reduce_algorithm* br_alg) {
889901
std::cerr << "%generalized_fold_reduction br_call loop time out" << std::endl;
890902
check_failed = true;
891903
}
892-
else if (neighborhood_br_alg.get_current_is_weight() >= status.weights[v]) {
904+
else if (neighborhood_br_alg.get_is_weight() >= status.weights[v]) {
893905
check_failed = true;
894906
}
895907

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

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

10601072
void generalized_fold_reduction::apply(branch_and_reduce_algorithm* br_alg) {
1073+
#ifndef NDEBUG
1074+
NodeWeight previous_is_weight = br_alg->status.is_weight + br_alg->status.reduction_offset;
1075+
#endif
10611076
auto& status = br_alg->status;
10621077
auto nodes = restore_vec.back().nodes;
10631078
auto MWIS_weight = restore_vec.back().MWIS_weight;
@@ -1071,7 +1086,8 @@ void generalized_fold_reduction::apply(branch_and_reduce_algorithm* br_alg) {
10711086
status.node_status[node] = IS_status::included;
10721087
}
10731088

1074-
status.is_weight += MWIS_weight;
1089+
status.is_weight += status.weights[nodes.main]; // for details see fold2::apply
1090+
// wrong: status.is_weight += MWIS_weight;
10751091
} else {
10761092
status.node_status[nodes.main] = IS_status::included;
10771093

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

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

0 commit comments

Comments
 (0)