/// <summary> /// 更新进化,产生新的种群 /// </summary> void UpdateGenome() { //变比 FitnssScaleSigma(); Sgenome dad = null; Sgenome mum = null; //使用精英选择的方式,取适应性最高的前2,容易陷入局部最优解 GetParent1(ref dad, ref mum); //轮赌盘的选择方式,可以保持子代基因的多样性, //但是最坏情况是适应性更高的基因并没有被遗传下去 //dad = GetParent2(); //mum = GetParent2(); mGenomes.Clear(); while (mGenomes.Count < mPopSize) { Sgenome baby1 = new Sgenome(); Sgenome baby2 = new Sgenome(); //交叉 Crossover(mum.vecBits, dad.vecBits, baby1.vecBits, baby2.vecBits); //突变 Mutate(baby1.vecBits); Mutate(baby2.vecBits); mGenomes.Add(baby1); if (mGenomes.Count < mPopSize) { mGenomes.Add(baby2); } } StartCoroutine(testRoute()); }
/// <summary> /// 采用精英选择的方式选出可以遗传的父母 /// </summary> void GetParent1(ref Sgenome dad, ref Sgenome mum) { //根据适应性排序 mGenomes.Sort((Sgenome x, Sgenome y) => { return(y.dFitness.CompareTo(x.dFitness)); }); dad = mGenomes[0]; mum = mGenomes[1]; }
/// <summary> /// 测试路径,并计算适应性 /// </summary> /// <returns></returns> IEnumerator testRoute() { yield return(new WaitForSeconds(GeneDealy)); for (int i = 0; i < mGenomes.Count; i++) { Sgenome gene = mGenomes[i]; List <int> cmd = decode(gene.vecBits); gene.dFitness = _path.TestRoute(cmd); if (gene.dFitness == 1) { Debug.Log("Find Path"); hasFindPath = true; break; } mTotalFittnessScore += gene.dFitness; yield return(new WaitForSeconds(TestSpeed)); } if (!hasFindPath) { Epoch(); } yield return(0); }