private static int swapChance = 9900; // 2 / 10000 #endregion Fields #region Methods private static double CalculateFitness(Chromosome c) { return CalculateFitness(c, false); }
// Lower = better. private static double CalculateFitness(Chromosome c, bool explain) { double targetValue = 0; c.FitnessBonus = 1; c.Fitness = 0; // I forget why I comment out trying to get other variables. foreach (KeyValuePair<string, Dictionary<string, double>> kvp in dict) { double r, s, u, v, w, x, y, z; // For now, gotta change these when changing problem sets! //kvp.Value.TryGetValue("R", out r); //kvp.Value.TryGetValue("S", out s); //kvp.Value.TryGetValue("U", out u); //kvp.Value.TryGetValue("V", out v); //kvp.Value.TryGetValue("W", out w); kvp.Value.TryGetValue("X", out x); kvp.Value.TryGetValue("Y", out y); kvp.Value.TryGetValue("Z", out z); //c.R = r; //c.S = s; //targetValue = u; //c.U = u; // Er, we don't want this in the equation. This is our target! //c.V = v; //c.W = w; c.X = x; // For simple equations, X is our target. //c.Y = y; // For simple equations, Y is our target. targetValue = y; //targetValue = z; //c.Z = z; c.ForceCalculate(); if (explain) Console.WriteLine(targetValue); if (explain) Console.WriteLine(c.X); if (explain) Console.WriteLine(c.Y); //Console.WriteLine(c.Result); //Console.WriteLine(c.Result / targetValue); //Console.WriteLine(c.Genes.Count); if (explain) Console.WriteLine(c.IsValid); if (!c.IsValid) { c.Fitness += maxFitness; break; } double tFitness = Math.Max(Math.Abs(c.Result - targetValue), minFitness); if (explain) Console.WriteLine("Base: " + tFitness); // Penalize Chromosomes that differ between real and validated lengths. // Because validation can increase the length of the string for evaluation purposes - turning XX into X*X, for example - we won't use this right now. //int ld = Math.Abs(c.GeneString.Length - c.GeneStringValidated.Length); int ld = 0; // On second thought, just penalize long strings. int thresholdLength = 20; int deltaLength = (c.GeneString.Length - thresholdLength); ld = (deltaLength > 0) ? deltaLength : 0; if (explain) Console.WriteLine("LD: " + ld); if (ld != 0) { if (explain) Console.WriteLine("Length Penalty"); tFitness *= malusLength * ld; c.FitnessBonus *= malusLength * ld; } //else //{ // tFitness /= bonusValid; // c.FitnessBonus /= bonusValid; //} //deltaLength = (c.GeneString.Length - bestEverChromosomeString.Length); //ld = (deltaLength > 0) ? deltaLength : 0; //if (explain) Console.WriteLine("LD: " + ld); //if (ld != 0) //{ // if (explain) Console.WriteLine("Length Penalty"); // tFitness *= malusLength * ld; // c.FitnessBonus *= malusLength * ld; //} //deltaLength = (c.GeneString.Length - c.GeneStringValidated.Length); //ld = (deltaLength > 0) ? deltaLength : 0; //if (explain) Console.WriteLine("Silence: " + ld); //if (ld != 0) //{ // if (explain) Console.WriteLine("Silence Penalty"); // tFitness *= malusSilence * ld; // c.FitnessBonus *= malusSilence * ld; //} // *0 or 0* is a pain. // As is 0X or X0... so variables negated in such a fashion should result in penalty as well. if (c.GeneString.Contains("*0") || c.GeneString.Contains("0*") || c.GeneStringValidated.Contains("*0") || c.GeneStringValidated.Contains("0*")) { if (explain) Console.WriteLine("*Zero Penalty"); tFitness *= malusTimesZero; c.FitnessBonus *= malusTimesZero; } // For now, gotta change these when changing problem sets! //char[] vars = { 'V', 'W', 'X', 'Y', 'Z' }; //char[] vars = { 'V', 'W', 'X' }; char[] vars = { 'X' }; char[] vars2 = { 'R', 'S', 'T', 'U', 'V', 'W', 'Y', 'Z' }; //List<char> varsAllList = new List<char>(); // Penalize 0X, X0, 1X, and X1. foreach (char ch in "RSTUVWXYZ") { if (c.GeneString.Contains("0" + ch) || c.GeneString.Contains(ch + "0")) { if (explain) Console.WriteLine(ch + "*Zero Penalty"); tFitness *= malusTimesZero; c.FitnessBonus *= malusTimesZero; } //varsAllList.Add(ch); } foreach (char ch in "RSTUVWXYZ") { if ( c.GeneString.Contains("1" + ch) || c.GeneString.Contains(ch + "1") || c.GeneString.Contains("1*" + ch) || c.GeneString.Contains(ch + "*1") || c.GeneString.Contains(ch + "/1") ) { if (explain) Console.WriteLine(ch + "*One Penalty"); tFitness *= malusTimesOne; c.FitnessBonus *= malusTimesOne; } } // I don't recall why I penalize this. foreach (char ch1 in "RSTUVWYZ") { foreach (char ch2 in "RSTUVWXYZ") { if (c.GeneString.Contains(ch1.ToString() + ch2.ToString()) || c.GeneString.Contains(ch2.ToString() + ch1.ToString())) { if (explain) Console.WriteLine(ch1 + ch2 + " Penalty"); tFitness *= malusTimesZero; c.FitnessBonus *= malusTimesZero; } } } //char[] varsAll = varsAllList.ToArray(); // Select against variables we don't want in the string. foreach (char ch in vars2) { if (c.GeneString.Count(n => n.Equals(ch)) >= 1) { if (explain) Console.WriteLine(ch + " Penalty"); tFitness *= malusGene * c.GeneString.Count(n => n.Equals(ch)); c.FitnessBonus *= malusGene * c.GeneString.Count(n => n.Equals(ch)); } } foreach (char ch in vars) { // Penalize the Chromosome if our intended variables aren't included. if (!c.GeneStringValidated.Contains(ch)) { if (explain) Console.WriteLine("Required Var Penalty"); tFitness *= malusRequiredVariable; c.FitnessBonus *= malusRequiredVariable; } // Reward if our intended variable(s) are. else { if (explain) Console.WriteLine("Required Var Bonus"); tFitness /= bonusGene; c.FitnessBonus /= bonusGene; } } if (explain) Console.WriteLine(tFitness); if (explain) Console.ReadLine(); if (tFitness > maxFitness) tFitness = maxFitness; c.Fitness += tFitness; } return c.Fitness; }
//public static Chromosome Crossover(Chromosome c, Chromosome b) //{ // return Crossover(c, b, 1); //} /* * Apparently, I very much need to review this code. As noted, my first attempt(s) at making this work properly, er, didn't. * There may still be room for different approaches to crossover, but if I can verify that this one works as I intend, * and that the fossil code doesn't, I can delete it entirely. * * Not that it can't be optimized. */ /// <summary> /// Takes two parent Chromosomes, and returns a child Chromosome that derives from a crossover of both. /// </summary> /// <param name="c">One parent Chromosome.</param> /// <param name="b">Another parent Chromosome.</param> /// <returns>A child Chromosome.</returns> public static List<Chromosome> Crossover(Chromosome c, Chromosome b) { List<Chromosome> children = new List<Chromosome>(); /* * Meh. My first attempt at this sucked. :) * Here, we take a random starting point in each Chromosome. * Then, we calculate a random length, no longer than the distance between the starting point and the end. */ //int ics = r.Next(0, c.genes.Count); //int ibs = r.Next(0, b.genes.Count); //int icl = r.Next(1, c.genes.Count - ics); //int ibl = r.Next(1, b.genes.Count - ibs); int ic = r.Next(1, c.Genes.Count - 1); int ib = r.Next(1, b.Genes.Count - 1); //icl = Math.Max(icl, minLength); //ibl = Math.Max(ibl, minLength); //if (ics + icl > c.genes.Count) //{ // ics -= Math.Abs(ics + icl - c.genes.Count); //} //if (ibs + ibl > b.genes.Count) //{ // ibs -= Math.Abs(ibs + ibl - b.genes.Count); //} //Console.WriteLine("c.Count: " + c.genes.Count + "; b.Count: " + b.genes.Count); //Console.WriteLine("c.Indices: " + ics + " " + (c.genes.Count - ics) + "; b.Indices: " + ibs + " " + (b.genes.Count - ibs)); //Console.WriteLine("c.Length: " + icl + "; b.Length: " + ibl); //Console.WriteLine(c.GeneString); //Console.WriteLine(b.GeneString); // Get a section of Chromosome c. ArrayList tcal1, tcal2; // = c.genes.GetRange(ics, icl); // Get a section of Chromosome b. ArrayList tbal1, tbal2; // = b.genes.GetRange(ibs, ibl); //tcal = c.genes.GetRange(0, ics); //tbal = b.genes.GetRange(ics, b.genes.Count - ics); tcal1 = c.Genes.GetRange(0, ic); tcal2 = c.Genes.GetRange(ic, c.Genes.Count - ic); tbal1 = b.Genes.GetRange(0, ib); tbal2 = b.Genes.GetRange(ib, b.Genes.Count - ib); // Create an array list to combine the sections above. ArrayList temp = new ArrayList(); ArrayList temp2 = new ArrayList(); //temp.AddRange(tcal1); //temp.AddRange(tbal2); //temp2.AddRange(tbal1); //temp2.AddRange(tcal2); int ir = r.Next(0, 2); //// I could have this entirely randomized - pick part of one, part of the other, at random, and then put them together, at random. //// For now, we'll take either a1 + b2, or b1 + a2. ir = 0; // I could do this in ternary, but this is just clearer. switch (ir) { // Add c first. case 0: temp.AddRange(tcal1); temp.AddRange(tbal2); break; // Add b first. case 1: temp.AddRange(tbal2); temp.AddRange(tcal1); break; } ir = r.Next(0, 2); ir = 0; switch (ir) { // Add c first. case 0: temp2.AddRange(tbal1); temp2.AddRange(tcal2); break; // Add b first. case 1: temp2.AddRange(tcal2); temp2.AddRange(tbal1); break; } // Create a Chromosome from the resulting combination of ranges. Chromosome t = new Chromosome(temp); t.parentA = c.GeneString; t.parentB = b.GeneString; Chromosome t2 = new Chromosome(temp2); t2.parentA = b.GeneString; t2.parentB = c.GeneString; //Console.WriteLine(c.genes.Count); //Console.WriteLine(b.genes.Count); //Console.WriteLine(t.genes.Count); //Console.WriteLine(t2.genes.Count); // Testing. //Chromosome tc = new Chromosome(tcal); //Chromosome tb = new Chromosome(tbal); //Console.WriteLine(tc.GeneString); //Console.WriteLine(tb.GeneString); //Console.WriteLine(t.parentA); //Console.WriteLine(t.parentB); //Console.WriteLine(t.GeneString); children.Add(t); children.Add(t2); return children; }
static void DisplayChromosomeAt(Chromosome c, int x, int y) { ConsoleColor fc = Console.ForegroundColor; ConsoleColor bc = Console.BackgroundColor; Console.SetCursorPosition(x, y); Console.WriteLine("Raw: " + c.GeneString); Console.SetCursorPosition(x, y + 1); Console.WriteLine("Processed: " + c.GeneStringValidated); Console.SetCursorPosition(x, y + 2); if (!c.IsValid) Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Evaluated: " + c.Result); Console.SetCursorPosition(x, y + 3); if (!c.IsValid) Console.ForegroundColor = ConsoleColor.Red; if (c.Fitness <= minFitness * dict.Count) Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Fitness: " + c.Fitness + " " + c.FitnessBonus); Console.ForegroundColor = fc; Console.SetCursorPosition(0, y + 4); Console.WriteLine("A: " + c.ParentA); Console.SetCursorPosition(0, y + 5); Console.WriteLine("B: " + c.ParentB); }
//private void getData() //{ // XmlSerializer xmlS = new XmlSerializer(typeof(List<Chromosome>)); // try // { // FileStream fs = new FileStream("C:/data.xml", FileMode.Open); // population = (List<Chromosome>)xmlS.Deserialize(fs); // fs.Close(); // historyPresent = true; // } // catch (Exception _e) { // population = new List<Chromosome>(); // historyPresent = false; // } //} //private void saveData() //{ // XmlSerializer xmlS = new XmlSerializer(typeof(List<Chromosome>)); // try // { // FileStream fs = new FileStream("C:/data.xml", FileMode.OpenOrCreate); // if(population.Count == 0) // getNewPopulation(); // xmlS.Serialize(fs, population); // fs.Flush(); // fs.Close(); // } // catch (Exception _e) // { // population = new List<Chromosome>(); // } //} public void getNewPopulation(int problemSize, bool flag) { if (flag) { for (int i = 0; i < 10; i++) { Chromosome c = new Chromosome(problemSize); for (int j = 0; j < c.mass.Count; j++) { c.mass[j] = rand.NextDouble(); c.force[j] = rand.NextDouble(); } population.Add(c); } } else { crossOver(); } }
public void mutation(Chromosome c) { if(population.FirstOrDefault().mass.Count <= 2) return; int pointOfMutation = rand.Next(0, c.force.Count); c.force[pointOfMutation] = rand.NextDouble(); c.mass[pointOfMutation] = rand.NextDouble(); }
public double fitnessFuction(Chromosome c) { double average = 0; for (int i = 0; i < c.force.Count; i++) { //We want a good amount of force. average += c.force[i]; //mass is not good. average -= c.mass[i]; } //averaging over all the values inside chromosome. average = average / c.mass.Count; //finding the max if (average > max) { max = average; bestFit = c; Debug.Log("Max : " + average); } return average; }
private void Initialize() { Lx = MathF.Ceiling(MathF.Log2((b - a) * MathF.Pow(10, q) + 1)); Ly = MathF.Ceiling(MathF.Log2((d - c) * MathF.Pow(10, q) + 1)); hx = (b - a) / (MathF.Pow(2, Lx) - 1); hy = (d - c) / (MathF.Pow(2, Ly) - 1); var points = new List <Vector2>(); float fitnessFunctionsSum = 0; float stepX = (b - a) / 4f; float stepY = (d - c) / 3f; points.Add(new Vector2(a + stepX, c + stepY)); for (int i = 1; i <= _population.Count - 1; i++) { var point = points[i - 1]; if (i % 3 == 0) { points.Add(new Vector2(points[0].X, point.Y + stepY)); continue; } points.Add(new Vector2(point.X + stepX, point.Y)); } for (int i = 0; i < points.Count; i++) { var chromosomeX = new Chromosome { Parameter = points[i].X }; var chromosomeY = new Chromosome { Parameter = points[i].Y }; var fitnessFunctionValue = _fitnessFunction(chromosomeX.Parameter, chromosomeY.Parameter); fitnessFunctionsSum += fitnessFunctionValue; var individual = new Individual { Сhromosomes = new List <Chromosome> { chromosomeX, chromosomeY }, FitnessFunctionValue = fitnessFunctionValue }; _population.Individuals.Add(individual); } _population.FitnessFunctionSum = fitnessFunctionsSum; if (CheckIfExistsFitnessFunctionValueLessZero()) { RecalculateFitnessFunctionValues(); } max = _population.FitnessFunctionSum / _population.Count; Console.WriteLine(_population.FitnessFunctionSum / _population.Count); }
public Chromosome ChaoticLS(Chromosome chrom) //Jia D , Zheng G , Khan M K . An effective memetic differential evolution algorithm based on chaotic local search[J]. Information ences, 2011, 181(15):3175-3187. { Chromosome betterChrom = Chromosome.Clone <Chromosome>(chrom); //use this method doing deep copy double beta = myRandom.NextDouble(0.0, 1.0); double u = 4.0, m = 1000; double betac, lambda; int Sl = (int)Math.Round(chrom.ChromosomeSize / 5.0); if (Sl < 1) { Sl = 1; } int[] loc = myRandom.NextUnique(0, chrom.ChromosomeSize - 1, Sl); //Random ran = new Random(Guid.NewGuid().GetHashCode()); while (true) { if (beta != 0.25 && beta != 0.5 && beta != 0.75) { break; } beta = myRandom.NextDouble(0.0, 1.0); } for (int i = 0; i < chrom.PopulationSize * 5; i++) { beta = u * beta * (1 - beta); foreach (var j in loc) { betac = chrom.LowerBd[j] + beta * (chrom.UpperBd[j] - chrom.LowerBd[j]); if (chrom.Fit > 0.0) { lambda = 1 - Math.Pow(Math.Abs((chrom.Fit - 1) / chrom.Fit), m); } else { lambda = 1 - Math.Pow(Math.Abs((chrom.Fit + 1) / chrom.Fit), m); } betterChrom.chromosome[j] = (1 - lambda) * chrom.chromosome[j] + lambda * betac; } betterChrom.CheckBoundary(); betterChrom.SetChromDecimalPlace(); betterChrom.SolveFitness(); if (betterChrom.Fit < chrom.Fit) { //Console.WriteLine("local search find a better individuals!"); break; } } if (betterChrom.Fit < chrom.Fit) { return(betterChrom); } else { return(chrom); } }
public Chromosome LocalSearch(Chromosome chrom) { return(CLSMethodEvent?.Invoke(chrom)); }
public List <Chromosome> Execute() { //using select method Selection SL = new Selection(); SL.SelectMethodEvent += SL.Select_Tournament; //Chromosome result=SL.Select(Population pop); //using cross method Crossover CX = new Crossover(); CX.CrossMethodEvent += CX.CrossOver_MIX; // List<Chromosome> result=CX.Cross(Chromosome mom, Chromosome dad); //using mute method Mutation MU = new Mutation(); MU.MuteMethodEvent += MU.DRM; //Chromosome result = MU.Mute(Chromosome chrom); //using chaotic local search ChaoticLocalSearch LS = new ChaoticLocalSearch(); LS.CLSMethodEvent += LS.ChaoticLS; #region All population evolutionary algebraic processes //Iterative evolution Random ran = new Random(Guid.NewGuid().GetHashCode()); List <Chromosome> result1 = new List <Chromosome>(); Chromosome result2 = new Chromosome(); int maxSameIt = 0; for (int it = 0; it < MaxIteration; it++) { #region one population for (int popi = 0; popi < NumPopulation; popi++) { // Update iteration times PopsOfGa[popi].CurrentIteration = it;//Current iteration of evolution PopsOfGaCX[popi].CurrentIteration = it; PopsOfGaMU[popi].CurrentIteration = it; //HistBestChromOfPops[popi].CurrentIteration = it; for (int k = 0; k < PopsOfGa[popi].PopulationSize; k++) { PopsOfGa[popi].ChromsOfPop[k].CurrentIteration = it; } for (int k = 0; k < PopsOfGaCX[popi].ChromsOfPop.Count; k++) { PopsOfGaCX[popi].ChromsOfPop[k].CurrentIteration = it; } for (int k = 0; k < PopsOfGaMU[popi].ChromsOfPop.Count; k++) { PopsOfGaMU[popi].ChromsOfPop[k].CurrentIteration = it; } //select and cross for (int k = 0; k < numOffspringsOfCross[popi] - 1; k = k + 2) { //select operator int Chroms1Index = SL.Select(PopsOfGa[popi]); int Chroms2Index = SL.Select(PopsOfGa[popi]); //cross operator result1 = CX.Cross(PopsOfGa[popi].ChromsOfPop[Chroms1Index], PopsOfGa[popi].ChromsOfPop[Chroms2Index]); PopsOfGaCX[popi].ChromsOfPop.AddRange(result1); } PopsOfGaCX[popi].ChromsOfPop.RemoveRange(0, numOffspringsOfCross[popi]); //Console.WriteLine("PopsOfGaCX before solve:"); //PopsOfGaCX[popi].ChromsOfPopCWFitAndChroms(); PopsOfGaCX[popi].ChromsOfPopSolveFit();// * solve every individuals fitness //Console.WriteLine("PopsOfGaCX after solve:"); //PopsOfGaCX[popi].ChromsOfPopCWFitAndChroms(); //mute operator for (int k = 0; k < numPointOfMute[popi]; k++) { int Chroms1IndexMu = ran.Next(0, PopsOfGa[popi].ChromsOfPop.Count); result2 = MU.Mute(PopsOfGa[popi].ChromsOfPop[Chroms1IndexMu]); PopsOfGaMU[popi].ChromsOfPop.Add(result2); } PopsOfGaMU[popi].ChromsOfPop.RemoveRange(0, numPointOfMute[popi]); //Console.WriteLine("PopsOfGaMU before solve:"); //PopsOfGaMU[popi].ChromsOfPopCWFitAndChroms(); //Console.WriteLine("PopsOfGaMU after solve:"); PopsOfGaMU[popi].ChromsOfPopSolveFit(); //PopsOfGaMU[popi].ChromsOfPopCWFitAndChroms(); //combine three population for (int iCx = 0; iCx < PopsOfGaCX[popi].PopulationSize; iCx++) { PopsOfGa[popi].ChromsOfPop.Add(Chromosome.Clone <Chromosome>(PopsOfGaCX[popi].ChromsOfPop[iCx])); } for (int iMu = 0; iMu < PopsOfGaMU[popi].PopulationSize; iMu++) { PopsOfGa[popi].ChromsOfPop.Add(Chromosome.Clone <Chromosome>(PopsOfGaMU[popi].ChromsOfPop[iMu])); } //Console.WriteLine($"PopsOfGa+PopsOfGaCX+PopsOfGaMU[{popi}] solve but before sort:"); //PopsOfGa[popi].ChromsOfPopCWFitAndChroms(); //Console.WriteLine($"sort:"); //sort(ascending) with fitness PopsOfGa[popi].FitSort();// //PopsOfGa[popi].ChromsOfPopCWFitAndChroms(); // remove the bad ones PopsOfGa[popi].ChromsOfPop.RemoveRange(PopulationSize[popi], (numOffspringsOfCross[popi] + numPointOfMute[popi])); //Console.WriteLine($"PopsOfGa[{popi}] after remove:"); //PopsOfGa[popi].ChromsOfPopCWFitAndChroms(); //Local search PopsOfGa[popi].ChromsOfPop[0] = Chromosome.Clone <Chromosome>(LS.LocalSearch(PopsOfGa[popi].ChromsOfPop[0])); //elitism in a population if (HistBestChromOfPops[popi].Fit > PopsOfGa[popi].ChromsOfPop[0].Fit) { HistBestChromOfPops[popi] = Chromosome.Clone <Chromosome>(PopsOfGa[popi].ChromsOfPop[0]); } else { //PopsOfGa[popi].ChromsOfPop[0] = (Chromosome)DeepClone(HistBestChromOfPops[popi]);//elitism PopsOfGa[popi].ChromsOfPop[0] = Chromosome.Clone <Chromosome>(HistBestChromOfPops[popi]);//elitism } HistBestChromOfPops[popi].CurrentIteration = it; } #endregion popi //Take turns to swap the best:The best value of the next population gives the best value of the previous population if (NumPopulation == 1) { //HistBestChromOfGa[it] = (Chromosome)DeepClone(HistBestChromOfPops[0]); HistBestChromOfGa[it] = Chromosome.Clone <Chromosome>(HistBestChromOfPops[0]); } else { //Chromosome tmepChromo = (Chromosome)DeepClone(PopsOfGa[0].ChromsOfPop[0]); Chromosome tmepChromo = Chromosome.Clone <Chromosome>(PopsOfGa[0].ChromsOfPop[0]); for (int popi = 0; popi < NumPopulation; popi++) { if (HistBestChromOfGa[it].Fit > PopsOfGa[popi].ChromsOfPop[0].Fit) { //HistBestChromOfGa[it] = (Chromosome)DeepClone(PopsOfGa[popi].ChromsOfPop[0]); HistBestChromOfGa[it] = Chromosome.Clone <Chromosome>(PopsOfGa[popi].ChromsOfPop[0]); } else { //PopsOfGa[popi].ChromsOfPop[0] = (Chromosome)DeepClone(HistBestChromOfGa[it]); PopsOfGa[popi].ChromsOfPop[0] = Chromosome.Clone <Chromosome>(HistBestChromOfGa[it]); } //if (PopsOfGa[popi + 1] != null) if ((popi + 1) < NumPopulation) { //PopsOfGa[popi].ChromsOfPop[0] = (Chromosome)DeepClone(PopsOfGa[popi + 1].ChromsOfPop[0]); PopsOfGa[popi].ChromsOfPop[0] = Chromosome.Clone <Chromosome>(PopsOfGa[popi + 1].ChromsOfPop[0]); } if (popi == (NumPopulation - 1) && popi != 0) { //PopsOfGa[NumPopulation - 1].ChromsOfPop[0] = (Chromosome)DeepClone(tmepChromo); PopsOfGa[NumPopulation - 1].ChromsOfPop[0] = Chromosome.Clone <Chromosome>(tmepChromo); } } } if (it > (int)Math.Round(MaxIteration * 0.3)) { for (int itsame = 0; itsame < (int)Math.Round(MaxIteration * 0.3); itsame++) { if (Math.Abs(HistBestChromOfGa[it].Fit - HistBestChromOfGa[it - itsame - 1].Fit) < 1e-30) { maxSameIt++; } } if (maxSameIt > (int)Math.Round(MaxIteration * 0.2)) { break; } } // Console.WriteLine($"iteration:{HistBestChromOfGa[it].CurrentIteration},bestFit:{HistBestChromOfGa[it].Fit}"); foreach (double para in HistBestChromOfGa[it].chromosome) { Console.Write($"{para} "); } Console.WriteLine(); Console.WriteLine(); } #endregion return(HistBestChromOfGa); // return globalBestChrom; }