/// <summary> /// Generate a random path through cities. /// </summary> /// <param name="rnd">Random number generator.</param> /// <returns>A genome.</returns> private IntegerArrayGenome RandomGenome(IGenerateRandom rnd) { var result = new IntegerArrayGenome(_cities.Length); int[] organism = result.Data; var taken = new bool[_cities.Length]; for (int i = 0; i < organism.Length - 1; i++) { int icandidate; do { icandidate = rnd.NextInt(0, organism.Length); } while (taken[icandidate]); organism[i] = icandidate; taken[icandidate] = true; if (i == organism.Length - 2) { icandidate = 0; while (taken[icandidate]) { icandidate++; } organism[i + 1] = icandidate; } } return(result); }
private IntegerArrayGenome RandomGenome() { Random rnd = new Random(); IntegerArrayGenome result = new IntegerArrayGenome(cities.Length); int[] organism = result.Data; bool[] taken = new bool[cities.Length]; for (int i = 0; i < organism.Length - 1; i++) { int icandidate; do { icandidate = (int)(rnd.NextDouble() * organism.Length); } while (taken[icandidate]); organism[i] = icandidate; taken[icandidate] = true; if (i == organism.Length - 2) { icandidate = 0; while (taken[icandidate]) { icandidate++; } organism[i + 1] = icandidate; } } return(result); }
public int[] Run() { StringBuilder builder = new StringBuilder(); IPopulation pop = InitPopulation(); ICalculateScore score = new FitnessFunction(cities); genetic = new TrainEA(pop, score); genetic.AddOperation(0.9, new SpliceNoRepeat(cityCount / 3)); genetic.AddOperation(0.1, new MutateShuffle()); int sameSolutionCount = 0; int iteration = 1; double lastSolution = Double.MaxValue; while (sameSolutionCount < maxSameSolition) { genetic.Iteration(); double thisSolution = genetic.Error; builder.Length = 0; builder.Append("Iteration: "); builder.Append(iteration++); builder.Append(", Best Path Length = "); builder.Append(thisSolution); Console.WriteLine(builder.ToString()); if (Math.Abs(lastSolution - thisSolution) < 1.0) { sameSolutionCount++; } else { sameSolutionCount = 0; } lastSolution = thisSolution; } Console.WriteLine("Good solution found:"); IntegerArrayGenome best = (IntegerArrayGenome)genetic.BestGenome; genetic.FinishTraining(); return(best.Data); }
/// <summary> /// Get a list of the genes that have not been taken before. This is useful /// if you do not wish the same gene to appear more than once in a /// genome. /// </summary> /// <param name="source">The pool of genes to select from.</param> /// <param name="taken"> An array of the taken genes.</param> /// <returns>Those genes in source that are not taken.</returns> private static int GetNotTaken(IntegerArrayGenome source, HashSet <int> taken) { foreach (int trial in source.Data) { if (!taken.Contains(trial)) { taken.Add(trial); return(trial); } } throw new GeneticError("Ran out of integers to select."); }
public void TestCompare() { BasicGenome genome1 = new IntegerArrayGenome(1); genome1.AdjustedScore = 10; genome1.Score = 4; BasicGenome genome2 = new IntegerArrayGenome(1); genome2.AdjustedScore = 4; genome2.Score = 10; MinimizeAdjustedScoreComp comp = new MinimizeAdjustedScoreComp(); Assert.IsTrue(comp.Compare(genome1, genome2) > 0); }
private IPopulation initPopulation() { IPopulation result = new BasicPopulation(POPULATION_SIZE, null); BasicSpecies defaultSpecies = new BasicSpecies(); defaultSpecies.Population = result; for (int i = 0; i < POPULATION_SIZE; i++) { IntegerArrayGenome genome = RandomGenome(); defaultSpecies.Members.Add(genome); } result.GenomeFactory = new IntegerArrayGenomeFactory(cities.Length); result.Species.Add(defaultSpecies); return(result); }
/// <summary> /// Create an initial random population of random paths through the cities. /// </summary> /// <param name="rnd">The random population.</param> /// <returns>The population</returns> private IPopulation InitPopulation(IGenerateRandom rnd) { IPopulation result = new BasicPopulation(PopulationSize, null); var defaultSpecies = new BasicSpecies(); defaultSpecies.Population = result; for (int i = 0; i < PopulationSize; i++) { IntegerArrayGenome genome = RandomGenome(rnd); defaultSpecies.Add(genome); } result.GenomeFactory = new IntegerArrayGenomeFactory(_cities.Length); result.Species.Add(defaultSpecies); return(result); }
/// <summary> /// Demonstrate the crossover splice operator. Two offspring will be created by swapping three /// segments of the parents (two cut points). Some genes may repeat. /// </summary> public static void Splice() { Console.WriteLine("Crossover Splice"); // Create a random number generator IGenerateRandom rnd = new MersenneTwisterGenerateRandom(); // Create a new population. IPopulation pop = new BasicPopulation(); pop.GenomeFactory = new IntegerArrayGenomeFactory(10); // Create a trainer with a very simple score function. We do not care // about the calculation of the score, as they will never be calculated. IEvolutionaryAlgorithm train = new BasicEA(pop, new NullScore()); // Create a splice operator, length = 5. Use it 1.0 (100%) of the time. var opp = new Splice(5); train.AddOperation(1.0, opp); // Create two parents, the genes are set to 1,2,3,4,5,7,8,9,10 // and 10,9,8,7,6,5,4,3,2,1. var parents = new IntegerArrayGenome[2]; parents[0] = (IntegerArrayGenome)pop.GenomeFactory.Factor(); parents[1] = (IntegerArrayGenome)pop.GenomeFactory.Factor(); for (int i = 1; i <= 10; i++) { parents[0].Data[i - 1] = i; parents[1].Data[i - 1] = 11 - i; } // Create an array to hold the offspring. var offspring = new IntegerArrayGenome[2]; // Perform the operation opp.PerformOperation(rnd, parents, 0, offspring, 0); // Display the results Console.WriteLine("Parent 1: " + string.Join(",", parents[0].Data)); Console.WriteLine("Parent 2: " + string.Join(",", parents[1].Data)); Console.WriteLine("Offspring 1: " + string.Join(",", offspring[0].Data)); Console.WriteLine("Offspring 2: " + string.Join(",", offspring[1].Data)); }
public double CalculateScore(IMLMethod network) { double result = 0.0; IntegerArrayGenome genome = (IntegerArrayGenome)network; int[] path = genome.Data; for (int i = 0; i < cities.Length - 1; i++) { City city1 = cities[path[i]]; City city2 = cities[path[i + 1]]; double dist = city1.Proximity(city2); result += dist; } return(result); }
/// <summary> /// Display the cities in the final path. /// </summary> /// <param name="solution">The solution to display.</param> public void DisplaySolution(IntegerArrayGenome solution) { bool first = true; int[] path = solution.Data; foreach (int aPath in path) { if (!first) { Console.Write(">"); } Console.Write("" + aPath); first = false; } Console.WriteLine(); }
/// <inheritdoc/> public void PerformOperation(EncogRandom rnd, IGenome[] parents, int parentIndex, IGenome[] offspring, int offspringIndex) { IntegerArrayGenome mother = (IntegerArrayGenome)parents[parentIndex]; IntegerArrayGenome father = (IntegerArrayGenome)parents[parentIndex + 1]; IntegerArrayGenome offspring1 = (IntegerArrayGenome)this.owner.Population.GenomeFactory.Factor(); IntegerArrayGenome offspring2 = (IntegerArrayGenome)this.owner.Population.GenomeFactory.Factor(); offspring[offspringIndex] = offspring1; offspring[offspringIndex + 1] = offspring2; int geneLength = mother.Size; // the chromosome must be cut at two positions, determine them int cutpoint1 = (int)(rnd.Next(geneLength - this.cutLength)); int cutpoint2 = cutpoint1 + this.cutLength; // keep track of which genes have been taken in each of the two // offspring, defaults to false. HashSet <int> taken1 = new HashSet <int>(); HashSet <int> taken2 = new HashSet <int>(); // handle cut section for (int i = 0; i < geneLength; i++) { if (!((i < cutpoint1) || (i > cutpoint2))) { offspring1.Copy(father, i, i); offspring2.Copy(mother, i, i); taken1.Add(father.Data[i]); taken2.Add(mother.Data[i]); } } // handle outer sections for (int i = 0; i < geneLength; i++) { if ((i < cutpoint1) || (i > cutpoint2)) { offspring1.Data[i] = SpliceNoRepeat.GetNotTaken(mother, taken1); offspring2.Data[i] = SpliceNoRepeat.GetNotTaken(father, taken2); } } }
/// <summary> /// Demonstrate the mutate shuffle operator. An offspring will be created by swapping two /// individual genes. /// </summary> public static void MutateShuffle() { Console.WriteLine("Mutate shuffle"); // Create a random number generator IGenerateRandom rnd = new MersenneTwisterGenerateRandom(); // Create a new population. IPopulation pop = new BasicPopulation(); pop.GenomeFactory = new IntegerArrayGenomeFactory(5); // Create a trainer with a very simple score function. We do not care // about the calculation of the score, as they will never be calculated. IEvolutionaryAlgorithm train = new BasicEA(pop, new NullScore()); // Create a shuffle operator. Use it 1.0 (100%) of the time. var opp = new MutateShuffle(); train.AddOperation(1.0, opp); // Create a single parent, the genes are set to 1,2,3,4,5. var parents = new IntegerArrayGenome[1]; parents[0] = (IntegerArrayGenome)pop.GenomeFactory.Factor(); for (int i = 1; i <= 5; i++) { parents[0].Data[i - 1] = i; } // Create an array to hold the offspring. var offspring = new IntegerArrayGenome[1]; offspring[0] = new IntegerArrayGenome(5); // Perform the operation opp.PerformOperation(rnd, parents, 0, offspring, 0); // Display the results Console.WriteLine("Parent: " + string.Join(",", parents[0].Data)); Console.WriteLine("Offspring: " + string.Join(",", offspring[0].Data)); }
private BasicPopulation InitPopulation() { BasicPopulation result = new BasicPopulation(populationSize, null); BasicSpecies defaultSpecies = new BasicSpecies() { Population = result }; for (int i = 0; i < populationSize; i++) { IntegerArrayGenome genome = RandomGenome(); defaultSpecies.Members.Add(genome); } result.GenomeFactory = new IntegerArrayGenomeFactory(cities.Length); result.Species.Add(defaultSpecies); return(result); }
/// <summary> /// The entry point for this example. If you would like to make this example /// stand alone, then add to its own project and rename to Main. /// </summary> /// <param name="args">Not used.</param> public static void ExampleMain(string[] args) { // Create a new population. IPopulation pop = new BasicPopulation(); ISpecies species = pop.CreateSpecies(); // Create 1000 genomes, assign the score to be the index number. for (int i = 0; i < 1000; i++) { IGenome genome = new IntegerArrayGenome(1); genome.Score = i; genome.AdjustedScore = i; pop.Species[0].Add(genome); } IGenerateRandom rnd = new MersenneTwisterGenerateRandom(); // Create a trainer with a very simple score function. We do not care // about the calculation of the score, as they will never be calculated. // We only care that we are maximizing. IEvolutionaryAlgorithm train = new BasicEA(pop, new NullScore()); // Perform the test for round counts between 1 and 10. for (int roundCount = 1; roundCount <= 10; roundCount++) { var selection = new TournamentSelection(train, roundCount); int sum = 0; int count = 0; for (int i = 0; i < 100000; i++) { int genomeID = selection.PerformSelection(rnd, species); IGenome genome = species.Members[genomeID]; sum += (int)genome.AdjustedScore; count++; } sum /= count; Console.WriteLine("Rounds: " + roundCount + ", Avg Score: " + sum); } }
public BasicPopulation CreateInitialPopulation(int populationSize, int geneCountPerChromosome) { try { var genomeFactory = new IntegerArrayGenomeFactory(geneCountPerChromosome); var population = new BasicPopulation(populationSize, genomeFactory); var defaultSpecies = new BasicSpecies(); for (var i = 1; i <= populationSize; i++) { Console.Write($"\n {i} Chomosome - "); IntegerArrayGenome genome = CreateRandomGenome(geneCountPerChromosome); defaultSpecies.Members.Add(genome); } population.Species.Add(defaultSpecies); return(population); } catch (Exception e) { Console.WriteLine(e); throw; } }
public IntegerArrayGenome CreateRandomGenome(int chomosomeLength) { try { var cityNumbers = new int[chomosomeLength]; for (var i = 0; i < cityNumbers.Length; i++) { cityNumbers[i] = i; // [0,1,2,3,4,5,6,7,8,9,0,11,12,13,14,15,16,17,18,19] } Shuffle(cityNumbers); // shuffle var integerGenome = new IntegerArrayGenome(chomosomeLength); for (var i = 0; i < cityNumbers.Length; i++) { integerGenome.Data[i] = cityNumbers[i]; if (i == 0) { Console.Write($"[{cityNumbers[i]}"); } else if (i < cityNumbers.Length - 1) { Console.Write($", {cityNumbers[i]}"); } else { Console.Write($", {cityNumbers[i]}]"); } } return(integerGenome); } catch (Exception ex) { Console.WriteLine(ex); throw; } }