//遗传算法,选择--从染色体池中选择一个染色体--(天择) //找出适应度低于随机数的个体出来----轮盘赌算法 private Chomosone SelectFrom(List <Chomosone> pool) { Chomosone individual = null; //Calc the total fitness float total = 0f; for (int i = pool.Count - 1; i >= 0; i--) { total += 1.0f / pool[i].fitness; //此处求1除以每个适应因子,再求和 } float slice = (float)(total * rand.NextDouble()); //Loop to find the individual float next = 0f; for (int i = pool.Count - 1; i >= 0; i--) { next += 1.0f / pool[i].fitness; if (next >= slice) { individual = pool[i]; break; } } if (individual == null) { individual = pool[pool.Count - 1]; } pool.Remove(individual); return(individual); }
//防止进化过程中产生的最优解被交叉和变异所破坏,可以将每一代中的最优解原封不动的复制到下一代中 public object Clone() { var genesClone = (List <DNA>)genes.Clone <DNA>(); Chomosone clone = new Chomosone(genesClone); clone.fitness = this.fitness; clone.Bounds = this.Bounds; return(clone); }
//遗传算子,模拟生物进化 public Chomosone OnProcess(List <int> rawIds) { List <Chomosone> pool = new List <Chomosone>(); //原始库挑选 List <Chomosone> remain = new List <Chomosone>(); //进化后剩下来的 for (int i = 0; i < poolSize; i++) { pool.Add(new Chomosone(rawIds)); } float minFitness = float.MaxValue; int count = 0; Chomosone chomosone = null; while (count < 1) { remain.Clear(); for (int x = pool.Count - 1; x >= 0; x -= 2) { Chomosone c0 = SelectFrom(pool); Chomosone c1 = SelectFrom(pool); c0.CrossOver(c1); c0.Mutate(); c1.Mutate(); c0.Place(); c1.Place(); remain.Add(c0); remain.Add(c1); } pool.AddRange(remain); count++; //按照适应度大小从小到大排序,从剩余中找出适应度最小的个体 var best = pool.OrderBy(cho => cho.fitness).First(); if (best.fitness != 1 && best.fitness < minFitness) { minFitness = best.fitness; chomosone = (Chomosone)best.Clone();//每次循环找出最优个体 } } Debug.Log("Min fitness : " + minFitness); Debug.Log("Chom fitness : " + chomosone.fitness); //---返回适应度最小的个体 return(chomosone); }
//遗传算法交叉操作--交换随机数和基因长度之间的基因 //genes是一个List<DNA>集合,交换集合中DNA的顺序 public void CrossOver(Chomosone other) { //产生一个随机数,根据随机数大小和突变概率比较,大则发生交叉事件 if (rand.NextDouble() > crossRate) { return; } var chomLength = genes.Count; int pos = rand.Next(chomLength); for (int x = pos; x < chomLength; x++) { var tmpDNA = genes[x]; genes[x] = other.genes[x]; other.genes[x] = tmpDNA; } }