Created
May 31, 2018 21:33
-
-
Save paveltimofeev/f8c752cea0132015a94405e5e16ba797 to your computer and use it in GitHub Desktop.
Evolutionary Search Algorithm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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