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
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! Online Algorithms.

use crate::algorithms::Options;
use crate::config::Config;
use crate::model::{ModelOutputFailure, ModelOutputSuccess};
use crate::problem::{DefaultGivenOnlineProblem, Online, Problem};
use crate::result::Result;
use crate::schedule::Schedule;
use crate::value::Value;
use pyo3::{IntoPy, PyObject};
use serde::de::DeserializeOwned;
use serde::Serialize;

pub mod multi_dimensional;
pub mod uni_dimensional;

/// Solution fragment at some time $t$ to an online problem.
///
/// * Configuration at time $t$.
/// * Memory if new memory should be added.
pub struct Step<T, M>(pub Config<T>, pub Option<M>);
pub type IntegralStep<M> = Step<i32, M>;
pub type FractionalStep<M> = Step<f64, M>;

/// Memory of online algorithm.
pub trait Memory<'a, T, P, C, D>:
    Clone
    + std::fmt::Debug
    + DefaultGivenOnlineProblem<T, P, C, D>
    + DeserializeOwned
    + IntoPy<PyObject>
    + Send
    + Serialize
    + 'a
where
    P: Problem<T, C, D>,
    C: ModelOutputSuccess,
    D: ModelOutputFailure,
{
}
impl<'a, T, P, C, D, M> Memory<'a, T, P, C, D> for M
where
    M: Clone
        + std::fmt::Debug
        + DefaultGivenOnlineProblem<T, P, C, D>
        + DeserializeOwned
        + IntoPy<PyObject>
        + Send
        + Serialize
        + 'a,
    P: Problem<T, C, D>,
    C: ModelOutputSuccess,
    D: ModelOutputFailure,
{
}

/// Implementation of an online algorithm.
///
/// * `P` - problem
/// * `M` - memory
/// * `O` - options
///
/// Receives the arguments:
/// * `o` - online problem instance
/// * `t` - current time slot
/// * `xs` - schedule up to the previous time slot
/// * `prev_m` - latest memory, is the default if nothing was memorized
/// * `options` - algorithm options
pub trait OnlineAlgorithm<'a, T, P, M, O, C, D>:
    Fn(Online<P>, i32, &Schedule<T>, M, O) -> Result<Step<T, M>> + Send + Sync
where
    T: Value<'a>,
    P: Problem<T, C, D> + 'a,
    M: Memory<'a, T, P, C, D>,
    O: Options<T, P, C, D>,
    C: ModelOutputSuccess,
    D: ModelOutputFailure,
{
    /// Executes the next iteration of an online algorithm.
    fn next(
        &self,
        o: Online<P>,
        xs: &Schedule<T>,
        prev_m_: Option<M>,
        options: O,
    ) -> Result<Step<T, M>> {
        let t = xs.t_end() + 1;
        let prev_m = match prev_m_ {
            None => M::default(&o),
            Some(prev_m) => prev_m,
        };

        self(o, t, xs, prev_m, options)
    }

    /// Executes the next iteration of an online algorithm with default options.
    fn next_with_default_options(
        &self,
        o: Online<P>,
        xs: &Schedule<T>,
        prev_m_: Option<M>,
    ) -> Result<Step<T, M>> {
        let options = O::default(&o.p);
        self.next(o, xs, prev_m_, options)
    }
}
impl<'a, T, P, M, O, C, D, F> OnlineAlgorithm<'a, T, P, M, O, C, D> for F
where
    T: Value<'a>,
    P: Problem<T, C, D> + 'a,
    M: Memory<'a, T, P, C, D>,
    O: Options<T, P, C, D>,
    C: ModelOutputSuccess,
    D: ModelOutputFailure,
    F: Fn(Online<P>, i32, &Schedule<T>, M, O) -> Result<Step<T, M>>
        + Send
        + Sync,
{
}