From 6144ce29791a5710a30e24794167e8ef2dd6907e Mon Sep 17 00:00:00 2001 From: reinterpretcat Date: Tue, 12 Dec 2023 21:38:17 +0100 Subject: [PATCH] Improve tolerance support in fast service feature --- .../tests/helpers/models/solution/route.rs | 2 +- .../src/format/problem/goal_reader.rs | 25 ++++++++++++++++--- vrp-pragmatic/src/format/problem/model.rs | 6 ++++- vrp-pragmatic/src/validation/objectives.rs | 2 +- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/vrp-core/tests/helpers/models/solution/route.rs b/vrp-core/tests/helpers/models/solution/route.rs index 821fe31ae..b54fa5dfd 100644 --- a/vrp-core/tests/helpers/models/solution/route.rs +++ b/vrp-core/tests/helpers/models/solution/route.rs @@ -109,7 +109,7 @@ impl RouteStateBuilder { } pub fn build(&mut self) -> RouteState { - std::mem::replace(&mut self.state, RouteState::default()) + std::mem::take(&mut self.state) } } diff --git a/vrp-pragmatic/src/format/problem/goal_reader.rs b/vrp-pragmatic/src/format/problem/goal_reader.rs index b43025bbd..e5ee8e42b 100644 --- a/vrp-pragmatic/src/format/problem/goal_reader.rs +++ b/vrp-pragmatic/src/format/problem/goal_reader.rs @@ -222,7 +222,9 @@ fn get_objective_features( Objective::TourOrder => { create_tour_order_soft_feature("tour_order", TOUR_ORDER_KEY, get_tour_order_fn()) } - Objective::FastService => get_fast_service_feature("fast_service", blocks, props), + Objective::FastService { tolerance } => { + get_fast_service_feature("fast_service", blocks, props, *tolerance) + } }) .collect() }) @@ -266,6 +268,7 @@ fn get_fast_service_feature( name: &str, blocks: &ProblemBlocks, props: &ProblemProperties, + tolerance: Option, ) -> Result { let (transport, activity) = (blocks.transport.clone(), blocks.activity.clone()); if props.has_reloads { @@ -277,6 +280,7 @@ fn get_fast_service_feature( create_simple_reload_route_intervals(Box::new(move |capacity: &MultiDimLoad| { *capacity * RELOAD_THRESHOLD })), + tolerance, FAST_SERVICE_KEY, ) } else { @@ -287,15 +291,30 @@ fn get_fast_service_feature( create_simple_reload_route_intervals(Box::new(move |capacity: &SingleDimLoad| { *capacity * RELOAD_THRESHOLD })), + tolerance, FAST_SERVICE_KEY, ) } } else { let route_intervals = Arc::new(NoRouteIntervals::default()); if props.has_multi_dimen_capacity { - create_fast_service_feature::(name, transport, activity, route_intervals, FAST_SERVICE_KEY) + create_fast_service_feature::( + name, + transport, + activity, + route_intervals, + tolerance, + FAST_SERVICE_KEY, + ) } else { - create_fast_service_feature::(name, transport, activity, route_intervals, FAST_SERVICE_KEY) + create_fast_service_feature::( + name, + transport, + activity, + route_intervals, + tolerance, + FAST_SERVICE_KEY, + ) } } } diff --git a/vrp-pragmatic/src/format/problem/model.rs b/vrp-pragmatic/src/format/problem/model.rs index 02668f79c..81514260d 100644 --- a/vrp-pragmatic/src/format/problem/model.rs +++ b/vrp-pragmatic/src/format/problem/model.rs @@ -648,7 +648,11 @@ pub enum Objective { /// An objective to prefer jobs to be served as soon as possible. #[serde(rename(deserialize = "fast-service", serialize = "fast-service"))] - FastService, + FastService { + /// An objective tolerance specifies how different objective values have to be + /// to consider them different. Relative distance metric is used. + tolerance: Option, + }, } /// Specifies balance objective options. At the moment, it uses coefficient of variation as diff --git a/vrp-pragmatic/src/validation/objectives.rs b/vrp-pragmatic/src/validation/objectives.rs index 55e7acc3f..ff7e13606 100644 --- a/vrp-pragmatic/src/validation/objectives.rs +++ b/vrp-pragmatic/src/validation/objectives.rs @@ -39,7 +39,7 @@ fn check_e1601_duplicate_objectives(objectives: &[&Objective]) -> Result<(), For BalanceDuration { .. } => acc.entry("balance-duration"), CompactTour { .. } => acc.entry("compact-tour"), TourOrder => acc.entry("tour-order"), - FastService => acc.entry("fast-service"), + FastService { .. } => acc.entry("fast-service"), } .and_modify(|count| *count += 1) .or_insert(1_usize);