#region License Information /* HeuristicLab * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Problems.Robocode { [StorableClass] [Item("Best Tank Program Analyzer", "Analyzer that stores the best tank program.")] public class BestSolutionAnalyzer : SingleSuccessorOperator, ISymbolicExpressionTreeAnalyzer { private const string QualityParameterName = "Quality"; private const string SymbolicExpressionTreeParameterName = "TankProgram"; private const string BestSolutionParameterName = "Best solution"; private const string ResultsParameterName = "Results"; private const string RobocodePathParamaterName = "RobocodePath"; private const string NrOfRoundsParameterName = "NrOfRounds"; private const string EnemiesParameterName = "Enemies"; public bool EnabledByDefault { get { return true; } } #region Parameters public IScopeTreeLookupParameter QualityParameter { get { return (IScopeTreeLookupParameter)Parameters[QualityParameterName]; } } public IScopeTreeLookupParameter SymbolicExpressionTreeParameter { get { return (IScopeTreeLookupParameter)Parameters[SymbolicExpressionTreeParameterName]; } } public ILookupParameter BestSolutionParameter { get { return (ILookupParameter)Parameters[BestSolutionParameterName]; } } public ILookupParameter ResultParameter { get { return (ILookupParameter)Parameters[ResultsParameterName]; } } public ILookupParameter RobocodePathParameter { get { return (ILookupParameter)Parameters[RobocodePathParamaterName]; } } public ILookupParameter NrOfRoundsParameter { get { return (ILookupParameter)Parameters[NrOfRoundsParameterName]; } } public ILookupParameter> EnemiesParameter { get { return (ILookupParameter>)Parameters[EnemiesParameterName]; } } #endregion [StorableConstructor] protected BestSolutionAnalyzer(bool deserializing) : base(deserializing) { } protected BestSolutionAnalyzer(BestSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { } public BestSolutionAnalyzer() { Parameters.Add(new ScopeTreeLookupParameter(QualityParameterName, "The solution quality of the tank program.")); Parameters.Add(new ScopeTreeLookupParameter(SymbolicExpressionTreeParameterName, "The tank program to evaluate represented as symbolic expression tree.")); Parameters.Add(new LookupParameter(BestSolutionParameterName, "The best tank program.")); Parameters.Add(new LookupParameter(ResultsParameterName, "The result collection of the algorithm.")); Parameters.Add(new LookupParameter(RobocodePathParamaterName, "Path of the Robocode installation.")); Parameters.Add(new LookupParameter(NrOfRoundsParameterName, "Nr. of Rounds a Robot has to fight against each opponent.")); Parameters.Add(new LookupParameter>(EnemiesParameterName, "The enemies that should be battled.")); } public override IOperation Apply() { // get an array of all trees // and an array of all qualities var trees = SymbolicExpressionTreeParameter.ActualValue; var qualities = QualityParameter.ActualValue; // find the tree with the best quality double maxQuality = double.NegativeInfinity; ISymbolicExpressionTree bestTree = null; for (int i = 0; i < qualities.Length; i++) { if (qualities[i].Value > maxQuality) { maxQuality = qualities[i].Value; bestTree = trees[i]; } } // create a solution instance var bestSolution = new Solution(bestTree, RobocodePathParameter.ActualValue.Value, NrOfRoundsParameter.ActualValue.Value, EnemiesParameter.ActualValue); // store the new solution in the best solution parameter BestSolutionParameter.ActualValue = bestSolution; // also add the best solution as a result to the result collection // or alternatively update the existing result var resultCollection = ResultParameter.ActualValue; if (!resultCollection.ContainsKey(BestSolutionParameterName)) { resultCollection.Add(new Result(BestSolutionParameterName, "The best tank program", bestSolution)); } else { resultCollection[BestSolutionParameterName].Value = bestSolution; } return base.Apply(); } public override IDeepCloneable Clone(Cloner cloner) { return new BestSolutionAnalyzer(this, cloner); } } }