Skip to content
a small framework for describing and running genetic algorithms
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples
src
.gitignore
LICENSE
README.md
package.json
yarn.lock

README.md

genetic

this is a small js framework to describe and run genetic algorithms. The main class exposed is Genetic<Type, Fitness>. The process of describing an evolving ecology is done via a fluent api:

basic docs

withGenesis: (T[]) => Genetic<T, F>

populate the world with an initial population

withFitness: ((T) => F) => Genetic<T, F>

describe a global fitness function, i.e. given a member of the population, statically compute a measure of fitness. If the Fitness measure is not implicitly comparable, you must implement a comparator.

selectingOn: ((Score<T, F>[]) => [T, T]) => Genetic<T, F>

Given a scored population, decide a way to select for mating in the new population.

matingBy: ((T, T) => [T, T]) => Genetic<T, F>

Given two members chosen to mate, decide how genetic crossover works.

mutatingBy: ((T, T) => [T, T]) => Genetic<T, F>

Given two members chosen to mate, decide how random mutation works.

shouldMate: (mom: T, dad: T) => boolean

Given a pair selected to mate, decide whether or not they are to mate. Likely you want to use a probability heuristic here, e.g. shouldMate = Genetic.withProbability(0.3)

mutationOccursFor: (individual: T) => boolean

Given an individual moving to the next generation, decide whether or not they are subject to random mutation. Likely you want to use a probability heuristic here, e.g. shouldMate = Genetic.withProbability(0.1)

example

For example: a word finder:

  const stringFinder: Genetic<string, number> = new Genetic()
    .withGenesis(times(250, () => Words.sampleOfLen(len).join('')))
    .matingBy((mother, father) => {
      const len = mother.length;
      let c1 = Math.floor(Math.random() * len);
      let c2 = Math.floor(Math.random() * len);
      if (c1 > c2) {
        [c1, c2] = [c2, c1];
      }
      const mid = c2 - c1;
      const son = father.substr(0, c1) + mother.substr(c1, mid) + father.substr(c2);
      const daughter = mother.substr(0, c1) + father.substr(c1, mid) + mother.substr(c2);
      return [son, daughter];
    })
    .mutatingBy(s => {
      const i = Math.floor(Math.random() * s.length);
      return replaceAt(s, i, Words.sample());
    })
    .selectingOn(list => [weightedRandom(list), weightedRandom(list)])
    .withStatsEvery(100)
    .doOnUpdates(doOnUpdates)
    .withFitness(w => {
      let correct = 0;
      for (let i = 0; i < len; i++) {
        if (w.charAt(i) === solution.charAt(i)) {
          correct++;
        }
      }
      return correct / len;
    });
  stringFinder.evolveWhile((i, s) => get(s, 'max') !== 1);
You can’t perform that action at this time.