dtrees_rs/algorithms/optimal/dl85/
builder.rs1use crate::algorithms::common::errors::ErrorWrapper;
2use crate::algorithms::common::heuristics::Heuristic;
3use crate::algorithms::common::types::{
4 BranchingPolicy, LowerBoundPolicy, NodeDataType, OptimalDepth2Policy,
5};
6use crate::algorithms::optimal::depth2::OptimalDepth2Tree;
7use crate::algorithms::optimal::dl85::config::DL85Config;
8use crate::algorithms::optimal::dl85::DL85;
9use crate::algorithms::optimal::rules::common::{
10 LowerBoundRule, MaxDepthRule, MinSupportRule, PureNodeRule, TimeLimitRule, UsableNodeRule,
11};
12use crate::algorithms::optimal::rules::{Rule, RuleManager};
13use crate::caching::Caching;
14
15pub struct DL85Builder<C, D, E, H>
41where
42 C: Caching + ?Sized,
43 D: OptimalDepth2Tree + ?Sized,
44 E: ErrorWrapper + ?Sized,
45 H: Heuristic + ?Sized,
46{
47 config: DL85Config,
48 cache: Option<Box<C>>,
49 depth2_search: Option<Box<D>>,
50 error_fn: Option<Box<E>>,
51 heuristic_fn: Option<Box<H>>,
52 nodes_rules: RuleManager,
53 search_rules: RuleManager,
54 time_rule: TimeLimitRule,
55}
56
57impl<C, D, E, H> Default for DL85Builder<C, D, E, H>
58where
59 C: Caching + ?Sized,
60 D: OptimalDepth2Tree + ?Sized,
61 E: ErrorWrapper + ?Sized,
62 H: Heuristic + ?Sized,
63{
64 fn default() -> Self {
65 let builder = Self {
66 config: DL85Config::default(),
67 cache: None,
68 depth2_search: None,
69 error_fn: None,
70 heuristic_fn: None,
71 nodes_rules: RuleManager::new(),
72 search_rules: RuleManager::new(),
73 time_rule: TimeLimitRule::default(),
74 };
75 builder.default_rules()
76 }
77}
78
79impl<C, D, E, H> DL85Builder<C, D, E, H>
80where
81 C: Caching + ?Sized,
82 D: OptimalDepth2Tree + ?Sized,
83 E: ErrorWrapper + ?Sized,
84 H: Heuristic + ?Sized,
85{
86 pub fn new() -> Self {
88 Self::default()
89 }
90
91 pub fn min_support(mut self, value: usize) -> Self {
93 self.config.base.min_support = value;
94 self.nodes_rules
95 .add_rule(Box::new(MinSupportRule::new(value)));
96 self
97 }
98
99 pub fn max_depth(mut self, value: usize) -> Self {
101 self.config.base.max_depth = value;
102 self.nodes_rules
103 .add_rule(Box::new(MaxDepthRule::new(value)));
104 self
105 }
106
107 pub fn max_error(mut self, value: f64) -> Self {
109 self.config.base.max_error = value;
110 self
111 }
112
113 pub fn max_time(mut self, value: f64) -> Self {
115 self.config.base.max_time = value;
116 self.time_rule = TimeLimitRule::new(value);
117 self
118 }
119
120 pub fn default_rules(mut self) -> Self {
123 self.nodes_rules.add_rule(Box::new(UsableNodeRule::new()));
124 self.nodes_rules.add_rule(Box::new(PureNodeRule::new()));
125 self.nodes_rules.add_rule(Box::new(LowerBoundRule::new()));
126 self
127 }
128
129 pub fn depth2_search(mut self, search: Box<D>) -> Self {
131 self.depth2_search = Some(search);
132 self
133 }
134
135 pub fn add_node_rule(mut self, rule: Box<dyn Rule>) -> Self {
137 self.nodes_rules.add_rule(rule);
138 self
139 }
140
141 pub fn add_node_rules(mut self, rules: Vec<Box<dyn Rule>>) -> Self {
143 for rule in rules {
144 self.nodes_rules.add_rule(rule)
145 }
146 self
147 }
148
149 pub fn add_search_rule(mut self, rule: Box<dyn Rule>) -> Self {
153 self.search_rules.add_rule(rule);
154 self
155 }
156
157 pub fn add_search_rules(mut self, rules: Vec<Box<dyn Rule>>) -> Self {
159 for rule in rules {
160 self.search_rules.add_rule(rule)
161 }
162 self
163 }
164
165 pub fn always_sort(mut self, value: bool) -> Self {
167 self.config.always_sort = value;
168 self
169 }
170
171 pub fn specialization(mut self, value: OptimalDepth2Policy) -> Self {
173 self.config.optimal_depth2policy = value;
174 self
175 }
176
177 pub fn lower_bound_strategy(mut self, value: LowerBoundPolicy) -> Self {
179 self.config.lower_bound_policy = value;
180 self
181 }
182
183 pub fn branching_strategy(mut self, value: BranchingPolicy) -> Self {
185 self.config.branching_policy = value;
186 self
187 }
188
189 pub fn node_exposed_data(mut self, value: NodeDataType) -> Self {
191 self.config.data_type = value;
192 self
193 }
194
195 pub fn cache(mut self, value: Box<C>) -> Self {
197 self.cache = Some(value);
198 self
199 }
200
201 pub fn error_function(mut self, value: Box<E>) -> Self {
203 self.error_fn = Some(value);
204 self
205 }
206
207 pub fn heuristic(mut self, value: Box<H>) -> Self {
209 self.heuristic_fn = Some(value);
210 self
211 }
212
213 pub fn build(self) -> Result<DL85<C, D, E, H>, String> {
215 let cache = self.cache.ok_or("Cache is required")?;
216 let depth2 = self.depth2_search.ok_or("Depth-2 search is required")?;
217 let error_function = self.error_fn.ok_or("Error function is required")?;
218 let heuristic = self.heuristic_fn.ok_or("Heuristic is required")?;
219
220 Ok(DL85::new(
221 self.config,
222 cache,
223 depth2,
224 error_function,
225 heuristic,
226 self.nodes_rules,
227 self.search_rules,
228 self.time_rule,
229 ))
230 }
231}