pub trait Solver<O, I: State> {
// Required methods
fn name(&self) -> &str;
fn next_iter(
&mut self,
problem: &mut Problem<O>,
state: I,
) -> Result<(I, Option<KV>), Error>;
// Provided methods
fn init(
&mut self,
_problem: &mut Problem<O>,
state: I,
) -> Result<(I, Option<KV>), Error> { ... }
fn terminate_internal(&mut self, state: &I) -> TerminationStatus { ... }
fn terminate(&mut self, _state: &I) -> TerminationStatus { ... }
}
Expand description
The interface all solvers are required to implement.
Every solver needs to implement this trait in order to function with the Executor
.
It handles initialization (init
), each iteration of the solver
(next_iter
), and termination of the algorithm
(terminate
and terminate_internal
).
Only next_iter
is mandatory to implement, all others provide default implementations.
A Solver
should be (de)serializable in order to work with checkpointing.
§Example
use argmin::core::{
ArgminFloat, Solver, IterState, CostFunction, Error, KV, Problem, TerminationReason, TerminationStatus
};
#[derive(Clone)]
struct OptimizationAlgorithm {}
impl<O, P, G, J, H, R, F> Solver<O, IterState<P, G, J, H, R, F>> for OptimizationAlgorithm
where
O: CostFunction<Param = P, Output = F>,
P: Clone,
F: ArgminFloat
{
fn name(&self) -> &str { "OptimizationAlgorithm" }
fn init(
&mut self,
problem: &mut Problem<O>,
state: IterState<P, G, J, H, R, F>,
) -> Result<(IterState<P, G, J, H, R, F>, Option<KV>), Error> {
// Initialize algorithm, update `state`.
// Implementing this method is optional.
Ok((state, None))
}
fn next_iter(
&mut self,
problem: &mut Problem<O>,
state: IterState<P, G, J, H, R, F>,
) -> Result<(IterState<P, G, J, H, R, F>, Option<KV>), Error> {
// Compute single iteration of algorithm, update `state`.
// Implementing this method is required.
Ok((state, None))
}
fn terminate(&mut self, state: &IterState<P, G, J, H, R, F>) -> TerminationStatus {
// Check if stopping criteria are met.
// Implementing this method is optional.
TerminationStatus::NotTerminated
}
}
Required Methods§
sourcefn next_iter(
&mut self,
problem: &mut Problem<O>,
state: I,
) -> Result<(I, Option<KV>), Error>
fn next_iter( &mut self, problem: &mut Problem<O>, state: I, ) -> Result<(I, Option<KV>), Error>
Computes a single iteration of the algorithm and has access to the optimization problem
definition and the internal state of the solver.
Returns an updated state
and optionally a KV
which holds key-value pairs used in
Observers.
Provided Methods§
sourcefn init(
&mut self,
_problem: &mut Problem<O>,
state: I,
) -> Result<(I, Option<KV>), Error>
fn init( &mut self, _problem: &mut Problem<O>, state: I, ) -> Result<(I, Option<KV>), Error>
Initializes the algorithm.
Executed before any iterations are performed and has access to the optimization problem
definition and the internal state of the solver.
Returns an updated state
and optionally a KV
which holds key-value pairs used in
Observers.
The default implementation returns the unaltered state
and no KV
.
sourcefn terminate_internal(&mut self, state: &I) -> TerminationStatus
fn terminate_internal(&mut self, state: &I) -> TerminationStatus
Checks whether basic termination reasons apply.
Terminate if
- algorithm was terminated somewhere else in the Executor
- iteration count exceeds maximum number of iterations
- best cost is lower than or equal to the target cost
This can be overwritten; however it is not advised. It is recommended to implement other
stopping criteria via (terminate
.
sourcefn terminate(&mut self, _state: &I) -> TerminationStatus
fn terminate(&mut self, _state: &I) -> TerminationStatus
Used to implement stopping criteria, in particular criteria which are not covered by
(terminate_internal
.
This method has access to the internal state and returns an TerminationReason
.