Skip to content

Commit

Permalink
Merge pull request #102 from luleyleo/cleanup-modules
Browse files Browse the repository at this point in the history
Cleanup project structure
  • Loading branch information
luleyleo authored Jul 23, 2022
2 parents c693716 + 2821011 commit 67c2a2e
Show file tree
Hide file tree
Showing 42 changed files with 303 additions and 287 deletions.
2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ derive_deref = "1.1.1"
embed-doc-image = "0.1.4"
erased-serde = "0.3.16"
float_eq = "0.7.0"
itoa = "1.0.1"
num_cpus = "1.13.0"
pest = "2.1.3"
pest_consume = "1.1.1"
Expand All @@ -24,7 +23,6 @@ rand = "0.8.4"
rand_distr = "0.4.2"
ron = "0.7.0"
rprompt = "1.0.5"
ryu = "1.0.9"
serde = {version = "1.0.131", features = ["derive"]}
trait-set = "0.3.0"

Expand Down
6 changes: 1 addition & 5 deletions examples/coco.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use mahf::{
framework::components,
heuristics::iwo,
operators::termination,
problems::coco_bound::{suits, CocoInstance},
Expand All @@ -18,10 +17,7 @@ fn main() -> anyhow::Result<()> {
final_deviation: 0.001,
modulation_index: 3,
},
components::And::new(vec![
termination::FixedIterations::new(500),
termination::TargetHit::new(),
]),
termination::FixedIterations::new(500) & termination::TargetHit::new(),
tracking::Logger::builder()
.log_common_sets()
.log_set(
Expand Down
4 changes: 2 additions & 2 deletions param-study/src/instances/iwo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use crate::{
util::{print_result, ArgsIter, Setup},
};
use mahf::{
float_eq::float_eq, framework, heuristics::iwo, operators::termination,
problems::bmf::BenchmarkFunction, random::Random, tracking,
float_eq::float_eq, framework, framework::Random, heuristics::iwo, operators::termination,
problems::bmf::BenchmarkFunction, tracking,
};
use std::time::Instant;

Expand Down
3 changes: 1 addition & 2 deletions param-study/src/instances/pso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ use std::time::Instant;

use mahf::{
float_eq::float_eq,
framework::{self},
framework::{self, Random},
heuristics::pso,
problems::bmf::BenchmarkFunction,
random::Random,
};

use crate::{
Expand Down
152 changes: 13 additions & 139 deletions src/framework/components.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! Framework components.
pub use crate::framework::conditions::Condition;

use crate::{
framework::{common_state, Fitness, State},
framework::state::{common, State},
problems::Problem,
};
use serde::Serialize;
Expand All @@ -26,22 +28,13 @@ trait_set! {
/// Most of the time, execution should be multi threaded and having
/// components implement [Send] makes this much easier.
///
pub trait Component<P>: AnyComponent {
pub trait Component<P: Problem>: AnyComponent {
#[allow(unused_variables)]
fn initialize(&self, problem: &P, state: &mut State) {}
fn execute(&self, problem: &P, state: &mut State);
}
erased_serde::serialize_trait_object!(<P: Problem> Component<P>);

pub trait Condition<P>: AnyComponent {
#[allow(unused_variables)]
fn initialize(&self, problem: &P, state: &mut State) {}
fn evaluate(&self, problem: &P, state: &mut State) -> bool;
}
erased_serde::serialize_trait_object!(<P: Problem> Condition<P>);

pub type Configuration<P> = Box<dyn Component<P>>;

#[derive(Serialize)]
#[serde(bound = "")]
pub struct Scope<P: Problem> {
Expand All @@ -51,10 +44,7 @@ pub struct Scope<P: Problem> {
init: fn(&mut State),
}

impl<P> Component<P> for Scope<P>
where
P: Problem + 'static,
{
impl<P: Problem> Component<P> for Scope<P> {
fn execute(&self, problem: &P, state: &mut State) {
state.with_substate(|state| {
(self.init)(state);
Expand All @@ -64,7 +54,7 @@ where
}
}

impl<P: Problem + 'static> Scope<P> {
impl<P: Problem> Scope<P> {
pub fn new(body: Vec<Box<dyn Component<P>>>) -> Box<dyn Component<P>> {
Self::new_with(|_| {}, body)
}
Expand All @@ -83,10 +73,7 @@ impl<P: Problem + 'static> Scope<P> {
#[serde(transparent)]
pub struct Block<P: Problem>(Vec<Box<dyn Component<P>>>);

impl<P> Component<P> for Block<P>
where
P: Problem + 'static,
{
impl<P: Problem> Component<P> for Block<P> {
fn initialize(&self, problem: &P, state: &mut State) {
for component in &self.0 {
component.initialize(problem, state);
Expand All @@ -100,7 +87,7 @@ where
}
}

impl<P: Problem + 'static> Block<P> {
impl<P: Problem> Block<P> {
pub fn new(components: Vec<Box<dyn Component<P>>>) -> Box<dyn Component<P>> {
Box::new(Block(components))
}
Expand All @@ -115,12 +102,9 @@ pub struct Loop<P: Problem> {
body: Box<dyn Component<P>>,
}

impl<P> Component<P> for Loop<P>
where
P: Problem + 'static,
{
impl<P: Problem> Component<P> for Loop<P> {
fn initialize(&self, problem: &P, state: &mut State) {
state.insert(common_state::Iterations(0));
state.insert(common::Iterations(0));

self.condition.initialize(problem, state);
self.body.initialize(problem, state);
Expand All @@ -130,12 +114,12 @@ where
self.condition.initialize(problem, state);
while self.condition.evaluate(problem, state) {
self.body.execute(problem, state);
*state.get_value_mut::<common_state::Iterations>() += 1;
*state.get_value_mut::<common::Iterations>() += 1;
}
}
}

impl<P: Problem + 'static> Loop<P> {
impl<P: Problem> Loop<P> {
pub fn new(
condition: Box<dyn Condition<P>>,
body: Vec<Box<dyn Component<P>>>,
Expand All @@ -153,10 +137,7 @@ pub struct Branch<P: Problem> {
else_body: Option<Box<dyn Component<P>>>,
}

impl<P> Component<P> for Branch<P>
where
P: Problem + 'static,
{
impl<P: Problem> Component<P> for Branch<P> {
fn initialize(&self, problem: &P, state: &mut State) {
self.condition.initialize(problem, state);
self.if_body.initialize(problem, state);
Expand Down Expand Up @@ -201,110 +182,3 @@ impl<P: Problem + 'static> Branch<P> {
})
}
}

#[derive(Serialize)]
pub struct SimpleEvaluator;

impl SimpleEvaluator {
pub fn new<P: Problem>() -> Box<dyn Component<P>> {
Box::new(Self)
}
}

impl<P: Problem> Component<P> for SimpleEvaluator {
fn initialize(&self, _problem: &P, state: &mut State) {
state.require::<common_state::Population>();
state.insert(common_state::Evaluations(0));
state.insert(common_state::BestFitness(Fitness::default()));
state.insert(common_state::BestIndividual(None));
}

fn execute(&self, problem: &P, state: &mut State) {
let mut mut_state = state.get_states_mut();

// Evaluate population
let population = mut_state.population_stack_mut();

if population.is_empty() {
return;
}

for individual in population.current_mut().iter_mut() {
let solution = individual.solution::<P::Encoding>();
let fitness = Fitness::try_from(problem.evaluate(solution)).unwrap();
individual.evaluate(fitness);
}

// Update best fitness and individual
let best_individual = population.best();

if mut_state
.get_mut::<common_state::BestIndividual>()
.replace_if_better(best_individual)
{
mut_state.set_value::<common_state::BestFitness>(best_individual.fitness());
}

// Update evaluations
*mut_state.get_value_mut::<common_state::Evaluations>() +=
population.current().len() as u32;
}
}

#[derive(Serialize)]
#[serde(bound = "")]
pub struct And<P: Problem>(Vec<Box<dyn Condition<P>>>);
impl<P: Problem + 'static> And<P> {
pub fn new(conditions: Vec<Box<dyn Condition<P>>>) -> Box<dyn Condition<P>> {
Box::new(Self(conditions))
}
}
impl<P: Problem + 'static> Condition<P> for And<P> {
fn initialize(&self, problem: &P, state: &mut State) {
for condition in self.0.iter() {
condition.initialize(problem, state);
}
}

fn evaluate(&self, problem: &P, state: &mut State) -> bool {
self.0
.iter()
.all(|condition| condition.evaluate(problem, state))
}
}
impl<P: Problem + 'static> std::ops::BitAnd for Box<dyn Condition<P>> {
type Output = Box<dyn Condition<P>>;

fn bitand(self, rhs: Self) -> Self::Output {
And::new(vec![self, rhs])
}
}

#[derive(Serialize)]
#[serde(bound = "")]
pub struct Or<P: Problem>(Vec<Box<dyn Condition<P>>>);
impl<P: Problem + 'static> Or<P> {
pub fn new(conditions: Vec<Box<dyn Condition<P>>>) -> Box<dyn Condition<P>> {
Box::new(Self(conditions))
}
}
impl<P: Problem + 'static> Condition<P> for Or<P> {
fn initialize(&self, problem: &P, state: &mut State) {
for condition in self.0.iter() {
condition.initialize(problem, state);
}
}

fn evaluate(&self, problem: &P, state: &mut State) -> bool {
self.0
.iter()
.any(|condition| condition.evaluate(problem, state))
}
}
impl<P: Problem + 'static> std::ops::BitOr for Box<dyn Condition<P>> {
type Output = Box<dyn Condition<P>>;

fn bitor(self, rhs: Self) -> Self::Output {
Or::new(vec![self, rhs])
}
}
70 changes: 70 additions & 0 deletions src/framework/conditions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use crate::{
framework::{components::AnyComponent, state::State},
problems::Problem,
};
use serde::Serialize;

pub trait Condition<P>: AnyComponent {
#[allow(unused_variables)]
fn initialize(&self, problem: &P, state: &mut State) {}
fn evaluate(&self, problem: &P, state: &mut State) -> bool;
}
erased_serde::serialize_trait_object!(<P: Problem> Condition<P>);

#[derive(Serialize)]
#[serde(bound = "")]
pub struct And<P: Problem>(Vec<Box<dyn Condition<P>>>);
impl<P: Problem + 'static> And<P> {
pub fn new(conditions: Vec<Box<dyn Condition<P>>>) -> Box<dyn Condition<P>> {
Box::new(Self(conditions))
}
}
impl<P: Problem + 'static> Condition<P> for And<P> {
fn initialize(&self, problem: &P, state: &mut State) {
for condition in self.0.iter() {
condition.initialize(problem, state);
}
}

fn evaluate(&self, problem: &P, state: &mut State) -> bool {
self.0
.iter()
.all(|condition| condition.evaluate(problem, state))
}
}
impl<P: Problem + 'static> std::ops::BitAnd for Box<dyn Condition<P>> {
type Output = Box<dyn Condition<P>>;

fn bitand(self, rhs: Self) -> Self::Output {
And::new(vec![self, rhs])
}
}

#[derive(Serialize)]
#[serde(bound = "")]
pub struct Or<P: Problem>(Vec<Box<dyn Condition<P>>>);
impl<P: Problem + 'static> Or<P> {
pub fn new(conditions: Vec<Box<dyn Condition<P>>>) -> Box<dyn Condition<P>> {
Box::new(Self(conditions))
}
}
impl<P: Problem + 'static> Condition<P> for Or<P> {
fn initialize(&self, problem: &P, state: &mut State) {
for condition in self.0.iter() {
condition.initialize(problem, state);
}
}

fn evaluate(&self, problem: &P, state: &mut State) -> bool {
self.0
.iter()
.any(|condition| condition.evaluate(problem, state))
}
}
impl<P: Problem + 'static> std::ops::BitOr for Box<dyn Condition<P>> {
type Output = Box<dyn Condition<P>>;

fn bitor(self, rhs: Self) -> Self::Output {
Or::new(vec![self, rhs])
}
}
Loading

0 comments on commit 67c2a2e

Please sign in to comment.