pub struct NSGA3 { /* private fields */ }Expand description
The Non-dominated Sorting Genetic Algorithm (NSGA3).
Implemented based on:
K. Deb and H. Jain, “An Evolutionary Many-Objective Optimization Algorithm Using Reference-Point-Based Non-dominated Sorting Approach, Part I: Solving Problems With Box Constraints,” in IEEE Transactions on Evolutionary Computation, vol. 18, no. 4, pp. 577-601, Aug. 2014, doi: 10.1109/TEVC.2013.2281535
See: https://10.1109/TEVC.2013.2281535
§Example - solve the DTLZ1 problem
use std::env;
use std::error::Error;
use std::path::PathBuf;
use log::LevelFilter;
use optirustic::algorithms::{
Algorithm, NSGA3Arg, Nsga3NumberOfIndividuals, StoppingCondition, NSGA3,
};
use optirustic::core::builtin_problems::DTLZ1Problem;
use optirustic::operators::SimulatedBinaryCrossoverArgs;
use optirustic::utils::{DasDarren1998, NumberOfPartitions};
/// Solve the DTLZ1 problem from Deb et al. (2013) with 3 objectives. This is a problem where the
/// optimal solutions or objectives lie on the hyper-plane passing through the intercept point
/// at 0.5 on each objective axis. This code replicates the first testing problem in Deb et al.
/// (2013).
///
/// Make sure to compile this in release mode to speed up the calculation:
///
/// `cargo run --example nsga3_dtlz1 -p optirustic --release`
fn main() -> Result<(), Box<dyn Error>> {
// Add log
env_logger::builder().filter_level(LevelFilter::Info).init();
let number_objectives: usize = 3;
// Set the number of variables to use in the DTLZ1 problem
let k: usize = 5;
let number_variables: usize = number_objectives + k - 1;
// Get the built-in problem
let problem = DTLZ1Problem::create(number_variables, number_objectives, false)?;
// Set the number of partitions to create the reference points for the NSGA3 algorithm. This
// uses one layer of 12 uniform gaps
let number_of_partitions = NumberOfPartitions::OneLayer(12);
// NSGA3 internally uses the Das & Darren approach to generate the points. This is also
// available using:
let das_darren = DasDarren1998::new(number_objectives, &number_of_partitions)?;
println!(
"Number of reference points to generate: {}",
das_darren.number_of_points()
);
// Customise the SBX and PM operators like in the paper
let crossover_operator_options = SimulatedBinaryCrossoverArgs {
distribution_index: 30.0,
crossover_probability: 1.0,
..SimulatedBinaryCrossoverArgs::default()
};
// Set up the NSGA3 algorithm
let args = NSGA3Arg {
// number of individuals from the paper (possibly equal to number of reference points)
number_of_individuals: Nsga3NumberOfIndividuals::Custom(92),
number_of_partitions,
crossover_operator_options: Some(crossover_operator_options),
mutation_operator_options: None,
// stop at generation 400
stopping_condition: StoppingCondition::MaxGeneration(400),
parallel: None,
export_history: None,
// to reproduce results
seed: Some(1),
resume_from_file: None,
};
// Initialise the algorithm
let mut algo = NSGA3::new(problem, args, false).unwrap();
// Run the algorithm
algo.run()?;
// Export the last results to a JSON file
let destination = PathBuf::from(&env::current_dir().unwrap())
.join("examples")
.join("results");
algo.save_to_json(&destination, Some("DTLZ1_3obj"))?;
// algo.plot_objectives("examples/results/DTLZ1_3obj.png")?;
Ok(())
}Implementations§
Source§impl NSGA3
impl NSGA3
Sourcepub fn new(
problem: Problem,
options: NSGA3Arg,
adaptive: bool,
) -> Result<Self, OError>
pub fn new( problem: Problem, options: NSGA3Arg, adaptive: bool, ) -> Result<Self, OError>
Initialise the NSGA3 algorithm.
§Arguments
problem: The problem being solved.options: TheNSGA3Argarguments to customise the algorithm behaviour.adaptive: Whether to use the adaptive approach to handle the reference points. Normally reference points are fixed and never change position, andNSGA3will try to associate one individual to each reference point. However, there are some problems where the reference lines never intersects the Pareto front and no Pareto-optimal solutions are associated to those reference points. The reference points intersecting the front may have too many points associated and create crowded solutions. To improve the solutions for these kind of problems, when this option is set totrue, new reference points will adaptively be added around the provided points to reduce crowding and force one solution to be associated to preferably only on reference direction. This option convertsNSGA3tocrate::algorithms::AdaptiveNSGA3(whereAstands for adaptive) and it is explained in Section VII of Jain and Deb (2013). For a detailed explanation about the implementation seeAdaptiveReferencePoints.
returns: NSGA3.
Sourcepub fn reference_points(&self) -> Vec<Vec<f64>>
pub fn reference_points(&self) -> Vec<Vec<f64>>
Get the reference points used in the evolution.
return: Vec<Vec<f64>>
Trait Implementations§
Source§impl Algorithm<NSGA3Arg> for NSGA3
Implementation of Section IV of the paper.
impl Algorithm<NSGA3Arg> for NSGA3
Implementation of Section IV of the paper.
Source§fn initialise(&mut self) -> Result<(), OError>
fn initialise(&mut self) -> Result<(), OError>
This assesses the initial random population.
return: Result<(), OError>
Source§fn evolve(&mut self) -> Result<(), OError>
fn evolve(&mut self) -> Result<(), OError>
Evolve the population. The first part of this code comes from NSGA2::evolve(). NSGA3 mainly differs in the survival method.
Source§fn additional_export_data(&self) -> Option<HashMap<String, DataValue>>
fn additional_export_data(&self) -> Option<HashMap<String, DataValue>>
Source§fn stopping_condition(&self) -> &StoppingCondition
fn stopping_condition(&self) -> &StoppingCondition
Source§fn start_time(&self) -> &Instant
fn start_time(&self) -> &Instant
Source§fn population(&self) -> &Population
fn population(&self) -> &Population
Source§fn export_history(&self) -> Option<&ExportHistory>
fn export_history(&self) -> Option<&ExportHistory>
Source§fn generation(&self) -> u32
fn generation(&self) -> u32
Source§fn number_of_function_evaluations(&self) -> u32
fn number_of_function_evaluations(&self) -> u32
Algorithm::evaluate_individual. If no
new solutions/individuals are chosen by an algorithm, this counter will not increase, as past
solutions are already evaluated. Read morefn algorithm_options(&self) -> NSGA3Arg
Source§fn elapsed(&self) -> [u64; 3]
fn elapsed(&self) -> [u64; 3]
Source§fn elapsed_as_string(&self) -> String
fn elapsed_as_string(&self) -> String
Source§fn do_parallel_evaluation(
individuals: &mut [Individual],
nfe: &mut u32,
) -> Result<(), OError>
fn do_parallel_evaluation( individuals: &mut [Individual], nfe: &mut u32, ) -> Result<(), OError>
nfe counter by the number of evaluated individuals.
This returns an error if the evaluation function fails or the evaluation function does not
provide a value for a problem constraints or objectives for one individual. Read moreSource§fn do_evaluation(
individuals: &mut [Individual],
nfe: &mut u32,
) -> Result<(), OError>
fn do_evaluation( individuals: &mut [Individual], nfe: &mut u32, ) -> Result<(), OError>
nfe counter by the number of evaluated individuals.
This returns an error if the evaluation function fails or the evaluation function does not
provide a value for a problem constraints or objectives for one individual.
Evaluation may be performed in threads using Self::do_parallel_evaluation. Read moreSource§fn evaluate_individual(idx: usize, i: &mut Individual) -> Result<(), OError>
fn evaluate_individual(idx: usize, i: &mut Individual) -> Result<(), OError>
Source§fn count_unevaluated(individuals: &[Individual]) -> u32
fn count_unevaluated(individuals: &[Individual]) -> u32
Source§fn is_stopping_condition_met(
&self,
condition: &StoppingCondition,
) -> Result<bool, OError>
fn is_stopping_condition_met( &self, condition: &StoppingCondition, ) -> Result<bool, OError>
Source§fn get_results(&self) -> AlgorithmExport
fn get_results(&self) -> AlgorithmExport
Source§fn save_to_json(
&self,
destination: &PathBuf,
file_prefix: Option<&str>,
) -> Result<(), OError>
fn save_to_json( &self, destination: &PathBuf, file_prefix: Option<&str>, ) -> Result<(), OError>
Source§fn read_json_file(
file: &PathBuf,
) -> Result<AlgorithmSerialisedExport<AlgorithmOptions>, OError>
fn read_json_file( file: &PathBuf, ) -> Result<AlgorithmSerialisedExport<AlgorithmOptions>, OError>
Self::save_to_json. Read moreSource§fn read_json_files(
folder: &PathBuf,
) -> Result<Vec<AlgorithmSerialisedExport<AlgorithmOptions>>, OError>
fn read_json_files( folder: &PathBuf, ) -> Result<Vec<AlgorithmSerialisedExport<AlgorithmOptions>>, OError>
Auto Trait Implementations§
impl Freeze for NSGA3
impl !RefUnwindSafe for NSGA3
impl !Send for NSGA3
impl !Sync for NSGA3
impl Unpin for NSGA3
impl !UnwindSafe for NSGA3
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.