Skip to content

Commit 32c80d1

Browse files
committed
Score branches before adding children
It may improve best score allowing us to avoid ever adding the children to the heap if their bound function doesn't think they can improve on it.
1 parent dcaa14f commit 32c80d1

File tree

2 files changed

+20
-18
lines changed

2 files changed

+20
-18
lines changed

src/bnb.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -51,24 +51,22 @@ impl<'a, M: BnbMetric> Iterator for BnbIter<'a, M> {
5151

5252
let selector = branch.selector;
5353

54-
self.insert_new_branches(&selector);
55-
56-
if branch.is_exclusion {
57-
return Some(None);
54+
let mut return_val = None;
55+
if !branch.is_exclusion {
56+
if let Some(score) = self.metric.score(&selector) {
57+
let better = match self.best {
58+
Some(best_score) => score < best_score,
59+
None => true,
60+
};
61+
if better {
62+
self.best = Some(score);
63+
return_val = Some(score);
64+
}
65+
};
5866
}
5967

60-
let score = match self.metric.score(&selector) {
61-
Some(score) => score,
62-
None => return Some(None),
63-
};
64-
65-
if let Some(best_score) = &self.best {
66-
if score >= *best_score {
67-
return Some(None);
68-
}
69-
}
70-
self.best = Some(score);
71-
Some(Some((selector, score)))
68+
self.insert_new_branches(&selector);
69+
Some(return_val.map(|score| (selector, score)))
7270
}
7371
}
7472

@@ -92,7 +90,11 @@ impl<'a, M: BnbMetric> BnbIter<'a, M> {
9290
fn consider_adding_to_queue(&mut self, cs: &CoinSelector<'a>, is_exclusion: bool) {
9391
let bound = self.metric.bound(cs);
9492
if let Some(bound) = bound {
95-
if self.best.is_none() || self.best.as_ref().unwrap() >= &bound {
93+
let is_good_enough = match self.best {
94+
Some(best) => best > bound,
95+
None => true,
96+
};
97+
if is_good_enough {
9698
let branch = Branch {
9799
lower_bound: bound,
98100
selector: cs.clone(),

tests/bnb.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ fn bnb_finds_an_exact_solution_in_n_iter() {
100100
.last()
101101
.expect("it found a solution");
102102

103-
assert_eq!(rounds, 50180);
103+
assert_eq!(rounds, 50168);
104104
assert_eq!(best.input_weight(), solution_weight);
105105
assert_eq!(best.selected_value(), target.value, "score={:?}", score);
106106
}

0 commit comments

Comments
 (0)