#region License Information /* HeuristicLab * Copyright (C) 2002-2012 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 System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using Google.ProtocolBuffers; using HeuristicLab.Analysis; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Encodings.RealVectorEncoding; using HeuristicLab.Optimization; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.ExternalEvaluation.RepetitionsExtension; namespace HeuristicLab.Problems.ExternalEvaluation.MyExtension { [Item("ExtendedExternalEvaluationProblem", "Creates a solution message, and communicates it via the driver to receive a quality message.")] [StorableClass] public class ExtendedExternalEvaluationProblem : ExternalEvaluationProblem, IStatefulItem { private IDictionary messages; [Storable(Name = "Messages")] [SuppressMessage("ReSharper", "InconsistentlySynchronizedField")] [SuppressMessage("ReSharper", "InconsistentNaming")] private IEnumerable> Messages_Persistence { get { return messages.ToDictionary( kvp => kvp.Key.ToByteArray(), kvp => kvp.Value.ToByteArray()); } set { messages = value.ToDictionary( kvp => SolutionMessage.ParseFrom(ByteString.CopyFrom(kvp.Key)), kvp => QualityMessage.ParseFrom(ByteString.CopyFrom(kvp.Value), GetQualityMessageExtensions())); } } #region Construction & Cloning [StorableConstructor] private ExtendedExternalEvaluationProblem(bool deserializing) : base(deserializing) { } private ExtendedExternalEvaluationProblem(ExtendedExternalEvaluationProblem original, Cloner cloner) : base(original, cloner) { Messages_Persistence = original.Messages_Persistence; } public override IDeepCloneable Clone(Cloner cloner) { return new ExtendedExternalEvaluationProblem(this, cloner); } public ExtendedExternalEvaluationProblem() : base() { messages = new Dictionary(); Encoding = new RealVectorEncoding("r", length: 40, min: 0, max: 10); } #endregion public override QualityMessage Evaluate(SolutionMessage solutionMessage) { var qualityMessage = base.Evaluate(solutionMessage); lock (messages) { messages.Add(solutionMessage, qualityMessage); } return qualityMessage; } public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) { base.Analyze(individuals, qualities, results, random); lock (messages) { ExtendedAnalyze(messages.Keys.ToArray(), messages.Values.ToArray(), results, Encoding, random); messages.Clear(); } } public virtual void ExtendedAnalyze(SolutionMessage[] solutionMessages, QualityMessage[] qualityMessages, ResultCollection results, IEncoding encoding, IRandom random) { if (!results.ContainsKey("SolutionsHistory")) { var dataTable = new DataTable("SolutionsHistory"); int solutionLength = ((RealVectorEncoding)encoding).Length; for (int i = 0; i < solutionLength; i++) dataTable.Rows.Add(new DataRow("a" + i, "Parameter " + i)); dataTable.Rows.Add(new DataRow("Quality")); dataTable.Rows.Add(new DataRow("Repetitions")); dataTable.Rows.Add(new DataRow("Variance")); dataTable.Rows.Add(new DataRow("CanceledRuns")); results.Add(new Result("SolutionsHistory", dataTable)); } var solutions = from result in solutionMessages.Zip(qualityMessages, (sm, qm) => new { sm, qm }) select new { inputs = result.sm.GetDoubleArrayVars(0).DataList, quality = result.qm.GetExtension(SingleObjectiveQualityMessage.QualityMessage_).Quality, repititions = GetExtension(result.qm, RepetitionsResponse.Repetitions, 1), variance = GetExtension(result.qm, RepetitionsResponse.Variance, 0), canceledRuns = GetExtension(result.qm, RepetitionsResponse.NumFailed, 0) }; var solutionsHistory = (DataTable)results["SolutionsHistory"].Value; foreach (var solution in solutions.OrderBy(s => s.quality)) { for (int i = 0; i < solution.inputs.Count; i++) solutionsHistory.Rows["a" + i].Values.Add(solution.inputs[i]); solutionsHistory.Rows["Quality"].Values.Add(solution.quality); solutionsHistory.Rows["Repetitions"].Values.Add(solution.repititions); solutionsHistory.Rows["Variance"].Values.Add(solution.variance); solutionsHistory.Rows["CanceledRuns"].Values.Add(solution.canceledRuns); } } private T GetExtension(QualityMessage msg, GeneratedExtensionBase extension, T @default = default(T)) { return msg.HasExtension(extension) ? msg.GetExtension(extension) : @default; } public override ExtensionRegistry GetQualityMessageExtensions() { var extensions = base.GetQualityMessageExtensions(); RepetitionsQualityMessage.RegisterAllExtensions(extensions); return extensions; } public void InitializeState() { } public void ClearState() { lock (messages) messages.Clear(); } } }