public override void Evolve() { // calc SGM var sgm = BuildFitnessSgm(this.P); // Evolve the two subpopulation var intensificationPop = this.Intensification(this.P, this.P_e, sgm); var diversityPop = this.Diversity(this.P, this.P.Length - intensificationPop.Length, sgm); // Combine the two populations Genotype[] newPop = new Genotype[this.P.Length]; for (int i = 0; i < intensificationPop.Length; i++) { newPop[i] = intensificationPop[i]; } for (int i = 0; i < diversityPop.Length; i++) { newPop[i + intensificationPop.Length] = diversityPop[i]; } // Sort and go to the next generation newPop = newPop.OrderBy(c => c.Cost).ToArray(); if (this.P[0].Cost < newPop[0].Cost) { newPop[0] = this.P[0]; } this.P = newPop; }
public virtual void Evolve() { // calc SGM var sgm = BuildSgm(this.P); // Evolve the two subpopulation var intensificationPop = this.Intensification(this.P, this.P_e, sgm); var diversityPop = this.Diversity(this.P, this.P.Length - intensificationPop.Length, sgm); // Combine the two populations Genotype[] newPop = new Genotype[this.P.Length]; try { Array.Copy(intensificationPop, 0, newPop, 0, intensificationPop.Length); } catch (Exception e) { Console.Error.Write(e); System.Environment.Exit(1); } try { Array.Copy(diversityPop, 0, newPop, intensificationPop.Length, diversityPop.Length); } catch (Exception e) { Console.Error.Write(e); System.Environment.Exit(1); } // Sort newPop = newPop.OrderBy(c => c.Cost).ToArray(); this.P = newPop; }
public Genotype[] GetElite(int elite, Genotype[] pop, double minDist) { List<Genotype> elites = new List<Genotype>(); Genotype lastElite = null; int pIndex = 0; while (elites.Count < elite) { // Get the first elite if (elites.Count == 0) { lastElite = pop[pIndex]; elites.Add(lastElite); pIndex++; continue; } // Get the rest of the elites if (GeneticAlgorithm.GeneticAlgorithmFunctions.HammingDis(lastElite.Sequence, pop[pIndex].Sequence) >= minDist) { lastElite = pop[pIndex]; elites.Add(lastElite); } pIndex++; if (pIndex >= pop.Length) { break; } } return elites.ToArray(); }
/// <summary> /// Intensification method according to Zhang et al. (2018) in Algorithm 3. /// Some parts have been tweaked to adapt to ordered problem constraints /// </summary> /// <param name="pop"></param> /// <param name="subPopSize"></param> /// <returns></returns> public override Genotype[] Intensification(Genotype[] pop, int subPopSize, double[,] sgm) { Random rand = new Random(Guid.NewGuid().GetHashCode()); //---------------------------------------------------------------------------------------------------------- // Step 1: Compute S_E and copy the best individuals into the next generation //---------------------------------------------------------------------------------------------------------- Genotype[] subPop = GetElite(subPopSize, pop, M_d); Genotype[] newPop = new Genotype[subPop.Length]; var sgm = BuildSgm(subPop); var S_E = GetReferencePoint(sgm); //---------------------------------------------------------------------------------------------------------- // Step 2: According to S_E, compute each vector of ppSGM M_P //---------------------------------------------------------------------------------------------------------- // Get the control amplitude double CA = CalcControlAmplitude(pop); var M_P = BuildPerturbationMatrix(sgm, CA, false); //---------------------------------------------------------------------------------------------------------- // Step 3: Breed temporary individuals by using pp=SGM and M_P and Alg 1. Similar to Alg 3, execute // crossover between temporary individuals and intensification subpopulation after updating. //---------------------------------------------------------------------------------------------------------- // Calc probabilty of mutation double p_m = 1 / (double)this.N; // Create the temporary individuals that reflect the subpopulation int[][] temporaryIndividuals = new int[pop.Length][]; Parallel.For(0, subPop.Length, ind => { temporaryIndividuals[ind] = this.NewTemporaryIndividual(M_P, this.N); }); // Crossover and mutation Parallel.For(0, subPop.Length, i => { if (i == 0) { newPop[i] = subPop[i]; } // var candidate = temporaryIndividuals[i]; var candidate = pop[GeneticAlgorithmFunctions.Select(pop.Length)].Sequence; var genotype = subPop[i]; var seq = GeneticAlgorithm.GeneticAlgorithmFunctions.Crossover(candidate, genotype.Sequence); seq = GeneticAlgorithm.GeneticAlgorithmFunctions.Mutate(seq, p_m); var cost = Problem.CalcCostRoute(seq); newPop[i] = new Genotype(seq, cost); }); // Sort and return newPop = subPop.OrderBy(c => c.Cost).ToArray(); return(newPop); }
/// <summary> /// Diversity method according to Zhang et al. (2018) in Algorithm 3. /// Some parts have been tweaked to adapt to ordered problem constraints /// </summary> /// <param name="pop"></param> public override Genotype[] Diversity(Genotype[] pop, int subPopSize, double[,] sgm) { Random rand = new Random(Guid.NewGuid().GetHashCode()); Genotype[] newPop = new Genotype[pop.Length]; // Get the control amplitude double CA = CalcControlAmplitude(pop); //---------------------------------------------------------------------------------------------------------- // Step 1: According to S_G, compute each vector of np_SGM M_N from Alg. 3 (Zhang et al. 2018) //---------------------------------------------------------------------------------------------------------- // var sgm = BuildSgm(pop); var M_N = BuildPerturbationMatrix(sgm, CA, true); // Create the temporary individuals that reflect the subpopulation int[][] temporaryIndividuals = new int[pop.Length][]; Parallel.For(0, newPop.Length, ind => { temporaryIndividuals[ind] = this.NewTemporaryIndividual(M_N, this.N); }); // Calculate the mutation probability double p_m = (1.0 + this.M_s * CA) / (double)N; //---------------------------------------------------------------------------------------------------------- // Step 2: Breed temporary individuals by using np-SGM M_N and Algorithm 1, and execute crossover //---------------------------------------------------------------------------------------------------------- Parallel.For(0, newPop.Length, ind => { int[] O = new int[this.N]; for (int i = 0; i < O.Length; i++) { O[i] = rand.NextDouble() <= 0.5 ? temporaryIndividuals[ind][i] : pop[ind].Sequence[i]; } // Step 3: Execute mutation according to mutation probability pm in Eq. (17) and ms is multiplier factor O = GeneticAlgorithm.GeneticAlgorithmFunctions.Mutate(O, p_m); int cost = Problem.CalcCostRoute(O); newPop[ind] = new Genotype(O, cost); }); // Sort and return newPop = newPop.OrderBy(c => c.Cost).ToArray(); Genotype[] returnPop = new Genotype[subPopSize]; Array.Copy(newPop, 0, returnPop, 0, returnPop.Length); return(returnPop); }
public Genotype[] InitialisePopulation(Instance instance, int p) { Random rand = new Random(Guid.NewGuid().GetHashCode()); Genotype[] pop = new Genotype[p]; for (int i = 0; i < p; i++) { // Build a sequence int[] sequence = new int[this.Problem.Nodes.Length]; for (int j = 1; j <= sequence.Length; j++) { sequence[j - 1] = j; } // Shuffle it and get the cost sequence = sequence.OrderBy(x => rand.Next()).ToArray(); int cost = instance.CalcCostRoute(sequence); Genotype genotype = new Genotype(sequence, cost); pop[i] = genotype; } return pop; }