competitive_library/other/
ternary_search.rs1pub fn ternary_search(mut low: f64, mut high: f64, f: Box<dyn Fn(f64) -> f64>) -> f64 {
2 let mut cnt = 1000;
3 while cnt > 0 {
4 let c1 = (low * 2.0 + high) / 3.0;
5 let c2 = (low + high * 2.0) / 3.0;
6
7 if f(c1) > f(c2) {
8 low = c1;
9 } else {
10 high = c2;
11 }
12 cnt -= 1;
13 }
14 high
15}
16
17#[cfg(test)]
18mod tests {
19 use super::ternary_search;
20 #[test]
22 fn a() {
23 let (a, b) = (10.0, 1.0);
24 let f = move |x: f64| (x * b) + a / (x + 1.0).sqrt();
25 let h = ternary_search(0.0, 1_000_000_000_000_000_000.0, Box::new(f));
26
27 assert!((f((h + 0.5) as i64 as f64) - 7.773_502_691_9).abs() < 0.000_001);
28 }
29 #[test]
30 fn b() {
31 let (a, b) = (5.0, 10.0);
32 let f = move |x: f64| (x * b) + a / (x + 1.0).sqrt();
33 let h = ternary_search(0.0, 1_000_000_000_000_000_000.0, Box::new(f));
34
35 assert!(dbg!((f((h + 0.5) as i64 as f64) - 5.000_000_000_0).abs()) < 0.000_001);
36 }
37
38 #[test]
39 fn c() {
40 let (a, b) = (1_000_000_000_000_000_000.0, 100.0);
41 let f = move |x: f64| (x * b) + a / (x + 1.0).sqrt();
42 let h = ternary_search(0.0, 1_000_000_000_000_000_000.0, Box::new(f));
43
44 assert!(dbg!((f((h + 0.4) as i64 as f64) - 8_772_053_214_538.598_f64).abs()) < 0.01);
45 }
46}