public static (double, double) GeneticAlg( Func <double, double> f, int numberOfGuys, int numberOfIterations ) { var generation = new Bit22[numberOfGuys]; //Wygeneruj osobniki for (int i = 0; i < numberOfGuys; i++) { var x = Program.GetRandomNumber(-1, 2); generation[i] = new Bit22((decimal)x); } Bit22 bestValue = null; for (int i = 0; i < numberOfIterations; i++) { generation = Fit(generation, out bestValue, f); generation = CrossOver(generation); generation = Mutate(generation).ToArray(); } return((double)bestValue.decValue, (f((double)bestValue.decValue))); }
public static decimal GetClostest(decimal p1, int bitIdx) { if (bitIdx < 0 || bitIdx > 21) { throw new Exception("Out of range"); } var p1b = new Bit22(p1).CopyAndMutate(bitIdx); int intValue = Math.Abs(Convert.ToInt32(p1b.value, 2)); return(-1 + (intValue * 0.000001m)); }
public static Bit22[] Fit(Bit22[] generation, out Bit22 fittest, Func <double, double> f) { fittest = generation .Select(x => new { x = x, val = f((double)x.decValue) }) .OrderByDescending(x => x.val) .First().x; var values = generation.Select(x => f((double)x.decValue)); var sum = values.Sum(); int populationNumber = 4; var nextPopulationNumbers = values.OrderByDescending(x => x).Select(x => { var current = (int)Math.Abs(Math.Round(generation.Length * x / sum)); if (populationNumber >= current) { populationNumber -= current; return(current); } else { populationNumber = 0; return(populationNumber); } }).ToList(); var all = nextPopulationNumbers.Sum(x => x); if (all < 4) { int toAdd = 4 - all; int max = nextPopulationNumbers.Max(); nextPopulationNumbers[0] = nextPopulationNumbers[0] + toAdd; } var nextPopulation = new List <Bit22>(); for (int i = 0; i < generation.Length; i++) { for (int j = 0; j < nextPopulationNumbers[i]; j++) { nextPopulation.Add(new Bit22(generation[i].decValue)); } } return(nextPopulation.ToArray()); }
public static Bit22[] CrossOver(Bit22[] generation) { List <Bit22> newGen = new List <Bit22>(); for (int i = 0; i < generation.Length; i++) { // get random partner int partner = RandomExcept(0, generation.Length, i); int crossBit = RandomExcept(0, 21, -1); Bit22 child = generation[i].Cross(generation[partner], crossBit); newGen.Add(child); } return(newGen.ToArray()); }
public Bit22 CopyAndMutate(decimal min, decimal max) { Random rnd = new Random(); var newBit = new Bit22(this.value); do { var bitIdx = rnd.Next(0, 21); char valueAt = this.value[bitIdx]; var stringValue = new StringBuilder(this.value) .Remove(bitIdx, 1) .Insert(bitIdx, valueAt == '1' ? '0' : '1') .ToString(); newBit = new Bit22(stringValue); }while(newBit.decValue < min || newBit.decValue > max); return(newBit); }
public static (double, double) GradMultipleClostests(double x, Func <double, double> f, double step, int maxIter = 1000) { int iter = 0; double max = -1000000; while (iter < maxIter) { double p1 = f(x); double clostest = (double)Bit22.GetClostestOne((decimal)x, 1, f); double p2 = f(clostest); if (p1 > p2) { return(p1, x); } max = p2; iter++; } return(max, x + step); }
public static decimal[] GetClostestMultipleBits(decimal p1, int bitCount) { if (bitCount < 0 || bitCount > 21) { throw new Exception("Out of range"); } var res = new decimal[bitCount]; for (int i = 0; i < bitCount; i++) { var resultBit = new Bit22(p1).CopyAndMutate(21 - i); int intValue = Math.Abs(Convert.ToInt32(resultBit.value, 2)); if (intValue > 3000000) { intValue = 3000000; } res[i] = -1 + (intValue * 0.000001m); } return(res); }
public Bit22 Cross(Bit22 partner, int bitNumber) { return(new Bit22(partner.value.Substring(0, bitNumber) + this.value.Substring(bitNumber, 22 - bitNumber))); }
static void Main(string[] args) { var b = new Bit22(3); int iter = 10; List <double> values = new List <double>(); List <(double, double)> resGrad = new List <(double, double)>(); List <(double, double)> simpleGradResult = new List <(double, double)>(); List <(double, double)> resAnn = new List <(double, double)>(); Func <double, double> f = x => x *Math.Sin(10 *Math.PI *x) + 1; for (int i = 0; i < iter; i++) { values.Add(GetRandomNumber(-1, 2)); } var sw = new Stopwatch(); sw.Start(); foreach (var x in values) { resGrad.Add(Optimizer.GradMultipleClostests(x, f, 0.001f, 1)); } sw.Stop(); var gradT = sw.ElapsedMilliseconds; sw.Start(); foreach (var x in values.Take(1)) { simpleGradResult.Add(Optimizer.SimpleGrad(x, f, 0.001f, 1)); } sw.Stop(); var simpleGradT = sw.ElapsedMilliseconds; sw = new Stopwatch(); sw.Start(); foreach (var x in values) { resAnn.Add(Optimizer.Annealing(x, f, 0.0000001, .9999, 100)); } sw.Stop(); var annT = sw.ElapsedMilliseconds; var maxGrad = resGrad.OrderByDescending(x => x.Item1).First(); var simpleGrad = simpleGradResult.OrderByDescending(x => x.Item1).First(); var maxAnn = resAnn.OrderByDescending(x => x.Item1).First(); sw = new Stopwatch(); sw.Start(); var genetic = Optimizer.GeneticAlg(f, 10, 1000); sw.Stop(); var genT = sw.ElapsedMilliseconds; //Console.WriteLine($"f({maxGrad.Item2}) = {maxGrad.Item1} T={gradT}"); // Console.WriteLine($"f({simpleGrad.Item2}) = {simpleGrad.Item1} T={simpleGradT}"); // Console.WriteLine($"f({maxAnn.Item2}) = {maxAnn.Item1}"); Console.WriteLine($"f({genetic.Item2}) = {genetic.Item1}, T={genT}"); //var bit = new Bit22(-0.999999m); //var clostest = Bit22.GetClostest(-0.999998m, 21); //Console.WriteLine(clostest); //TestGrad(f); }