pub struct HyperVolume;Expand description
Struct with methods to calculate the exact hyper-volume metric. Depending on the number of problem
objectives n, a different method is used to ensure a correct and fast calculation:
- with
2objectives: by calculating the rectangle areas between each objective point and the reference point. - with
3objectives: by using the algorithm proposed by Fonseca et al. (2006) inHyperVolumeFonseca2006. - with
4or more objectives: by using the algorithm proposed by While et al. (2012) inHyperVolumeWhile2012.
The hyper-volume can be calculated from the following sources:
- an array of
IndividualusingHyperVolume::from_individual - an array of objectives given as
f64usingHyperVolume::from_values - a JSON file using
HyperVolume::from_file - a folder with JSON files using
HyperVolume::from_files
§Example
The following example shows how to calculate the hyper-volume and track convergence.
use std::env;
use std::path::PathBuf;
use optirustic::algorithms::{Algorithm, ExportHistory, NSGA2Arg, StoppingCondition, NSGA2};
use optirustic::core::builtin_problems::SCHProblem;
use optirustic::core::OError;
use optirustic::metrics::HyperVolume;
/// This example shows how to track the algorithm convergence by calculating the hyper-volume metric.
/// This library employs different and fast methods, depending on the number of problem objectives,
/// such as [Fonseca et al. (2006)](http://dx.doi.org/10.1109/CEC.2006.1688440) or
/// [While et al. (2012)](http://dx.doi.org/10.1109/TEVC.2010.2077298).
///
/// Convergence can be tracked while an algorithm runs by saving the evolution history of the
/// population. This is useful if you have an evaluation function, that evaluates the problem
/// objectives and constraints (this is the `evaluate()` function in the `Evaluator` trait),
/// that takes very long to run .
///
/// The example below solves the SCH problem, export the evolution history as JSON every 100
/// generations and calculate the hyper-volume at different generations.
///
/// Make sure to compile this in release mode to speed up the calculation:
///
/// `cargo run --example convergence -p optirustic --release`
fn main() -> Result<(), OError> {
let problem = SCHProblem::create()?;
let out_path = PathBuf::from(&env::current_dir().expect("Cannot fetch current directory"))
.join("examples")
.join("results")
.join("convergence");
// this exports a JSON file every 100 generations
let export_history = ExportHistory::new(100, &out_path)?;
let args = NSGA2Arg {
number_of_individuals: 10,
stopping_condition: StoppingCondition::MaxGeneration(1000),
crossover_operator_options: None,
mutation_operator_options: None,
parallel: Some(false),
export_history: Some(export_history),
resume_from_file: None,
seed: Some(10),
};
let mut algo = NSGA2::new(problem, args)?;
algo.run()?;
let mut results = algo.get_results();
let serialised_data = NSGA2::read_json_files(&out_path)?;
let ref_point = HyperVolume::estimate_reference_point_from_files(&serialised_data, None)?;
println!("Reference point: {:?}", ref_point);
// calculate metric from the history file
let serialised_data = NSGA2::read_json_file(&out_path.join("History_NSGA2_gen200.json"))?;
let hv = HyperVolume::from_file(&serialised_data, &ref_point)?;
println!(
"Hyper-volume at generation #{} is {}",
hv.generation, hv.value
);
// calculate metric at the last iteration
let hv = HyperVolume::from_individual(&mut results.individuals, &ref_point)?;
println!("Hyper-volume at last generation is {}", hv);
// calculate the hyper-volume at all generations to check the overall convergence
let all_serialise_data = NSGA2::read_json_files(&out_path)?;
let hvs = HyperVolume::from_files(&all_serialise_data, &ref_point)?;
println!("Hyper-volumes generations: {:?}", hvs.generations());
println!("Hyper-volumes values: {:?}", hvs.values());
Ok(())
}Implementations§
Source§impl HyperVolume
impl HyperVolume
Sourcepub fn from_individual(
individuals: &mut [Individual],
reference_point: &[f64],
) -> Result<f64, OError>
pub fn from_individual( individuals: &mut [Individual], reference_point: &[f64], ) -> Result<f64, OError>
Calculate the exact hyper-volume metric for the objective values stored in the vector of
Individual. If you have an array of objective values instead of Individual, you can
use HyperVolume::from_values instead.
§Arguments
individuals: The individuals to use in the calculation. The algorithm will use the objective vales stored in each individual.reference_point: The reference or anti-optimal point to use in the calculation. If you are not sure about the point to use you could pick the worst value of each objective from the individual’s values usingHyperVolume::estimate_reference_point.
returns: Result<f64, OError>
Sourcepub fn from_values(
problem: Problem,
individuals: &[HashMap<String, f64>],
reference_point: &[f64],
) -> Result<f64, OError>
pub fn from_values( problem: Problem, individuals: &[HashMap<String, f64>], reference_point: &[f64], ) -> Result<f64, OError>
Calculate the exact hyper-volume metric for the objectives.
§Arguments
problem: The problem to solve.individuals: The objectives values; each array represents an individual, each nested map contains the objective names and values instead.reference_point: The reference or anti-optimal point to use in the calculation. If you are not sure about the point to use you could pick the worst value of each objective from the individual’s values using theHyperVolume::estimate_reference_pointmethod.
returns: Result<f64, OError>
Sourcepub fn from_file<AlgorithmOptions: Serialize + DeserializeOwned>(
data: &AlgorithmSerialisedExport<AlgorithmOptions>,
reference_point: &[f64],
) -> Result<HyperVolumeFileData, OError>
pub fn from_file<AlgorithmOptions: Serialize + DeserializeOwned>( data: &AlgorithmSerialisedExport<AlgorithmOptions>, reference_point: &[f64], ) -> Result<HyperVolumeFileData, OError>
Calculate the hyper-volume using serialised objective values (i.e. exported in a JSON file
using crate::algorithms::Algorithm::save_to_json).
§Arguments
data: The serialised data. This can be imported usingcrate::algorithms::Algorithm::read_json_filewherecrate::algorithms::Algorithmis the algorithm used to export the data (for examplecrate::algorithms::NSGA2).reference_point: The reference or anti-optimal point to use in the calculation. If you are not sure about the point to use you could pick the worst value of each objective from the individual’s values usingHyperVolume::estimate_reference_point.
returns: Result<HyperVolumeFileData, OError>: the hyper-volume value and the file
information.
Sourcepub fn from_files<AlgorithmOptions: Serialize + DeserializeOwned>(
data: &[AlgorithmSerialisedExport<AlgorithmOptions>],
reference_point: &[f64],
) -> Result<AllHyperVolumeFileData, OError>
pub fn from_files<AlgorithmOptions: Serialize + DeserializeOwned>( data: &[AlgorithmSerialisedExport<AlgorithmOptions>], reference_point: &[f64], ) -> Result<AllHyperVolumeFileData, OError>
Calculate the hyper-volume using the serialised objective values (i.e. exported in a JSON
file using crate::algorithms::Algorithm::save_to_json).
§Arguments
data: The serialised data from the JSON files. These can be imported usingcrate::algorithms::Algorithm::read_json_fileswherecrate::algorithms::Algorithmis the algorithm used to export the data (for examplecrate::algorithms::NSGA2).reference_point: The reference or anti-optimal point to use in the calculation.
returns: Result<AllHyperVolumeFileData, OError>: the hyper-volume values and the file
information.
Sourcepub fn estimate_reference_point(
individuals: &[Individual],
offset: Option<Vec<f64>>,
) -> Result<Vec<f64>, OError>
pub fn estimate_reference_point( individuals: &[Individual], offset: Option<Vec<f64>>, ) -> Result<Vec<f64>, OError>
Calculates a reference point by taking the maximum of each objective (or minimum if the objective is maximised) from the calculated individual’s objective values, so that the point will be dominated by all other points. An optional offset for all objectives could also be added or removed to enforce strict dominance (if the objective is minimised the offset is added to the calculated reference point, otherwise it is subtracted).
§Arguments
individuals: The individuals to use in the calculation.offset: The offset to add to each objective coordinate of the calculated reference point. This must have a size equal to the number of objectives in the problem (Problem::number_of_objectives).
returns: Result<Vec<f64>, OError> The reference point. This returns an error if there are
no individuals or the size of the offset does not match Problem::number_of_objectives.
Sourcepub fn estimate_reference_point_from_file<AlgorithmOptions: Serialize + DeserializeOwned>(
data: &AlgorithmSerialisedExport<AlgorithmOptions>,
offset: Option<Vec<f64>>,
) -> Result<Vec<f64>, OError>
pub fn estimate_reference_point_from_file<AlgorithmOptions: Serialize + DeserializeOwned>( data: &AlgorithmSerialisedExport<AlgorithmOptions>, offset: Option<Vec<f64>>, ) -> Result<Vec<f64>, OError>
Calculates a reference point by taking the maximum of each objective (or minimum if the
objective is maximised) from the objective values exported in a JSON file.
See HyperVolume::estimate_reference_point for a detailed description of the estimation.
§Arguments
data: The serialised data. This can be imported usingcrate::algorithms::Algorithm::read_json_filewherecrate::algorithms::Algorithmis the algorithm used to export the data (for examplecrate::algorithms::NSGA2).offset: The offset to add to each objective coordinate of the calculated reference point. This must have a size equal to the number of objectives in the problem (Problem::number_of_objectives).
returns: Result<Vec<f64>, OError> The reference point. This returns an error if there are
no individuals or the size of the offset does not match Problem::number_of_objectives.
Sourcepub fn estimate_reference_point_from_files<AlgorithmOptions: Serialize + DeserializeOwned>(
data: &[AlgorithmSerialisedExport<AlgorithmOptions>],
offset: Option<Vec<f64>>,
) -> Result<Vec<f64>, OError>
pub fn estimate_reference_point_from_files<AlgorithmOptions: Serialize + DeserializeOwned>( data: &[AlgorithmSerialisedExport<AlgorithmOptions>], offset: Option<Vec<f64>>, ) -> Result<Vec<f64>, OError>
Calculates a reference point by taking the maximum of each objective (or minimum if the
objective is maximised) from the objective values exported in a JSON files. This may be
use to estimate the reference point when convergence is being tracked and one dominated
reference point is needed.
See HyperVolume::estimate_reference_point for a detailed description of the estimation.
§Arguments
data: The serialised data from the JSON files. These can be imported usingcrate::algorithms::Algorithm::read_json_fileswherecrate::algorithms::Algorithmis the algorithm used to export the data (for examplecrate::algorithms::NSGA2).offset: The offset to add to each objective coordinate of the calculated reference point. This must have a size equal to the number of objectives in the problem (Problem::number_of_objectives).
returns: Result<Vec<f64>, OError> The reference point. This returns an error if there are
no individuals or the size of the offset does not match Problem::number_of_objectives.
Auto Trait Implementations§
impl Freeze for HyperVolume
impl RefUnwindSafe for HyperVolume
impl Send for HyperVolume
impl Sync for HyperVolume
impl Unpin for HyperVolume
impl UnwindSafe for HyperVolume
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.