/// <summary> /// Generates a random individual. /// </summary> /// <param name="solver"></param> /// <returns></returns> public Individual <List <int>, GeneticProblem, Fitness> Generate( Solver <List <int>, GeneticProblem, Fitness> solver) { // create new genomes list. List <int> genome = new List <int>(); // build cities to place (in a thread-safe way!) List <int> cities_to_place = new List <int>(); lock (solver) { for (int idx = 0; idx < solver.Problem.Along.Count; idx++) { cities_to_place.Add(solver.Problem.Along[idx]); } } BestPlacementHelper helper = BestPlacementHelper.Instance(); helper.DoFast( solver.Problem, solver.FitnessCalculator as FitnessCalculator, genome, cities_to_place); Individual individual = new Individual(genome); individual.CalculateFitness(solver.Problem, solver.FitnessCalculator); return(individual); }
/// <summary> /// Take a piece of the genome and re-do best placement. /// </summary> /// <param name="solver"></param> /// <param name="mutating"></param> /// <returns></returns> private Individual <List <int>, GeneticProblem, Fitness> MutateByTakingPiece( Solver <List <int>, GeneticProblem, Fitness> solver, Individual <List <int>, GeneticProblem, Fitness> mutating) { // take a random piece. int idx1 = 0; int idx2 = 0; while (idx2 - idx1 == 0) { idx1 = solver.Random.Next(mutating.Genomes.Count - 1) + 1; idx2 = solver.Random.Next(mutating.Genomes.Count - 1) + 1; if (idx1 > idx2) { int temp = idx1; idx1 = idx2; idx2 = temp; } } // if the genome range is big take it from the best individual. Individual <List <int>, GeneticProblem, Fitness> source = (mutating as Individual <List <int>, GeneticProblem, Fitness>); Individual <List <int>, GeneticProblem, Fitness> target = (mutating as Individual <List <int>, GeneticProblem, Fitness>); List <int> source_piece = source.Genomes.GetRange(idx1, idx2 - idx1); List <int> new_genome = target.Genomes.GetRange(0, target.Genomes.Count); // insert the piece into the worst individual. // remove nodes in the source_piece. foreach (int source_node in source_piece) { new_genome.Remove(source_node); } // apply best placement algorithm to place the selected genomes. //List<int> genome = new List<int>(); BestPlacementHelper helper = BestPlacementHelper.Instance(); helper.DoFast( solver.Problem, solver.FitnessCalculator as FitnessCalculator, new_genome, source_piece); Individual individual = new Individual(new_genome); individual.CalculateFitness(solver.Problem, solver.FitnessCalculator); return(individual); }
/// <summary> /// Generates one individual. /// </summary> /// <param name="solver"></param> /// <returns></returns> public Individual <List <Genome>, Problem, Fitness> Generate( Solver <List <Genome>, Problem, Fitness> solver) { IRandomGenerator random = new RandomGenerator(); // generate a list of cities to place. List <int> cities = new List <int>(); for (int city_to_place = 0; city_to_place < solver.Problem.Cities; city_to_place++) { cities.Add(city_to_place); } // create new individuals. Individual individual = new Individual(new List <Genome>()); //individual.Initialize(); // place one random city in each round. for (int round_idx = 0; round_idx < solver.Problem.InitialVehicles; round_idx++) { // select a random city to place. int city_idx = random.Generate(cities.Count); int city = cities[city_idx]; cities.RemoveAt(city_idx); // create new genome. Genome genome = new Genome(); genome.Add(city); individual.Genomes.Add(genome); } individual = BestPlacementHelper.DoFast( solver.Problem, (solver.FitnessCalculator as FitnessCalculator), individual, cities); return(individual); }
CrossOver(Solver <List <int>, GeneticProblem, Fitness> solver, Individual <List <int>, GeneticProblem, Fitness> parent1, Individual <List <int>, GeneticProblem, Fitness> parent2) { // take a random piece. int idx1 = 0; int idx2 = 0; while (idx2 - idx1 == 0) { idx1 = solver.Random.Next(parent1.Genomes.Count - 1) + 1; idx2 = solver.Random.Next(parent2.Genomes.Count - 1) + 1; if (idx1 > idx2) { int temp = idx1; idx1 = idx2; idx2 = temp; } } // if the genome range is big take it from the best individual. Individual <List <int>, GeneticProblem, Fitness> source = (parent1 as Individual <List <int>, GeneticProblem, Fitness>); Individual <List <int>, GeneticProblem, Fitness> target = (parent2 as Individual <List <int>, GeneticProblem, Fitness>); if (idx2 - idx1 < parent1.Genomes.Count / 2) { // the range is small; take the worste genomes. if (source.Fitness.CompareTo(target.Fitness) > 0) { Individual <List <int>, GeneticProblem, Fitness> temp = source; source = target; target = temp; } else { // do nothing. } } else { // the range is big; take the good genomes. if (source.Fitness.CompareTo(target.Fitness) > 0) { // do nothing. } else { Individual <List <int>, GeneticProblem, Fitness> temp = source; source = target; target = temp; } } List <int> source_piece = source.Genomes.GetRange(idx1, idx2 - idx1); List <int> new_genome = target.Genomes.GetRange(0, target.Genomes.Count); // insert the piece into the worst individual. // remove nodes in the source_piece. foreach (int source_node in source_piece) { new_genome.Remove(source_node); } // apply best placement algorithm to place the selected genomes. //List<int> genome = new List<int>(); BestPlacementHelper helper = BestPlacementHelper.Instance(); helper.DoFast( solver.Problem, solver.FitnessCalculator as FitnessCalculator, new_genome, source_piece); // return a new individual based on the new genome list. Individual individual = new Individual(new_genome); individual.CalculateFitness(solver.Problem, solver.FitnessCalculator); return(individual); }