/// <summary> /// Constructor. /// Creates a new multiobjective problem instance. /// </summary> /// <param name="solutionType">The solution type must "Real" or "BinaryReal", and "ArrayReal".</param> /// <param name="numberOfVariables">Number of variables</param> public NSGAIIProblem(string solutionType, MOO comp, int solutionsCounter) { this.component = comp; NumberOfVariables = comp.readSlidersList().Count; NumberOfObjectives = comp.objectives.Count; NumberOfConstraints = 0; ProblemName = "Multiobjective"; // Log comp.LogAddMessage("Number of Variables = " + NumberOfVariables); comp.LogAddMessage("Number of Objectives = " + NumberOfObjectives); comp.LogAddMessage("Number of Constraints = " + NumberOfConstraints); UpperLimit = new double[NumberOfVariables]; LowerLimit = new double[NumberOfVariables]; for (int i = 0; i < NumberOfVariables; i++) { GH_NumberSlider curSlider = comp.readSlidersList()[i]; LowerLimit[i] = (double)curSlider.Slider.Minimum; UpperLimit[i] = (double)curSlider.Slider.Maximum; } if (solutionType == "BinaryReal") { SolutionType = new BinaryRealSolutionType(this); } else if (solutionType == "Real") { SolutionType = new RealSolutionType(this); } else if (solutionType == "ArrayReal") { SolutionType = new ArrayRealSolutionType(this); } else { Console.WriteLine("Error: solution type " + solutionType + " is invalid"); //Logger.Log.Error("Solution type " + solutionType + " is invalid"); return; } // Log comp.LogAddMessage("Solution Type = " + solutionType); }
/// <summary> /// Usage: three options /// - NSGAII /// - NSGAII problemName /// - NSGAII problemName paretoFrontFile /// </summary> /// <param name="args"></param> public NSGAIIRunner(string[] args, Problem p, string Path, MOO comp) { Problem problem = p; // The problem to solve Algorithm algorithm; // The algorithm to use Operator crossover; // Crossover operator Operator mutation; // Mutation operator Operator selection; // Selection operator this.comp = comp; Dictionary <string, object> parameters; // Operator parameters QualityIndicator indicators; // Object to get quality indicators // Logger object and file to store log messages //var logger = Logger.Log; //var appenders = logger.Logger.Repository.GetAppenders(); //var fileAppender = appenders[0] as log4net.Appender.FileAppender; //fileAppender.File = "NSGAII.log"; //fileAppender.ActivateOptions(); indicators = null; //if (args.Length == 1) //{ // object[] param = { "Real" }; // problem = ProblemFactory.GetProblem(args[0], param); //} //else if (args.Length == 2) //{ // object[] param = { "Real" }; // problem = ProblemFactory.GetProblem(args[0], param); // indicators = new QualityIndicator(problem, args[1]); //} //else //{ // Default problem // //problem = ; // //problem = new Kursawe("BinaryReal", 3); // //problem = new Water("Real"); // //problem = new ZDT3("ArrayReal", 30); // //problem = new ConstrEx("Real"); // //problem = new DTLZ1("Real"); // //problem = new OKA2("Real") ; //} algorithm = new NSGAII(problem, comp); //algorithm = new ssNSGAII(problem); // Algorithm parameters algorithm.SetInputParameter("populationSize", comp.popSize); algorithm.SetInputParameter("maxEvaluations", comp.maxEvals); comp.LogAddMessage("Population Size = " + comp.popSize); comp.LogAddMessage("Max Evaluations = " + comp.maxEvals); // Mutation and Crossover for Real codification parameters = new Dictionary <string, object>(); parameters.Add("probability", 0.9); parameters.Add("distributionIndex", 20.0); crossover = CrossoverFactory.GetCrossoverOperator("SBXCrossover", parameters); comp.LogAddMessage("Crossover Type = " + "SBXCrossover"); comp.LogAddMessage("Crossover Probability = " + 0.9); comp.LogAddMessage("Crossover Distribution Index = " + 20); parameters = new Dictionary <string, object>(); parameters.Add("probability", 1.0 / problem.NumberOfVariables); parameters.Add("distributionIndex", 20.0); mutation = MutationFactory.GetMutationOperator("PolynomialMutation", parameters); comp.LogAddMessage("Mutation Type = " + "Polynomial Mutation"); comp.LogAddMessage("Mutation Probability = " + (1 / problem.NumberOfVariables)); comp.LogAddMessage("Mutation Distribution Index = " + 20); // Selection Operator parameters = null; selection = SelectionFactory.GetSelectionOperator("BinaryTournament2", parameters); comp.LogAddMessage("Selection Type = " + "Binary Tournament 2"); // Add the operators to the algorithm algorithm.AddOperator("crossover", crossover); algorithm.AddOperator("mutation", mutation); algorithm.AddOperator("selection", selection); // Add the indicator object to the algorithm algorithm.SetInputParameter("indicators", indicators); // Execute the Algorithm long initTime = Environment.TickCount; SolutionSet population = algorithm.Execute(); long estimatedTime = Environment.TickCount - initTime; comp.LogAddMessage("Total Execution Time = " + estimatedTime + "ms"); // Result messages //logger.Info("Total execution time: " + estimatedTime + "ms"); //logger.Info("Variables values have been writen to file VAR"); //population.PrintVariablesToFile(@"C:\Users\Jonathas\Desktop\text.txt"); population.PrintVariablesToFile(@"" + comp.fileName + "VAR-" + comp.fileName); //logger.Info("Objectives values have been writen to file FUN"); population.PrintObjectivesToFile(@"" + comp.fileName + "OBJ-" + comp.fileName); // Saving all solutions to file //Console.WriteLine("Time: " + estimatedTime); //Console.ReadLine(); if (indicators != null) { //logger.Info("Quality indicators"); //logger.Info("Hypervolume: " + indicators.GetHypervolume(population)); //logger.Info("GD : " + indicators.GetGD(population)); //logger.Info("IGD : " + indicators.GetIGD(population)); //logger.Info("Spread : " + indicators.GetSpread(population)); //logger.Info("Epsilon : " + indicators.GetEpsilon(population)); int evaluations = (int)algorithm.GetOutputParameter("evaluations"); //logger.Info("Speed : " + evaluations + " evaluations"); } }
/// <summary> /// Runs the NSGA-II algorithm. /// </summary> /// <returns>a <code>SolutionSet</code> that is a set of non dominated solutions as a result of the algorithm execution</returns> public override SolutionSet Execute() { // !!!! NEEDED PARAMETES !!! start //J* Parameters int populationSize = -1; // J* store population size int maxEvaluations = -1; // J* store number of max Evaluations int evaluations; // J* number of current evaluations // J* Objects needed to illustrate the use of quality indicators inside the algorithms QualityIndicator indicators = null; // QualityIndicator object int requiredEvaluations; // Use in the example of use of the // indicators object (see below) // J* populations needed to implement NSGA-II SolutionSet population; //J* Current population SolutionSet offspringPopulation; //J* offspring population SolutionSet union; //J* population resultant from current and offpring population //J* Genetic Operators Operator mutationOperator; Operator crossoverOperator; Operator selectionOperator; //J* Used to evaluate crowding distance Distance distance = new Distance(); //J* !!!! NEEDED PARAMETES !!! end //J* !!! INITIALIZING PARAMETERS - start !!! //Read the parameters JMetalCSharp.Utils.Utils.GetIntValueFromParameter(this.InputParameters, "maxEvaluations", ref maxEvaluations); //J* required JMetalCSharp.Utils.Utils.GetIntValueFromParameter(this.InputParameters, "populationSize", ref populationSize); //J* required JMetalCSharp.Utils.Utils.GetIndicatorsFromParameters(this.InputParameters, "indicators", ref indicators); //J* optional //Initialize the variables population = new SolutionSet(populationSize); evaluations = 0; requiredEvaluations = 0; //Read the operators mutationOperator = Operators["mutation"]; crossoverOperator = Operators["crossover"]; selectionOperator = Operators["selection"]; //J* !!! INITIALIZING PARAMETERS - end !!! //J* !!! Creating first population !!! JMetalRandom.SetRandom(comp.MyRand); comp.LogAddMessage("Random seed = " + comp.Seed); // Create the initial solutionSet Solution newSolution; for (int i = 0; i < populationSize; i++) { newSolution = new Solution(Problem); Problem.Evaluate(newSolution); Problem.EvaluateConstraints(newSolution); evaluations++; population.Add(newSolution); } // Generations while (evaluations < maxEvaluations) { // Create the offSpring solutionSet offspringPopulation = new SolutionSet(populationSize); Solution[] parents = new Solution[2]; for (int i = 0; i < (populationSize / 2); i++) { if (evaluations < maxEvaluations) { //obtain parents parents[0] = (Solution)selectionOperator.Execute(population); parents[1] = (Solution)selectionOperator.Execute(population); Solution[] offSpring = (Solution[])crossoverOperator.Execute(parents); mutationOperator.Execute(offSpring[0]); mutationOperator.Execute(offSpring[1]); Problem.Evaluate(offSpring[0]); Problem.EvaluateConstraints(offSpring[0]); Problem.Evaluate(offSpring[1]); Problem.EvaluateConstraints(offSpring[1]); offspringPopulation.Add(offSpring[0]); offspringPopulation.Add(offSpring[1]); evaluations += 2; } } // Create the solutionSet union of solutionSet and offSpring union = ((SolutionSet)population).Union(offspringPopulation); // Ranking the union Ranking ranking = new Ranking(union); int remain = populationSize; int index = 0; SolutionSet front = null; population.Clear(); // Obtain the next front front = ranking.GetSubfront(index); while ((remain > 0) && (remain >= front.Size())) { //Assign crowding distance to individuals distance.CrowdingDistanceAssignment(front, Problem.NumberOfObjectives); //Add the individuals of this front for (int k = 0; k < front.Size(); k++) { population.Add(front.Get(k)); } //Decrement remain remain = remain - front.Size(); //Obtain the next front index++; if (remain > 0) { front = ranking.GetSubfront(index); } } // Remain is less than front(index).size, insert only the best one if (remain > 0) { // front contains individuals to insert distance.CrowdingDistanceAssignment(front, Problem.NumberOfObjectives); front.Sort(new CrowdingComparator()); for (int k = 0; k < remain; k++) { population.Add(front.Get(k)); } remain = 0; } // This piece of code shows how to use the indicator object into the code // of NSGA-II. In particular, it finds the number of evaluations required // by the algorithm to obtain a Pareto front with a hypervolume higher // than the hypervolume of the true Pareto front. if ((indicators != null) && (requiredEvaluations == 0)) { double HV = indicators.GetHypervolume(population); if (HV >= (0.98 * indicators.TrueParetoFrontHypervolume)) { requiredEvaluations = evaluations; } } } // Return as output parameter the required evaluations SetOutputParameter("evaluations", requiredEvaluations); comp.LogAddMessage("Evaluations = " + evaluations); // Return the first non-dominated front Ranking rank = new Ranking(population); Result = rank.GetSubfront(0); return(Result); }