Struct ddo::Times

source ·
pub struct Times<X>(pub usize, pub X);
Expand description

This strategy acts as a decorator for an other max width heuristic. It multiplies the maximum width of the strategy it delegates to by a constant (configured) factor. It is typically used in conjunction with NbUnassigned to provide a maximum width that allows a certain number of nodes. Using a constant factor of 1 means that this decorator will have absolutely no impact.

§Note:

This wrapper forces a minimum width of one. So it is never going to return 0 for a value of the max width.

§Example

Here is an example of how to use this strategy to allow 5 times as many nodes as there are nodes unassigned variable in a layer.

In the following example, there are 5 variables. Three of these have already been assigned. Which means there are only two unassigned variables left. Using the Times(5) decorator would mean that the maximum allowed width for a layer is 10 nodes.

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct KnapsackState {
      // details omitted in this example
}
struct Knapsack {
      // details omitted in this example
}
impl Problem for Knapsack {
     type State = KnapsackState;
     fn nb_variables(&self) -> usize {
         5
     }
      // details omitted in this example
}
let problem = Knapsack {
      // details omitted in this example
};
let heuristic = Times(5, NbUnassignedWidth(problem.nb_variables()));
let subproblem= SubProblem {
    // three decisions have already been made. There only remain variables 0 and 2
    path: vec![
        Decision{variable: Variable(1), value: 1},
        Decision{variable: Variable(3), value: 1},
        Decision{variable: Variable(4), value: 1},
    ]
};
assert_eq!(10, heuristic.max_width(&subproblem));

§Typical usage example

Typically, you will only ever create a Times policy when instantiating your solver. The following example shows how you create a solver that imposes a fixed maximum layer width of five node per unassigned variable.

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct KnapsackState {
      // details omitted in this example
}
struct Knapsack {
      // details omitted in this example
}
impl Problem for Knapsack {
      // details omitted in this example
}
struct KPRelax<'a>{pb: &'a Knapsack}
impl Relaxation for KPRelax<'_> {
      // details omitted in this example
}
struct KPRanking;
impl StateRanking for KPRanking {
      // details omitted in this example
}
pub struct KPDominance;
impl Dominance for KPDominance {
      // details omitted in this example
}
 
let problem = Knapsack {
      // details omitted
};
let relaxation = KPRelax{pb: &problem};
let heuristic = KPRanking;
let dominance = SimpleDominanceChecker::new(KPDominance, problem.nb_variables());
let cutoff = NoCutoff; // might as well be a TimeBudget (or something else) 
let mut fringe = SimpleFringe::new(MaxUB::new(&heuristic));
let mut solver = DefaultSolver::new(
      &problem, 
      &relaxation, 
      &heuristic, 
      &Times(5, NbUnassignedWidth(problem.nb_variables())),
      &dominance,
      &cutoff, 
      &mut fringe);

Tuple Fields§

§0: usize§1: X

Trait Implementations§

source§

impl<X: Clone> Clone for Times<X>

source§

fn clone(&self) -> Times<X>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<X: Debug> Debug for Times<X>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<S, X: WidthHeuristic<S>> WidthHeuristic<S> for Times<X>

source§

fn max_width(&self, x: &SubProblem<S>) -> usize

Estimates a good maximum width for an MDD rooted in the given state
source§

impl<X: Copy> Copy for Times<X>

Auto Trait Implementations§

§

impl<X> RefUnwindSafe for Times<X>
where X: RefUnwindSafe,

§

impl<X> Send for Times<X>
where X: Send,

§

impl<X> Sync for Times<X>
where X: Sync,

§

impl<X> Unpin for Times<X>
where X: Unpin,

§

impl<X> UnwindSafe for Times<X>
where X: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.