Skip to content
Optimization algorithms realized in Rust
Branch: master
Clone or download
Latest commit 22b4a33 Apr 27, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples Improve modules import. Apr 23, 2019
src Move examples from workspace to examples directory. Apr 23, 2019
.gitignore Added some traits and structs. Jun 25, 2016
Cargo.toml Move examples from workspace to examples directory. Apr 23, 2019
LICENSE Update information Apr 10, 2019
README.md Comments enhancement Apr 26, 2019

README.md

optlib

Current Version Documentation License

Optimization algorithms implemented in Rust

For now optlib provides only genetic algorithm.

Example of optimization

//! Example of optimizing the Schwefel function.
//!
//! y = f(x), where x = (x0, x1, ..., xi,... xn).
//! Global minimum is x' = (420.9687, 420.9687, ...) for any xi lying in [-500.0; 500.0].
//! f(x') = 0
//!
//! # Terms
//! * 'Goal function' - the function for optimization. y = f(x).
//! * `Gene` - a single value of xi.
//! * 'Chromosome' - a point in the search space. x = (x0, x1, x2, ..., xn).
//! * 'Individual' - union of x and value of goal function.
//! * 'Population' - set of the individuals.
//! * 'Generation' - a number of iteration of genetic algorithm.
use optlib::genetic;
use optlib::genetic::creation;
use optlib::genetic::cross;
use optlib::genetic::goal;
use optlib::genetic::logging;
use optlib::genetic::mutation;
use optlib::genetic::pairing;
use optlib::genetic::pre_birth;
use optlib::genetic::selection;
use optlib::genetic::stopchecker;
use optlib::testfunctions;
use optlib::Optimizer;

/// Gene type
type Gene = f32;

/// Chromosomes type
type Chromosomes = Vec<Gene>;

fn main() {
    // General parameters

    // Search space. Any xi lies in [-500.0; 500.0]
    let minval: Gene = -500.0;
    let maxval: Gene = 500.0;

    // Initial population individuals count
    let population_size = 500;

    // Count of xi in chromosomes
    let chromo_count = 15;

    let intervals = vec![(minval, maxval); chromo_count];

    // Make a trait object for a goal function (Schwefel function)
    let goal = goal::GoalFromFunction::new(testfunctions::schwefel);

    // creator will generate an initial population using RandomCreator.
    // Individuals of this population will have random chromosomes within a given interval.
    let creator = creation::vec_float::RandomCreator::new(population_size, intervals.clone());

    // Make a trait object for the pairing.
    // Pairing is the algorithm of selecting individuals for crossbreeding.
    // RandomPairing selects random individuals from the population.
    let pairing = pairing::RandomPairing::new();

    // Crossbreeding algorithm.
    // Make a Cross trait object. The bitwise crossing for float genes.
    let single_cross = cross::FloatCrossExp::new();
    let cross = cross::VecCrossAllGenes::new(Box::new(single_cross));

    // Make a Mutation trait object.
    // Use bitwise mutation (change random bits with given probability).
    let mutation_probability = 15.0;
    let mutation_gene_count = 3;
    let single_mutation = mutation::BitwiseMutation::new(mutation_gene_count);
    let mutation = mutation::VecMutation::new(mutation_probability, Box::new(single_mutation));

    // Pre birth. Throw away new child chromosomes if their genes do not lie within given intervals.
    let pre_births: Vec<Box<genetic::PreBirth<Chromosomes>>> = vec![Box::new(
        pre_birth::vec_float::CheckChromoInterval::new(intervals.clone()),
    )];

    // Stop checker. Stop criterion for genetic algorithm.
    // Stop algorithm if the value of goal function will become less than 10⁻⁴ or
    // after 3000 generations (iterations).
    let stop_checker = stopchecker::CompositeAny::new(vec![
        Box::new(stopchecker::Threshold::new(1e-4)),
        Box::new(stopchecker::MaxIterations::new(3000)),
    ]);

    // Make a trait object for selection. Selection kills the worst individuals.
    // Kill all individuals if the value of goal function is NaN or Inf.
    // Kill worst individuals to keep initial population size.
    let selections: Vec<Box<dyn genetic::Selection<Chromosomes>>> = vec![
        Box::new(selection::KillFitnessNaN::new()),
        Box::new(selection::LimitPopulation::new(population_size)),
    ];

    // Make a loggers trait objects
    let loggers: Vec<Box<genetic::Logger<Chromosomes>>> = vec![
        Box::new(logging::StdoutResultOnlyLogger::new(15)),
        Box::new(logging::TimeStdoutLogger::new()),
    ];

    // Construct main optimizer struct
    let mut optimizer = genetic::GeneticOptimizer::new(
        Box::new(goal),
        Box::new(stop_checker),
        Box::new(creator),
        Box::new(pairing),
        Box::new(cross),
        Box::new(mutation),
        selections,
        pre_births,
        loggers,
    );

    // Run genetic algorithm
    optimizer.find_min();
}

Build all crates:

cargo build --release --all

Run example:

cargo run --bin genetic-schwefel --release

Work result:

Solution:
  420.974975585937500
  420.969146728515625
  420.955078125000000
  421.004760742187500
  420.999511718750000
  421.007263183593750
  420.987487792968750
  421.001800537109375
  420.980499267578125
  420.991180419921875
  421.001068115234375
  420.942718505859375
  420.964080810546875
  420.951721191406250
  420.961029052734375


Goal: 0.000488281250000
Iterations count: 3000
Time elapsed: 2352 ms
You can’t perform that action at this time.