use std::fmt::{Debug, Formatter};
use crate::problems::Problem;
pub struct Individual<P: Problem + ?Sized> {
solution: P::Encoding,
objective: Option<P::Objective>,
}
impl<P: Problem + ?Sized> Individual<P> {
pub fn new(solution: P::Encoding, objective: P::Objective) -> Self {
Self {
solution,
objective: Some(objective),
}
}
pub fn new_unevaluated(solution: P::Encoding) -> Self {
Self {
solution,
objective: None,
}
}
pub fn evaluate_with<F>(&mut self, mut objective_fn: F)
where
F: FnMut(&P::Encoding) -> P::Objective,
{
self.objective = Some(objective_fn(&self.solution));
}
pub fn set_objective(&mut self, objective: P::Objective) -> bool {
let evaluated = self.objective.is_some();
self.objective = Some(objective);
evaluated
}
pub fn solution(&self) -> &P::Encoding {
&self.solution
}
pub fn solution_mut(&mut self) -> &mut P::Encoding {
self.objective = None;
&mut self.solution
}
pub fn into_solution(self) -> P::Encoding {
self.solution
}
pub fn is_evaluated(&self) -> bool {
self.objective.is_some()
}
pub fn get_objective(&self) -> Option<&P::Objective> {
self.objective.as_ref()
}
pub fn objective(&self) -> &P::Objective {
self.objective.as_ref().unwrap()
}
}
impl<P> Individual<P>
where
P: Problem,
P::Encoding: Default,
{
pub(crate) fn new_test_unit(objective: P::Objective) -> Self {
Self::new(P::Encoding::default(), objective)
}
}
impl<P> Default for Individual<P>
where
P: Problem,
P::Encoding: Default,
{
fn default() -> Self {
Self::new_unevaluated(P::Encoding::default())
}
}
impl<P: Problem> Clone for Individual<P> {
fn clone(&self) -> Self {
Self {
solution: self.solution.clone(),
objective: self.objective.clone(),
}
}
}
impl<P: Problem> PartialEq for Individual<P> {
fn eq(&self, other: &Self) -> bool {
self.solution == other.solution && self.objective == other.objective
}
}
impl<E: Debug, P: Problem<Encoding = E>> Debug for Individual<P> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let mut debug = f.debug_struct("Individual");
debug.field("solution", &self.solution);
if let Some(objective) = self.get_objective() {
debug.field("objective", objective);
}
debug.finish()
}
}