///|
/// Result of comparing several deterministic construction strategies.
pub struct MultiStartRun {
result : @core.SolveResult
attempt_count : Int
selected_strategy : @constructive.ConstructionStrategy
} derive(Debug)
///|
pub fn MultiStartRun::result(self : MultiStartRun) -> @core.SolveResult {
self.result
}
///|
pub fn MultiStartRun::attempt_count(self : MultiStartRun) -> Int {
self.attempt_count
}
///|
pub fn MultiStartRun::selected_strategy(
self : MultiStartRun,
) -> @constructive.ConstructionStrategy {
self.selected_strategy
}
///|
fn default_strategies() -> Array[@constructive.ConstructionStrategy] {
[
@constructive.ConstructionStrategy::ClarkeWright,
@constructive.ConstructionStrategy::NearestNeighbor,
@constructive.ConstructionStrategy::CheapestInsertion,
@constructive.ConstructionStrategy::DemandFirst,
@constructive.ConstructionStrategy::Radial,
@constructive.ConstructionStrategy::Balanced,
]
}
///|
/// Solves the same instance from several independent constructive seeds.
pub fn solve_with_strategies(
instance : @core.VrpInstance,
strategies : Array[@constructive.ConstructionStrategy],
config : @core.SolveConfig,
) -> MultiStartRun {
let selected = if strategies.is_empty() {
default_strategies()
} else {
strategies.copy()
}
let mut best_result : @core.SolveResult? = None
let mut best_strategy = selected[0]
for strategy in selected {
let seed = @constructive.seed_by_strategy(instance, strategy, config)
let result = solve_with_seed(instance, seed, config~)
match best_result {
None => {
best_result = Some(result)
best_strategy = strategy
}
Some(current) =>
if result.best_solution.objective < current.best_solution.objective {
best_result = Some(result)
best_strategy = strategy
} else {
best_result = Some(current)
}
}
}
match best_result {
None => {
let result = solve(instance, config~)
{
result,
attempt_count: 1,
selected_strategy: @constructive.ConstructionStrategy::ClarkeWright,
}
}
Some(result) =>
{
result,
attempt_count: selected.length(),
selected_strategy: best_strategy,
}
}
}