public override int[] NewTemporaryIndividual(double[,] sgm, int n) { Random rand = new Random(Guid.NewGuid().GetHashCode()); int[] seq = new int[n]; var msgm = GeneticAlgorithmFunctions.CopyArray(sgm); seq[0] = 1; // Go through sgm and build new sequence for (int i = 1; i < seq.Length; i++) { int from = seq[i - 1]; // Remove the possibility of going back to the FROM node var next = Markov.Markov.GetNext(from, msgm); seq[i] = next; Markov.Markov.RemoveColumn(from, msgm); } if (seq.Distinct().Count() != seq.Length || !GeneticAlgorithmFunctions.IsDistinct(seq)) { Console.Error.WriteLine("Error with sequence"); Console.WriteLine(String.Join(", ", seq)); System.Environment.Exit(1); } return(seq); }
/// <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); }