Skip to content

Commit

Permalink
Avoid boxing iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
reinterpretcat committed Oct 3, 2024
1 parent f193fc9 commit e25d90b
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 25 deletions.
6 changes: 3 additions & 3 deletions vrp-core/src/models/problem/jobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ impl Job {
}

/// Get all places from the job.
pub fn places(&self) -> Box<dyn Iterator<Item = &Place> + '_> {
pub fn places(&self) -> impl Iterator<Item = &Place> + '_ {
match &self {
Job::Single(single) => Box::new(single.places.iter()),
Job::Multi(multi) => Box::new(multi.jobs.iter().flat_map(|single| single.places.iter())),
Job::Single(single) => Either::Left(single.places.iter()),
Job::Multi(multi) => Either::Right(multi.jobs.iter().flat_map(|single| single.places.iter())),
}
}
}
Expand Down
10 changes: 4 additions & 6 deletions vrp-core/src/solver/search/decompose_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::construction::heuristics::*;
use crate::models::GoalContext;
use crate::solver::search::create_environment_with_custom_quota;
use crate::solver::*;
use crate::utils::Either;
use rosomaxa::utils::parallel_into_collect;
use std::cell::RefCell;
use std::cmp::Ordering;
Expand Down Expand Up @@ -190,20 +191,17 @@ fn create_partial_insertion_ctx(
fn create_empty_insertion_ctxs(
insertion_ctx: &InsertionContext,
environment: Arc<Environment>,
) -> Box<dyn Iterator<Item = (InsertionContext, HashSet<usize>)>> {
// TODO split into more insertion_ctxs if too many required jobs are present
// this might increase overall refinement speed

) -> impl Iterator<Item = (InsertionContext, HashSet<usize>)> {
let solution = &insertion_ctx.solution;

if solution.required.is_empty()
&& solution.unassigned.is_empty()
&& solution.ignored.is_empty()
&& solution.locked.is_empty()
{
Box::new(empty())
Either::Left(empty())
} else {
Box::new(once((
Either::Right(once((
InsertionContext {
problem: insertion_ctx.problem.clone(),
solution: SolutionContext {
Expand Down
27 changes: 14 additions & 13 deletions vrp-core/src/solver/search/ruin/adjusted_string_removal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::models::problem::Job;
use crate::models::solution::Tour;
use crate::solver::search::*;
use crate::solver::RefinementContext;
use crate::utils::Either;
use rosomaxa::prelude::{Float, Random};
use std::cell::RefCell;
use std::sync::Arc;
Expand Down Expand Up @@ -101,8 +102,6 @@ impl Ruin for AdjustedStringRemoval {
}
}

type JobIter<'a> = Box<dyn Iterator<Item = Job> + 'a>;

/// Calculates average tour cardinality rounded to nearest integral value.
fn calculate_average_tour_cardinality(routes: &[RouteContext]) -> Float {
(routes.iter().map(|route_ctx| route_ctx.route().tour.job_activity_count() as Float).sum::<Float>()
Expand All @@ -116,20 +115,24 @@ fn select_string<'a>(
cardinality: usize,
alpha: Float,
random: &Arc<dyn Random>,
) -> JobIter<'a> {
) -> impl Iterator<Item = Job> + 'a {
if random.is_head_not_tails() {
sequential_string(seed_tour, cardinality, random)
Either::Left(sequential_string(seed_tour, cardinality, random))
} else {
preserved_string(seed_tour, cardinality, alpha, random)
Either::Right(preserved_string(seed_tour, cardinality, alpha, random))
}
}

/// Selects sequential string.
fn sequential_string<'a>(seed_tour: (&'a Tour, usize), cardinality: usize, random: &Arc<dyn Random>) -> JobIter<'a> {
fn sequential_string<'a>(
seed_tour: (&'a Tour, usize),
cardinality: usize,
random: &Arc<dyn Random>,
) -> impl Iterator<Item = Job> + 'a {
let (begin, end) = lower_bounds(cardinality, seed_tour.0.job_activity_count(), seed_tour.1);
let start = random.uniform_int(begin as i32, end as i32) as usize;

Box::new((start..(start + cardinality)).filter_map(move |i| seed_tour.0.get(i).and_then(|a| a.retrieve_job())))
(start..(start + cardinality)).filter_map(move |i| seed_tour.0.get(i).and_then(|a| a.retrieve_job()))
}

/// Selects string with preserved jobs.
Expand All @@ -138,7 +141,7 @@ fn preserved_string<'a>(
cardinality: usize,
alpha: Float,
random: &Arc<dyn Random>,
) -> JobIter<'a> {
) -> impl Iterator<Item = Job> + 'a {
let size = seed_tour.0.job_activity_count();
let index = seed_tour.1;

Expand All @@ -155,11 +158,9 @@ fn preserved_string<'a>(
// this line makes sure that string cardinality is kept as requested.
let total = total - usize::from(index >= split_start && index < split_end);

Box::new(
(start_total..(start_total + total))
.filter(move |&i| i < split_start || i >= split_end || i == index)
.filter_map(move |i| seed_tour.0.get(i).and_then(|a| a.retrieve_job())),
)
(start_total..(start_total + total))
.filter(move |&i| i < split_start || i >= split_end || i == index)
.filter_map(move |i| seed_tour.0.get(i).and_then(|a| a.retrieve_job()))
}

/// Returns range of possible lower bounds.
Expand Down
7 changes: 4 additions & 3 deletions vrp-pragmatic/src/format/solution/activity_matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use vrp_core::models::common::*;
use vrp_core::models::problem::{Job, JobIdDimension, Single};
use vrp_core::models::solution::{Activity, Place};
use vrp_core::prelude::*;
use vrp_core::utils::Either;

/// Aggregates job specific information for a job activity.
pub(crate) struct JobInfo(pub Job, pub Arc<Single>, pub Place, pub TimeWindow);
Expand Down Expand Up @@ -40,8 +41,8 @@ pub(crate) fn try_match_point_job(
"pickup" | "delivery" | "replacement" | "service" => {
let job =
job_index.get(&activity.job_id).ok_or_else(|| format!("unknown job id: '{}'", activity.job_id))?;
let singles: Box<dyn Iterator<Item = &Arc<_>>> = match job {
Job::Single(single) => Box::new(once(single)),
let singles = match job {
Job::Single(single) => Either::Left(once(single)),
Job::Multi(multi) => {
let tags = multi
.jobs
Expand All @@ -57,7 +58,7 @@ pub(crate) fn try_match_point_job(
.into());
}

Box::new(multi.jobs.iter())
Either::Right(multi.jobs.iter())
}
};
let (single, place) = singles
Expand Down

0 comments on commit e25d90b

Please sign in to comment.