internal Population RunGeneration(int currentGeneration, Population currentPopulation, FitnessFunction fitnessFunctionDelegate) { //create new empty populations for processing var tempPopulation = currentPopulation.CreateEmptyCopy(); var processedPopulation = tempPopulation.CreateEmptyCopy(); tempPopulation.Solutions.AddRange(currentPopulation.Solutions); //clear the current population, this keeps it simple as the solutions could //easily get corrupted by genetic operators as from v 2.04 on, the genes are no longer cloned currentPopulation.Solutions.Clear(); //invoke the operators var enabledOperators = this.Operators.Where((o) => o.Enabled).ToList(); var operatorCount = enabledOperators.Count(); for (int op = 0; op < operatorCount; op++) { var enabled = true; var genOp = enabledOperators [op] as IGeneticOperator; if (genOp != null) { enabled = genOp.Enabled; } else { throw new NullReferenceException("A genetic operator was null."); } //note that each internal operator will adhere to the enabled flag itself, //however the check is made here as this cannot be guaranteed with third party //operators. if (enabled) { genOp.Invoke(tempPopulation, ref processedPopulation, fitnessFunctionDelegate); Evaluations += genOp.GetOperatorInvokedEvaluations(); tempPopulation.Solutions.Clear(); tempPopulation.Solutions.AddRange(processedPopulation.Solutions); processedPopulation.Solutions.Clear(); // if the next operator in the collection does not require an evaluated population // then no need to evaluate if (op + 1 < operatorCount) { // we are not the last operator, there is another operator to follow // so check to see if an evaluation is required if (enabledOperators [op + 1].RequiresEvaluatedPopulation) { Evaluations += tempPopulation.Evaluate(fitnessFunctionDelegate); } else { EvaluationsRemoved++; } } else { Evaluations += tempPopulation.Evaluate(fitnessFunctionDelegate); } //TODO: Add appropriate Logging //if (this.OnLogging != null) { // var eventArgs = new LoggingEventArgs ("Generation: {0}, Evaluations: {1}", currentGeneration + 1, Evaluations); // this.OnLogging (this, eventArgs); //} //raise the Generation Complete event if (this.OnOperatorComplete != null) { var eventArgs = new GaOperatorEventArgs(genOp, tempPopulation, currentGeneration + 1, Evaluations); this.OnOperatorComplete(this, eventArgs); } } } return(tempPopulation); }
internal Population RunGeneration(int currentGeneration, Population currentPopulation, FitnessFunction fitnessFunctionDelegate) { //create new empty populations for processing var tempPopulation = currentPopulation.CreateEmptyCopy(); var processedPopulation = tempPopulation.CreateEmptyCopy(); tempPopulation.Solutions.AddRange(currentPopulation.Solutions); //clear the current population, this keeps it simple as the solutions could //easily get corrupted by genetic operators as from v 2.04 on, the genes are no longer cloned currentPopulation.Solutions.Clear(); //invoke the operators //Note: Each operator will contribute to populating the New Population. It is not untill all operators are //invoked the the new population is complete. For example the Elite operator with 10% will return a //_newPopulation object containing only the top 10% of the solutions that exist in _population. //Deletions handled by the operator(s) foreach (var op in this.Operators) { var enabled = true; //maxFitnessPre = tempPopulation.MaximumFitness; var genOp = op as IGeneticOperator; //this is the new interface if (genOp != null) { //using new interface so check enabled enabled = genOp.Enabled; } //note that each internal operator will adhere to the enabled flag itself, //however the check is made here as this cannot be guaranteed with third party //operators. if (enabled) { op.Invoke(tempPopulation, ref processedPopulation, fitnessFunctionDelegate); Evaluations += op.GetOperatorInvokedEvaluations(); tempPopulation.Solutions.Clear(); tempPopulation.Solutions.AddRange(processedPopulation.Solutions); processedPopulation.Solutions.Clear(); //TODO: Fix this. //Some solutions will have already been evaluated during the operator invocations //e.g. crossover, however, they may have also been mutated. By tracking/evaluating //mutated we could get here only needing to evaluate those that wern't touched //by the operators. The Chromosome.EvaluatedByOperator flag could help here... //evaluate in case it affects the next operators selection Evaluations += tempPopulation.Evaluate(fitnessFunctionDelegate); //raise the Generation Complete event if (this.OnOperatorComplete != null) { var eventArgs = new GaOperatorEventArgs(op, tempPopulation, currentGeneration + 1, Evaluations); this.OnOperatorComplete(this, eventArgs); } } } return(tempPopulation); }