Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: move GA operators behind feature flags #474

Merged
merged 12 commits into from
Apr 12, 2024
39 changes: 34 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,20 @@ name = "ecrs"
path = "src/lib.rs"

[features]
default = ["ga"]
ga = ["test_functions", "dep:push-trait", "dep:len-trait", "dep:num-traits"]
default = ["ga", "ga_ops_impls"]
ga = ["dep:push-trait", "dep:len-trait", "dep:num-traits"]
ga_ops_impls = ["ga_impl_crossover", "ga_impl_mutation", "ga_impl_replacement", "ga_impl_selection", "ga_impl_population"]
ga_impl_crossover = ["ga"]
ga_impl_mutation = ["ga"]
ga_impl_replacement = ["ga"]
ga_impl_selection = ["ga"]
ga_impl_population = ["ga"]
aco = ["dep:nalgebra", "dep:num"]
ff = ["dep:rayon"]
pso = ["dep:rayon", "dep:num", "test_functions"]
aco_tsp = ["aco"]
test_functions = []

all = ["ga", "aco", "ff", "pso", "test_functions"]

[dependencies]
rand = "0.8.5"
Expand All @@ -44,14 +50,12 @@ push-trait = { version = "0.6.0", optional = true }
len-trait = { version = "0.6.1", optional = true }
num-traits = { version = "0.2.15", optional = true }


[dev-dependencies]
log4rs = "1.2.0"
criterion = "0.5.1"
clap = { version = "4.2.7", features = ["derive"] }
md5 = "0.7.0"


[[bench]]
name = "aco_bench"
harness = false
Expand All @@ -72,3 +76,28 @@ lto = "fat"
panic = "abort"
opt-level = 3

[[example]]
name = "jssp"
path = "examples/jssp/main.rs"
required-features = ["ga", "ga_ops_impls"]

[[example]]
name = "ga"
path = "examples/ga.rs"
required-features = ["ga", "ga_ops_impls", "test_functions"]

[[example]]
name = "ga_ackley_test_function"
path = "examples/ga_ackley_test_function.rs"
required-features = ["ga", "ga_ops_impls", "test_functions"]

[[example]]
name = "ga_bsc"
path = "examples/ga_bsc.rs"
required-features = ["ga", "ga_ops_impls", "test_functions"]

[[example]]
name = "ga_rvc"
path = "examples/ga_rvc.rs"
required-features = ["ga", "ga_ops_impls", "test_functions"]

10 changes: 1 addition & 9 deletions examples/ga.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#[cfg(feature = "ga")]
use ecrs::{
ga::{self, individual::RealValueIndividual, probe::AggregatedProbe},
prelude::{
Expand All @@ -7,15 +6,13 @@ use ecrs::{
},
};

#[cfg(feature = "ga")]
mod util;

#[cfg(feature = "ga")]
#[allow(clippy::ptr_arg)]
fn rastrigin_fitness(chromosome: &Vec<f64>) -> f64 {
1000.0 * f64::exp(-ecrs::test_functions::rastrigin(chromosome))
}

#[cfg(feature = "ga")]
fn main() {
let _ = util::init_logging();

Expand Down Expand Up @@ -57,8 +54,3 @@ fn main() {

println!("{res:?}");
}

#[cfg(not(feature = "ga"))]
fn main() {
panic!("Required feature \"ga\" is not enabled");
}
8 changes: 1 addition & 7 deletions examples/ga_ackley_test_function.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![cfg(feature = "ga")]

use ecrs::{ga, test_functions};

mod util;

fn main() {
Expand All @@ -16,8 +15,3 @@ fn main() {

println!("4D ackley function zero approximation {best_individual:#?}")
}

#[cfg(not(feature = "ga"))]
fn main() {
panic!("Required feature \"ga\" is not enabled");
}
9 changes: 0 additions & 9 deletions examples/ga_bsc.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
#[cfg(feature = "ga")]
use ecrs::ga;
#[cfg(feature = "ga")]
mod util;

#[allow(clippy::ptr_arg)]
#[cfg(feature = "ga")]
pub fn wordmax_fitness(chromosome: &Vec<bool>) -> f64 {
chromosome.iter().filter(|gene| **gene).count() as f64
}

#[cfg(feature = "ga")]
fn main() {
let _ = util::init_logging();

Expand All @@ -24,8 +20,3 @@ fn main() {

println!("Bitstring with most ones: {best_individual:#?}")
}

#[cfg(not(feature = "ga"))]
fn main() {
panic!("Required feature \"ga\" is not enabled");
}
10 changes: 0 additions & 10 deletions examples/ga_rvc.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
#[cfg(feature = "ga")]
use ecrs::ga;
#[cfg(feature = "ga")]
mod util;

#[allow(clippy::ptr_arg)]
#[cfg(feature = "ga")]
pub fn rastrigin_fitness(chromosome: &Vec<f64>) -> f64 {
1000.0 * f64::exp(-rastrigin(chromosome))
}

#[cfg(feature = "ga")]
fn rastrigin(chromosome: &[f64]) -> f64 {
10.0 * chromosome.len() as f64
+ chromosome.iter().fold(0.0, |sum, x| {
sum + x.powi(2) - 10.0 * (2.0 * std::f64::consts::PI * x).cos()
})
}

#[cfg(feature = "ga")]
fn main() {
let _ = util::init_logging();

Expand All @@ -31,8 +26,3 @@ fn main() {

println!("5D Rastrigin function zero approximation {best_individual:#?}")
}

#[cfg(not(feature = "ga"))]
fn main() {
panic!("Required feature \"ga\" is not enabled");
}
7 changes: 1 addition & 6 deletions examples/jssp/problem/fitness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,12 +268,7 @@ impl JsspFitness {
self.calculate_critical_distance(indv, 0, &mut visited)
}

fn calculate_critical_distance(
&mut self,
indv: &mut JsspIndividual,
op_id: usize,
visited: &mut Vec<bool>,
) {
fn calculate_critical_distance(&mut self, indv: &mut JsspIndividual, op_id: usize, visited: &mut [bool]) {
let mut stack: Vec<usize> = Vec::with_capacity(visited.len() * 2);

stack.push(op_id);
Expand Down
3 changes: 3 additions & 0 deletions src/ff/auxiliary.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::f64;

#[allow(clippy::ptr_arg)]
pub fn rastrigin(params: &Vec<f64>) -> f64 {
let mut res = 0 as f64;
for param in params.iter() {
Expand All @@ -8,6 +9,7 @@ pub fn rastrigin(params: &Vec<f64>) -> f64 {
res + 10_f64 * params.len() as f64
}

#[allow(clippy::ptr_arg)]
pub fn cartesian_distance(a: &Vec<f64>, b: &[f64]) -> f64 {
//Distance between two points
let mut res: f64 = 0 as f64;
Expand All @@ -17,6 +19,7 @@ pub fn cartesian_distance(a: &Vec<f64>, b: &[f64]) -> f64 {
f64::sqrt(res)
}

#[allow(clippy::ptr_arg)]
pub fn taxi_measure_distance(a: &Vec<f64>, b: &[f64]) -> f64 {
let mut res: f64 = 0 as f64;
for dimension in 0..a.len() {
Expand Down
10 changes: 5 additions & 5 deletions src/ga.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,15 @@
//! 1. Fitness function (the algorithm must know what it is optimizing)
//! 2. Problem dimension
//! 3. Population generator (the algorithm must be able to create initial population)
//! 4. Probe (the logging object -- if you don't want to see any logs other than final result just pass [Empty probe](crate::ga::probes::Empty))
//! 4. Probe (the logging object -- if you don't want to see any logs other than final result just pass [Empty probe](crate::ga::probe::EmptyProbe))
//!
//! The defaults for operators and parameters are provided for two types of chromosomes: bit string and real valued vector (see docs of [Builder](crage::ga::builder::Builder)),
//! The defaults for operators and parameters are provided for two types of chromosomes: bit string and real valued vector (see docs of [Builder](crate::ga::builder::Builder)),
//! but keep in mind that these default options might not be even good for your particular problem as the operators & parameters should be
//! tailored individually for each problem.
//!
//! * See [probes & configuration](ecrs::ga::probe)
//! * See [population generators](ecrs::ga::population)
//! * See [fitness & configuration](ecrs::ga::fitness)
//! * See [probes & configuration](crate::ga::probe)
//! * See [population generators](crate::ga::population)
//! * See [fitness & configuration](crate::ga::operators::fitness)
//! * See [available params](self::GAParams)

pub mod builder;
Expand Down
Loading
Loading