Skip to content

Commit

Permalink
Merge pull request #13 from s-simoncelli/add-new-nsga3-example
Browse files Browse the repository at this point in the history
Added new NSGA3 example
  • Loading branch information
s-simoncelli authored Aug 10, 2024
2 parents 8189f5a + cf8b72c commit 1b88a5e
Show file tree
Hide file tree
Showing 7 changed files with 4,575 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use optirustic::algorithms::{
Algorithm, MaxGeneration, NSGA3Arg, Nsga3NumberOfIndividuals, StoppingConditionType, NSGA3,
};
use optirustic::core::builtin_problems::DTLZ1Problem;
use optirustic::operators::{PolynomialMutationArgs, SimulatedBinaryCrossoverArgs};
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
Expand All @@ -18,7 +18,7 @@ use optirustic::utils::{DasDarren1998, NumberOfPartitions};
///
/// Make sure to compile this in release mode to speed up the calculation:
///
/// `cargo run --example nsga3 --release`
/// `cargo run --example nsga3_dtlz1 --release`
fn main() -> Result<(), Box<dyn Error>> {
// Add log
env_logger::builder().filter_level(LevelFilter::Info).init();
Expand All @@ -32,7 +32,6 @@ fn main() -> Result<(), Box<dyn Error>> {

// 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(6);
let number_of_partitions = NumberOfPartitions::OneLayer(12);
// NSGA3 internally uses the Das & Darren approach to generate the points. This is also
// available using:
Expand All @@ -46,17 +45,16 @@ fn main() -> Result<(), Box<dyn Error>> {
let crossover_operator_options = SimulatedBinaryCrossoverArgs {
distribution_index: 30.0,
crossover_probability: 1.0,
variable_probability: 0.5,
..SimulatedBinaryCrossoverArgs::default()
};
let mutation_operator_options = PolynomialMutationArgs::default(&problem);

// 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: Some(mutation_operator_options),
mutation_operator_options: None,
// stop at generation 400
stopping_condition: StoppingConditionType::MaxGeneration(MaxGeneration(400)),
parallel: None,
Expand All @@ -77,7 +75,7 @@ fn main() -> Result<(), Box<dyn Error>> {
.join("results");

algo.save_to_json(&destination, Some("DTLZ1_3obj"))?;

// algo.plot_objectives("optirustic/examples/results/DTLZ1_3obj.png")?;

Ok(())
}
77 changes: 77 additions & 0 deletions optirustic/examples/nsga3_dtlz2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use std::env;
use std::error::Error;
use std::path::PathBuf;

use log::LevelFilter;

use optirustic::algorithms::{
Algorithm, MaxGeneration, NSGA3Arg, Nsga3NumberOfIndividuals, StoppingConditionType, NSGA3,
};
use optirustic::core::builtin_problems::DTLZ2Problem;
use optirustic::operators::SimulatedBinaryCrossoverArgs;
use optirustic::utils::{DasDarren1998, NumberOfPartitions};

/// Solve the DTLZ2 problem from Deb et al. (2013) with 3 objectives.
///
/// Make sure to compile this in release mode to speed up the calculation:
///
/// `cargo run --example nsga3_dtlz2 --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 = 10;
let number_variables: usize = number_objectives + k - 1;
// Get the built-in problem
let problem = DTLZ2Problem::create(number_variables, number_objectives)?;

// 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(6);
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: StoppingConditionType::MaxGeneration(MaxGeneration(400)),
parallel: None,
export_history: None,
// to reproduce results
seed: Some(1),
};

// Initialise the algorithm
let mut algo = NSGA3::new(problem, args).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("DTLZ2_3obj"))?;

Ok(())
}
8 changes: 7 additions & 1 deletion optirustic/examples/reference_points_1layer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use std::env;
use std::path::PathBuf;

use optirustic::core::OError;
use optirustic::utils::{DasDarren1998, NumberOfPartitions};

Expand All @@ -16,5 +19,8 @@ fn main() -> Result<(), OError> {
println!("Weights = {:?}", weights);

// Save the charts of points to inspect them
m.plot("ref_points_3obj_5gaps.png")
let out_path = PathBuf::from(&env::current_dir().unwrap())
.join("examples")
.join("results");
m.plot(&out_path.join("ref_points_3obj_5gaps.png"))
}
8 changes: 7 additions & 1 deletion optirustic/examples/reference_points_2layers.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use std::env;
use std::path::PathBuf;

use optirustic::core::OError;
use optirustic::utils::{DasDarren1998, NumberOfPartitions, TwoLayerPartitions};

Expand All @@ -20,5 +23,8 @@ fn main() -> Result<(), OError> {
println!("Weights = {:?}", weights);

// Save the charts of points to inspect them
m.plot("ref_points_2layers_3obj_5gaps.png")
let out_path = PathBuf::from(&env::current_dir().unwrap())
.join("examples")
.join("results");
m.plot(&out_path.join("ref_points_2layers_3obj_5gaps.png"))
}
Loading

0 comments on commit 1b88a5e

Please sign in to comment.