// With such approach best decision will be randomized a bit faster public string Mutate(string input, int lowerBound, int upperBound) { var result = input; for (var i = 0; i < _times; ++i) { if (!(_random.NextDouble() <= _chance)) { continue; } var index = _random.Next(input.Length / BinaryConvertor.IntBytes); var replaceFrom = index * BinaryConvertor.IntBytes; var replaceTo = replaceFrom + BinaryConvertor.IntBytes; var inner = input.Substring(replaceFrom, BinaryConvertor.IntBytes); var oldValue = Math.Abs(BinaryConvertor.BinaryStringToInts(inner)[0]); var newValue = _random.Next(-oldValue, oldValue); result = input.Substring(0, replaceFrom) + BinaryConvertor.IntsToBinaryString(newValue) + input.Substring(replaceTo); } return(result); }
private static void Compute <TF>(AlgorithmOptions options, bool useCache = true) where TF : IFunction, new() { var function = useCache ? (IFunction) new Cached <TF>() : new TF(); var solved = new Algorithm(options).Execute(function); var result = BinaryConvertor.BinaryStringToInts(solved); Console.WriteLine($"Computed {function.GetType()}: {string.Join(", ", result)}"); }
public void Print(IEnumerable <string> population, Func <string, double> fitnessLambda) { Console.WriteLine($"CYCLE {_cycle}"); var total = 0d; foreach (var child in population) { foreach (var integer in BinaryConvertor.BinaryStringToInts(child)) { Console.Write($"{integer} "); } var fitness = fitnessLambda(child); total += fitness; Console.WriteLine($": {fitness}"); } var average = total / population.Count(); var diff = (average - _lastFitness) / _lastFitness * 100; Console.WriteLine($"Average fitness: {average} ({diff}%)\n"); _lastFitness = average; ++_cycle; }
public double Fitness(IFunction function, string input) { return(function.Compute(BinaryConvertor.BinaryStringToInts(input))); }
private bool IsValid(string population) { var ints = BinaryConvertor.BinaryStringToInts(population); return(ints.All(i => i >= _options.LowerBound && i <= _options.UpperBound)); }