/// <summary> /// 执行遗传算法 /// </summary> public void Start() { for (int i = 0; i < maxGenerationSize; i++) { //更新适应度 UpdateFitness(); //按照适应度排序 GenomeList.Sort(); ////如果最优个体的适应性度量值=最差个体的适应性度量值 if (GenomeList.Count == 0 || GenomeList[GenomeList.Count - 1].Fitness == GenomeList[0].Fitness) { break; } //将第解赋值给最优个体 if (Math.Abs(GenomeList[GenomeList.Count - 1].Fitness) < Math.Abs(GenomeList[0].Fitness)) { this.bestGenome = GenomeList[0]; } else { this.bestGenome = GenomeList[GenomeList.Count - 1]; } //选择复制 Selection(); //繁衍子代--交叉 Breed(); //变异 Mutation(); //将下一代种群重新赋值给种群容器 GenomeList = nextGenomeList; } }
/// <summary> /// 更新群体适应度 /// </summary> private void UpdateFitness() { //计算适应度 if (fitnessCalculator == null) { throw new Exception("没有初始化 FitnessFunction 委托"); } foreach (Genome genome in genomeList) { fitnessCalculator(genome); } //按照适应度排序 GenomeList.Sort(); }
public void rankGenomes() { int size = population.Count; //TODO: JUSTIN: This needs to be handled elsewhere. Call it when novelty is calculated in EvolutionAlgorithm.cs so that we can set the objective properly when the others are set. //calculateGenomicNovelty(); /*if(doNovelty) { * measure_novelty(); * }//*/ //reset rank information for (int i = 0; i < size; i++) { if (ranks.Count < (i + 1)) { ranks.Add(new RankInformation()); } else { ranks[i].reset(); } } /*Console.WriteLine("Did it reset properly?"); * foreach (RankInformation r in ranks) * { * Console.WriteLine(r.domination_count + " " + r.rank + " " + r.ranked); * } * Console.WriteLine("Dunno, maybe you should check if that spam is all zeroes and falses.");//*///Yeah. It reset properly. //calculate domination by testing each genome against every other genome for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { update_domination((NeatGenome.NeatGenome)population[i], (NeatGenome.NeatGenome)population[j], ranks[i], ranks[j]); } } //successively peel off non-dominated fronts (e.g. those genomes no longer dominated by any in //the remaining population) List <int> front = new List <int>(); int ranked_count = 0; int current_rank = 1; while (ranked_count < size) { //search for non-dominated front for (int i = 0; i < size; i++) { //continue if already ranked if (ranks[i].ranked) { continue; } //if not dominated, add to front if (ranks[i].domination_count == 0) { front.Add(i); ranks[i].ranked = true; ranks[i].rank = current_rank; } } int front_size = front.Count; //Console.WriteLine("Front " + current_rank + " size: " + front_size); //now take all the non-dominated individuals, see who they dominated, and decrease //those genomes' domination counts, because we are removing this front from consideration //to find the next front of individuals non-dominated by the remaining individuals in //the population for (int i = 0; i < front_size; i++) { RankInformation r = ranks[front[i]]; foreach (RankInformation dominated in r.dominates) { dominated.domination_count--; } } ranked_count += front_size; front.Clear(); current_rank++; } //we save the last objective for potential use as genomic novelty objective int last_obj = population[0].objectives.Length - 1; //fitness = popsize-rank (better way might be maxranks+1-rank), but doesn't matter //because speciation is not used and tournament selection is employed for (int i = 0; i < size; i++) { //population[i].Fitness = (size+1)-ranks[i].rank;//+population[i].objectives[last_obj]/100000.0; population[i].Fitness = (current_rank + 1) - ranks[i].rank; } /*foreach (RankInformation r in ranks) * { * Console.WriteLine("After ranking: " + r.domination_count + " " + r.rank + " " + r.ranked); * }//*/ population.Sort(); /*foreach (IGenome aye in population) * { * Console.Write(aye.Fitness + " : [" + aye.RealFitness + "] : "); * foreach (double d in aye.objectives) Console.Write(d + " "); * Console.WriteLine(); * }//*/ generation++; /*if(generation%50==0) * this.printDistribution();//*///JUSTIN: Don't do this.. takes up too much space. Also doesn't currently work for multiple runs. }
public void rankGenomes() { int size = population.Count; calculateGenomicNovelty(); if (doNovelty) { measure_novelty(); } //reset rank information for (int i = 0; i < size; i++) { if (ranks.Count < i + 1) { ranks.Add(new RankInformation()); } else { ranks[i].reset(); } } //calculate domination by testing each genome against every other genome for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { update_domination((NeatGenome.NeatGenome)population[i], (NeatGenome.NeatGenome)population[j], ranks[i], ranks[j]); } } //successively peel off non-dominated fronts (e.g. those genomes no longer dominated by any in //the remaining population) List <int> front = new List <int>(); int ranked_count = 0; int current_rank = 1; while (ranked_count < size) { //search for non-dominated front for (int i = 0; i < size; i++) { //continue if already ranked if (ranks[i].ranked) { continue; } //if not dominated, add to front if (ranks[i].domination_count == 0) { front.Add(i); ranks[i].ranked = true; ranks[i].rank = current_rank; } } int front_size = front.Count; Console.WriteLine("Front " + current_rank + " size: " + front_size); //now take all the non-dominated individuals, see who they dominated, and decrease //those genomes' domination counts, because we are removing this front from consideration //to find the next front of individuals non-dominated by the remaining individuals in //the population for (int i = 0; i < front_size; i++) { RankInformation r = ranks[front[i]]; foreach (RankInformation dominated in r.dominates) { dominated.domination_count--; } } ranked_count += front_size; front.Clear(); current_rank++; } //we save the last objective for potential use as genomic novelty objective int last_obj = population[0].objectives.Length - 1; //fitness = popsize-rank (better way might be maxranks+1-rank), but doesn't matter //because speciation is not used and tournament selection is employed for (int i = 0; i < size; i++) { population[i].Fitness = (size + 1) - ranks[i].rank; //+population[i].objectives[last_obj]/100000.0; } population.Sort(); generation++; if (generation % 250 == 0) { this.printDistribution(); } }