evolution 0.1.11

  • Readme
  • Changelog
  • Example
  • Installing
  • 50

Evolution #

An optimization library based on evolutionary algorithms for use in dart and flutter projects.

Getting started #

Add the dependency to your pubspec.yaml file:

dependencies:
  evolution: #latest version

Add the import statement to your source files:

import 'package:evolution/evolution.dart' ;

Or, give it a try and run the example:

dart ./example/main.dart 

The example consists of some simple optimization tasks:

  • Sphere100 is a version of the sphere function with global minimum at (100.0, ..., 100.0).
  • Sphere100 (restricted) is the same problem solved on a restricted search space.
  • Ackley10 is a version of the ackley function with global minimum at (10.0, ..., 10.0).
  • Ackley100 is a version of the ackley function with global minimum at (100.0, ..., 100.0).
  • Ackley100 (restricted) is the same problem solved on a restricted search space.

It will run 10 trials of the same problem, printing the number of the trial , the fitness value [f] (small is better) and the solution [ag] represented by an Agent.

Build a simple algorithm #

  1. Generate an initial population of candidate solutions (Agents), each of which will have property values of 0.0:
Population start = generatePopulation(
    sizeN, // number of [Agent]s in the population
    positions, // number of variables, i.e dimensionality of the problem
    Random(seed), // pass a random number generator object to the Population
    fitness, // gibe each Agents an evaluation function
  );
  1. Mutate the population. You can specify a weight factor to control the impact of mutation.
Population mutated = start.mutation();

Instead, you can use the imperative version:

Population mutated = start.mutationI();
  1. Generate a differential population of size [diffN].
Population differential = mutated.differential(diffN);
  1. Select a portion of the population of [sizeN] as survivors.
Population selected = differential.sorted().select(sizeN);

Instead, you can use the imperative version:

Population selected = differential.sortedI().selectI(sizeN);
  1. Loop!

Try the Differential Evolution algorithm #

A more specific algorithm is Differential Evolution. It is defined as:

/// A version of Differential Evolution with unrestricted search space.
Agent diff(
  int positions, // number of variables, i.e dimensionality of the problem
  int sizeN, // number of [Agent]s in the population
  int bestN, // number of [Agent]s selected by fitness
  int randN, // number of [Agent]s randomly selected
  int diffN, // number of [Agent]s generated by differential evolution
  int seed, // seeding the random number generator
  int steps, // number of generations
  double w, // weighting factor used in differential evolution
  double Function(List<double>) fitness, // evaluation function
) {
  Random r = Random(seed);

  int z = 0;
  Population p0 = generatePopulation(
    sizeN,
    positions,
    r,
    fitness,
  );

  while (z < steps) {
    double wz = w / ((z == 0 ? 1 : z)).toDouble();
    
    // best survivors
    Population best = p0.sorted().select(bestN);

    // mutation
    Population mutated = p0.mutation(wz / 10.0);

    // differential operation
    Population differential = mutated.differential(diffN, wz * 10.0);

    // combine subpopulations
    Population all = Population(
        best + differential,
        r,
        fitness);

    // best survivors of combined population
    Population result = all.sorted().select(sizeN);

    p0 = result;
    z++;
  }
  Population res = p0.sorted().select(1);
  return res.first;
}

To improve performace, use a restricted search space and the corresponding version of the algorithm:

Agent diff2(
  int positions, //dimensionality of the problem
  int sizeN, // number of solution candidates to be entered in each new generation 
  int bestN, // number of best solutions selected within on generation 
  int randN, // number of random solutions selected within on generation with arbitrary fitness
  int diffN, //  number of solution candidates generated by differential process in  each generation 
  int seed, // initializing the pseudo-random number generator 
  int steps, // number of generations 
  double w, // spread of mutation 
  double Function(List<double>) fitness, // evaluation function for solution candidates
  double lower, // lower bound of the search space
  double upper, // upper bound of the search space
) {
  Random r = Random(seed);

  int z = 0;
  Population p0 = generatePopulation(sizeN, positions, r, fitness);

  while (z < steps) {
    double wz = w / ((z == 0 ? 1 : z)).toDouble();

    // best survivors
    Population best = p0.sorted().select(bestN);

    // mutation
    Population mutatedConfined = p0.mutation(wz / 10.0).confined(lower, upper);

    // differential operation
    Population differential = mutatedConfined.differential(diffN, wz * 10.0);

    // combine subpopulations
    Population all = Population(
        best + differential,
        r,
        fitness);

    // best survivors of combined population
    Population result = all.sorted().select(sizeN);

    p0 = result;
    z++;
  }

  Population res = p0.sorted().select(1);
  return res.first;
}

Changelog #

0.1.11 #

  • fix issues reported by pana

0.1.10 #

  • improve README

0.1.9 #

  • improve examples

0.1.8 #

  • improve description

0.1.7 #

  • improve documentation

0.1.6 #

  • use optima 0.1.0

0.1.5 #

  • improve documentation

0.1.4 #

  • depend on optima

0.1.3 #

  • improve documentation

0.1.2 #

  • switch from factory constructors to static methods to enable mixins
  • use mixins

0.1.1 #

  • minor bugfixes

0.1.0 #

  • Initial version.

example/main.dart

import 'package:evolution/evolution.dart';
import 'package:optima/optima.dart';

void main() {
  //var seed = DateTime.now().millisecond;
/*
  print(
      'Optimize a version of the sphere function centered at (100.0, ... , 100.0) on the unrestricted version of the problem.');
  10.times((int i) {
    var ret = diff(4, 25, 10, 10, 25, i, 500, 10.0, sphere100);
    print('Sphere100 - Trial Nr.: ${i} - f: ${ret.fitness()} - ag: ${ret}');
    return ret;
  });

  print('Use the version restricted on (50, 150) in each dimension.');
  10.times((int i) {
    var result = diff2(4, 25, 10, 10, 25, i, 500, 10.0, sphere100, 50, 150);
    print(
        'Sphere100 (restricted) - Trial Nr.: ${i} - f: ${result.fitness()} - ag: ${result}');
    return result;
  });

  print(
      'Optimize a version of the ackley function centered at (10.0, ... , 10.0) on the unrestricted version of the problem.');
  10.times((int i) {
    var result = diff(4, 25, 10, 10, 25, i, 1000, 10.0, ackley10);
    print('Ackley10 - Trial Nr.: ${i} - f: ${result.fitness()} - ag: ${result}   ');
    return result;
  });

  print(
      'Optimize a version of the ackley function centered at (100.0, ... , 100.0) on the unrestricted version of the problem.');
  print('This will not find a solution to the problem.');

  10.times((int i) {
    var result = diff(4, 25, 10, 10, 25, i, 1000, 10.0, ackley100);
    print('Ackley100 - Trial Nr.: ${i} - f: ${result.fitness()} - ag: ${result}');
    return result;
  });
*/
  print('Use the version restricted on (50, 150) in each dimension.');
  10.times((int i) {
    var result = diff2(4, 25, 10, 10, 25, i, 1000, 100.0, ackley100, 50, 150);
    print(
        'Ackley100 (restricted) - Trial Nr.: ${i} - f: ${result.fitness()} - ag: ${result}');
    return result;
  });
}

/// The Ackley function centered at (10.0, ... , 10.0)
double Function(List<double>) ackley10 = (l) {
  List<double> m = l.map((d) {
    return d - 10.0;
  }).toList();

  return ackley(m);
};

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  evolution: ^0.1.11

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:evolution/evolution.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
0
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
50
Learn more about scoring.

We analyzed this package on Jul 11, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.15

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.7.0 <3.0.0
optima ^0.1.1 0.1.3