1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use log::debug;
use crate::algorithms::offline::{OfflineOptions, PureOfflineResult};
use crate::config::IntegralConfig;
use crate::model::{ModelOutputFailure, ModelOutputSuccess};
use crate::problem::{IntegralSmoothedConvexOptimization, Problem};
use crate::result::{Failure, Result};
use crate::schedule::IntegralSchedule;
use crate::utils::assert;
pub fn static_integral<C, D>(
p: IntegralSmoothedConvexOptimization<'_, C, D>,
_: (),
OfflineOptions { inverted, alpha, l }: OfflineOptions,
) -> Result<PureOfflineResult<i32>>
where
C: ModelOutputSuccess,
D: ModelOutputFailure,
{
assert(!inverted, Failure::UnsupportedInvertedCost)?;
assert(
l.is_none() || l == Some(0.),
Failure::UnsupportedLConstrainedMovement,
)?;
let (config, _) =
check_configs(&p, alpha, 0, IntegralConfig::repeat(0, p.d))?;
let xs = IntegralSchedule::new(vec![config; p.t_end as usize]);
Ok(PureOfflineResult { xs })
}
fn check_configs<C, D>(
p: &IntegralSmoothedConvexOptimization<'_, C, D>,
alpha: f64,
k: usize,
mut base_config: IntegralConfig,
) -> Result<(IntegralConfig, f64)>
where
C: ModelOutputSuccess,
D: ModelOutputFailure,
{
if k < p.d as usize {
debug!("Checking dimension {}.", k + 1);
let mut picked_config = base_config.clone();
let mut picked_cost = f64::INFINITY;
for j in p.bounds[k].0..=p.bounds[k].1 {
base_config[k] = j;
let (config, cost) =
check_configs(p, alpha, k + 1, base_config.clone())?;
if cost < picked_cost {
picked_config = config;
picked_cost = cost;
} else if cost > picked_cost {
break;
}
}
Ok((picked_config, picked_cost))
} else {
let cost = p
.objective_function(&IntegralSchedule::new(vec![
base_config
.clone();
p.t_end as usize
]))?
.cost
.raw();
debug!("Config {:?} has associated cost {:?}.", base_config, cost);
Ok((base_config, cost))
}
}