Skip to content

Instantly share code, notes, and snippets.

@paveltimofeev
Created May 31, 2018 21:33
Show Gist options
  • Save paveltimofeev/f8c752cea0132015a94405e5e16ba797 to your computer and use it in GitHub Desktop.
Save paveltimofeev/f8c752cea0132015a94405e5e16ba797 to your computer and use it in GitHub Desktop.
Evolutionary Search Algorithm
using System;
using System.Collections;
using System.Collections.Generic;
public class EvolutionarySearchAlgorithm<T> {
System.Random random = new System.Random();
Func<T, T> mutationFunc;
IComparer<T> evaluationFunc;
/// <param name="mutationFunc">Mutation function return mutated T object</param>
/// <param name="evaluationFunc">Evaluation function, compare two T objects and choose better</param>
public EvolutionarySearchAlgorithm(Func<T, T> mutationFunc, IComparer<T> evaluationFunc)
{
this.mutationFunc = mutationFunc;
this.evaluationFunc = evaluationFunc;
}
/// <summary>
/// Return new population mutated n-times (generations)
/// </summary>
/// <param name="initialPopulation">Initial population</param>
/// <param name="muPercent">Percent of elite population</param>
/// <param name="generations">Number of passes</param>
/// <returns></returns>
public List<T> Search( List<T> initialPopulation, float muPercent, int generations = 1 )
{
if (initialPopulation == null || initialPopulation.Count == 0)
throw new ArgumentOutOfRangeException("initialPopulation");
if (muPercent <= 0 || muPercent > 1)
throw new ArgumentOutOfRangeException("muPercent");
int mu = (int)((float)initialPopulation.Count * muPercent);
T[] population = new T[initialPopulation.Count];
initialPopulation.CopyTo(population, 0);
for (int i = 0; i <= generations; i++)
{
Array.Sort<T>(population, shuffleFunc);
mutatePopulation(ref population);
evaluateAndSort(ref population);
if( i < generations)
removeLambdaPart(ref population, mu);
}
return new List<T>(population);
}
private int shuffleFunc(T x, T y)
{
return random.Next(2) - 1;
}
private void mutatePopulation(ref T[] population)
{
for (int i = 0; i < population.Length; i++)
{
population[i] = mutationFunc(population[i]);
}
}
private void evaluateAndSort(ref T[] population)
{
Array.Sort<T>(population, evaluationFunc);
}
private void removeLambdaPart(ref T[] population, int mu)
{
for (int i = 0; i < population.Length; i++)
{
if (i > mu)
{
population[i] = population[i - (mu + 1) * (int)Math.Floor((double)i / (mu + 1))];
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment