Skip to content

Commit

Permalink
Add debug trait implementation for GoalContext
Browse files Browse the repository at this point in the history
  • Loading branch information
reinterpretcat committed Apr 5, 2023
1 parent 44a0f39 commit 9441b6e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 19 deletions.
7 changes: 6 additions & 1 deletion vrp-core/src/models/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ pub struct Problem {

impl Debug for Problem {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct(short_type_name::<Self>()).field("fleet", &self.fleet).finish_non_exhaustive()
f.debug_struct(short_type_name::<Self>())
.field("fleet", &self.fleet)
.field("jobs", &self.jobs.size())
.field("locks", &self.locks.len())
.field("goal", self.goal.as_ref())
.finish_non_exhaustive()
}
}

Expand Down
51 changes: 33 additions & 18 deletions vrp-core/src/models/goal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ use crate::construction::enablers::*;
use crate::construction::heuristics::*;
use crate::models::common::Cost;
use crate::models::problem::Job;
use crate::utils::short_type_name;
use hashbrown::{HashMap, HashSet};
use rand::prelude::SliceRandom;
use rosomaxa::algorithms::nsga2::dominance_order;
use rosomaxa::population::Shuffled;
use rosomaxa::prelude::*;
use std::cmp::Ordering;
use std::fmt::{Debug, Formatter};
use std::slice::Iter;
use std::sync::Arc;

Expand All @@ -30,8 +32,8 @@ use std::sync::Arc;
/// for vehicles/jobs, etc.
#[derive(Clone, Default)]
pub struct GoalContext {
pub(crate) hierarchical_objectives: Vec<Vec<Arc<dyn FeatureObjective<Solution = InsertionContext> + Send + Sync>>>,
pub(crate) flat_objectives: Vec<Arc<dyn FeatureObjective<Solution = InsertionContext> + Send + Sync>>,
pub(crate) global_objectives: Vec<Vec<Arc<dyn FeatureObjective<Solution = InsertionContext> + Send + Sync>>>,
pub(crate) flatten_objectives: Vec<Arc<dyn FeatureObjective<Solution = InsertionContext> + Send + Sync>>,
pub(crate) local_objectives: Vec<Vec<Arc<dyn FeatureObjective<Solution = InsertionContext> + Send + Sync>>>,
pub(crate) constraints: Vec<Arc<dyn FeatureConstraint + Send + Sync>>,
pub(crate) states: Vec<Arc<dyn FeatureState + Send + Sync>>,
Expand Down Expand Up @@ -96,14 +98,26 @@ impl GoalContext {
})
};

let hierarchical_objectives = remap_objectives(global_objective_map)?;
let global_objectives = remap_objectives(global_objective_map)?;
let local_objectives = remap_objectives(local_objective_map)?;

let states = features.iter().filter_map(|feature| feature.state.clone()).collect();
let constraints = features.iter().filter_map(|feature| feature.constraint.clone()).collect();
let flat_objectives = hierarchical_objectives.iter().flat_map(|inners| inners.iter()).cloned().collect();
let flatten_objectives = global_objectives.iter().flat_map(|inners| inners.iter()).cloned().collect();

Ok(Self { hierarchical_objectives, flat_objectives, local_objectives, constraints, states })
Ok(Self { global_objectives, flatten_objectives, local_objectives, constraints, states })
}
}

impl Debug for GoalContext {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct(short_type_name::<Self>())
.field("global", &self.global_objectives.len())
.field("flatten", &self.flatten_objectives.len())
.field("local", &self.local_objectives.len())
.field("constraints", &self.constraints.len())
.field("states", &self.states.len())
.finish()
}
}

Expand Down Expand Up @@ -279,34 +293,35 @@ impl MultiObjective for GoalContext {
type Solution = InsertionContext;

fn total_order(&self, a: &Self::Solution, b: &Self::Solution) -> Ordering {
unwrap_from_result(self.hierarchical_objectives.iter().try_fold(Ordering::Equal, |_, objectives| {
match dominance_order(a, b, objectives.iter().map(|o| o.as_ref())) {
unwrap_from_result(self.global_objectives.iter().try_fold(
Ordering::Equal,
|_, objectives| match dominance_order(a, b, objectives.iter().map(|o| o.as_ref())) {
Ordering::Equal => Ok(Ordering::Equal),
order => Err(order),
}
}))
},
))
}

fn fitness<'a>(&'a self, solution: &'a Self::Solution) -> Box<dyn Iterator<Item = f64> + 'a> {
Box::new(self.flat_objectives.iter().map(|o| o.fitness(solution)))
Box::new(self.flatten_objectives.iter().map(|o| o.fitness(solution)))
}

fn get_order(&self, a: &Self::Solution, b: &Self::Solution, idx: usize) -> Result<Ordering, String> {
self.flat_objectives
self.flatten_objectives
.get(idx)
.map(|o| o.total_order(a, b))
.ok_or_else(|| format!("cannot get total_order with index: {idx}"))
}

fn get_distance(&self, a: &Self::Solution, b: &Self::Solution, idx: usize) -> Result<f64, String> {
self.flat_objectives
self.flatten_objectives
.get(idx)
.map(|o| o.distance(a, b))
.ok_or_else(|| format!("cannot get distance with index: {idx}"))
}

fn size(&self) -> usize {
self.flat_objectives.len()
self.flatten_objectives.len()
}
}

Expand All @@ -315,15 +330,15 @@ impl HeuristicObjective for GoalContext {}
impl Shuffled for GoalContext {
/// Returns a new instance of `GoalContext` with shuffled objectives.
fn get_shuffled(&self, random: &(dyn Random + Send + Sync)) -> Self {
let mut hierarchical_objectives = self.hierarchical_objectives.clone();
let mut flat_objectives = self.flat_objectives.clone();
let mut global_objectives = self.global_objectives.clone();
let mut flatten_objectives = self.flatten_objectives.clone();
let mut local_objectives = self.local_objectives.clone();

hierarchical_objectives.shuffle(&mut random.get_rng());
flat_objectives.shuffle(&mut random.get_rng());
global_objectives.shuffle(&mut random.get_rng());
flatten_objectives.shuffle(&mut random.get_rng());
local_objectives.shuffle(&mut random.get_rng());

Self { hierarchical_objectives, flat_objectives, local_objectives, ..self.clone() }
Self { global_objectives, flatten_objectives, local_objectives, ..self.clone() }
}
}

Expand Down

0 comments on commit 9441b6e

Please sign in to comment.