using System.Collections.Generic; using HeuristicLab.BioBoost.ProblemDescription; using HeuristicLab.BioBoost.Representation; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using System.Linq; using System.Linq.Expressions; using System.Security.Cryptography; namespace HeuristicLab.BioBoost.Analysis { [Item("BestBioBoostSolutionAnalyzer", "An operator for analyzing the best bioboost solution.")] [StorableClass] public class BestBioBoostSolutionAnalyzer : SingleSuccessorOperator, IAnalyzer { public bool EnabledByDefault { get { return true; } } #region Parameters public LookupParameter MaximizationParameter { get { return (LookupParameter) Parameters["Maximization"]; } } public ScopeTreeLookupParameter TotalCostParameter { get { return (ScopeTreeLookupParameter) Parameters["TotalCost"]; } } public LookupParameter ProblemDataParameter { get { return (LookupParameter) Parameters["ProblemData"]; } } public LookupParameter BestSolutionParameter { get { return (LookupParameter) Parameters["BestSolution"]; } } public ValueLookupParameter ResultsParameter { get { return (ValueLookupParameter)Parameters["Results"]; } } public LookupParameter BestKnownQualityParameter { get { return (LookupParameter)Parameters["BestKnownQuality"]; } } public LookupParameter BestQualityParameter { get { return (LookupParameter)Parameters["BestQuality"]; } } public LookupParameter BestKnownSolutionParameter { get { return (LookupParameter)Parameters["BestKnownSolution"]; } } public LookupParameter> SolutionHistoryParameter { get { return (LookupParameter>)Parameters["SolutionHistory"]; } } public ValueLookupParameter TrackHistoryParameter { get { return (ValueLookupParameter) Parameters["TrackHistory"]; } } #endregion #region Parameter Values public bool Maximization { get { return MaximizationParameter.ActualValue.Value; } } public BioBoostProblemData ProblemData { get { return ProblemDataParameter.ActualValue; } } public BioBoostCompoundSolution BestSolution { get { return BestSolutionParameter.ActualValue; } set { BestSolutionParameter.ActualValue = value; } } private bool TrackHistory { get { return TrackHistoryParameter.ActualValue.Value; } } #endregion #region Construction & Cloning [StorableConstructor] protected BestBioBoostSolutionAnalyzer(bool isDeserializing) : base(isDeserializing) {} protected BestBioBoostSolutionAnalyzer(BestBioBoostSolutionAnalyzer orig, Cloner cloner) : base(orig, cloner) {} public BestBioBoostSolutionAnalyzer() { Parameters.Add(new LookupParameter("Maximization", "Whether this is a maximization problem.")); Parameters.Add(new ScopeTreeLookupParameter("TotalCost", "The total cost of the whole scenario.")); Parameters.Add(new LookupParameter("ProblemData", "The collection of problem data.")); Parameters.Add(new LookupParameter("BestSolution", "Aggregation of solution components.")); Parameters.Add(new ValueLookupParameter("Results", "The result collection where the best solution should be stored.")); Parameters.Add(new LookupParameter("BestKnownQuality", "The quality of the best known solution of this instance.")); Parameters.Add(new LookupParameter("BestQuality", "The quality of the best solution of this run.")); Parameters.Add(new LookupParameter("BestKnownSolution", "The best known solution of this instance.")); Parameters.Add(new LookupParameter>("SolutionHistory", "The history of best solutions over time.")); Parameters.Add(new ValueLookupParameter("TrackHistory", "True if all best solutions (over time) should be recorded in SolutionHistory", new BoolValue(false))); } public override IDeepCloneable Clone(Cloner cloner) { return new BestBioBoostSolutionAnalyzer(this, cloner); } [StorableHook(HookType.AfterDeserialization)] public void AfterDeserialization() { if (!Parameters.ContainsKey("Maximization")) Parameters.Add(new LookupParameter("Maximization", "Whether this is a maximization problem.")); if (!Parameters.ContainsKey("SolutionHistory")) Parameters.Add(new LookupParameter>("SolutionHistory", "The history of best solutions over time.")); if (!Parameters.ContainsKey("TrackHistory")) Parameters.Add(new ValueLookupParameter("TrackHistory", "True if all best solutions (over time) should be recorded in SolutionHistory", new BoolValue(false))); if (!Parameters.ContainsKey("BestQuality")) Parameters.Add(new LookupParameter("BestQuality", "The quality of the best solution of this run.")); } #endregion IEnumerable GetSubScopes(IScope scope, int depth) { if (depth == 1) return scope.SubScopes; return scope.SubScopes.Select(s => GetSubScopes(s, depth - 1)).Aggregate((l1, l2) => l1.Concat(l2)); } public override IOperation Apply() { var costs = TotalCostParameter.ActualValue.Select((cost, idx) => new {cost.Value, idx}).OrderBy(p => p.Value); var best = Maximization ? costs.Last() : costs.First(); var bestScope = TotalCostParameter.Depth == 0 ? ExecutionContext.Scope : GetSubScopes(ExecutionContext.Scope, TotalCostParameter.Depth).ToList()[best.idx]; var newBestSolution = new BioBoostCompoundSolution(bestScope, ProblemData); if (BestSolution == null) { BestSolution = newBestSolution; ResultsParameter.ActualValue.Add(new Result("BestSolution", BestSolution)); } else { BestSolution.UpdateTo(newBestSolution); } if (BestKnownQualityParameter.ActualValue == null || Maximization && best.Value > BestKnownQualityParameter.ActualValue.Value || !Maximization && best.Value < BestKnownQualityParameter.ActualValue.Value) { BestKnownQualityParameter.ActualValue = new DoubleValue(best.Value); BestKnownSolutionParameter.ActualValue = BestSolution; } if (TrackHistory && (BestQualityParameter.ActualValue == null || Maximization && best.Value > BestQualityParameter.ActualValue.Value || !Maximization && best.Value < BestQualityParameter.ActualValue.Value)) { IResult solutionHistoryResult = null; if (!ResultsParameter.ActualValue.TryGetValue("SolutionHistory", out solutionHistoryResult)) { solutionHistoryResult = new Result("SolutionHistory", new ItemCollection()); ResultsParameter.ActualValue.Add(solutionHistoryResult); } ((ItemCollection) solutionHistoryResult.Value).Add( (BioBoostCompoundSolution) newBestSolution.SlimClone()); } return base.Apply(); } } }