problemreductions/solvers/
brute_force.rs1use crate::config::DimsIterator;
4use crate::solvers::Solver;
5use crate::traits::Problem;
6use crate::types::Aggregate;
7
8#[derive(Debug, Clone, Default)]
14pub struct BruteForce;
15
16impl BruteForce {
17 pub fn new() -> Self {
19 Self
20 }
21
22 pub fn find_witness<P>(&self, problem: &P) -> Option<Vec<usize>>
24 where
25 P: Problem,
26 P::Value: Aggregate,
27 {
28 self.find_all_witnesses(problem).into_iter().next()
29 }
30
31 pub fn find_all_witnesses<P>(&self, problem: &P) -> Vec<Vec<usize>>
33 where
34 P: Problem,
35 P::Value: Aggregate,
36 {
37 let total = self.solve(problem);
38
39 if !P::Value::supports_witnesses() {
40 return vec![];
41 }
42
43 DimsIterator::new(problem.dims())
44 .filter(|config| {
45 let value = problem.evaluate(config);
46 P::Value::contributes_to_witnesses(&value, &total)
47 })
48 .collect()
49 }
50
51 pub fn solve_with_witnesses<P>(&self, problem: &P) -> (P::Value, Vec<Vec<usize>>)
53 where
54 P: Problem,
55 P::Value: Aggregate,
56 {
57 let total = self.solve(problem);
58
59 if !P::Value::supports_witnesses() {
60 return (total, vec![]);
61 }
62
63 let witnesses = DimsIterator::new(problem.dims())
64 .filter(|config| {
65 let value = problem.evaluate(config);
66 P::Value::contributes_to_witnesses(&value, &total)
67 })
68 .collect();
69
70 (total, witnesses)
71 }
72}
73
74impl Solver for BruteForce {
75 fn solve<P>(&self, problem: &P) -> P::Value
76 where
77 P: Problem,
78 P::Value: Aggregate,
79 {
80 DimsIterator::new(problem.dims())
81 .map(|config| problem.evaluate(&config))
82 .fold(P::Value::identity(), P::Value::combine)
83 }
84}
85
86#[cfg(test)]
87#[path = "../unit_tests/solvers/brute_force.rs"]
88mod tests;