using System; using System.Collections.Generic; using System.Linq; using System.Threading; using HeuristicLab.Algorithms.DataAnalysis; using HeuristicLab.Analysis; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.IntegerVectorEncoding; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Optimization.Operators; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.DataAnalysis; using HeuristicLab.Random; namespace HeuristicLab.Algorithms.EGO { [Item("Discrete Adaptive Sampling Algorithm (D-EGO)", "A discrete adaptive sampling algorithm.")] [Creatable(CreatableAttribute.Categories.SingleSolutionAlgorithms, Priority = 150)] [StorableClass] public class DiscreteAdaptiveSamplingAlgorithm : HeuristicOptimizationEngineAlgorithm, IStorableContent { public string Filename { get; set; } #region Problem Properties public override Type ProblemType => typeof(IHeuristicOptimizationProblem); private ISingleObjectiveHeuristicOptimizationProblem SingleObjectiveProblem => Problem as ISingleObjectiveHeuristicOptimizationProblem; #endregion #region Parameter Names private const string InfillCriterionParameterName = "InfillCriterion"; private const string InitialEvaluationsParameterName = "Initial Evaluations"; private const string TerminatorParameterName = "Terminator"; private const string SeedParameterName = "Seed"; private const string SetSeedRandomlyParameterName = "SetSeedRandomly"; private const string RegressionAlgorithmParameterName = "RegressionAlgorithm"; private const string InfillOptimizationAlgorithmParameterName = "InfillOptimizationAlgorithm"; private const string AnalyzerParameterName = "Analyzers"; private const string RemoveDuplicatesParamterName = "PerturbDuplicates"; private const string MaxModelSizeParameterName = "Maximal Model Size"; private const string InitialDatasetParameterName = "SampleSet"; #endregion #region Parameter Properties public IFixedValueParameter SeedParameter => (IFixedValueParameter)Parameters[SeedParameterName]; public IFixedValueParameter SetSeedRandomlyParameter => (IFixedValueParameter)Parameters[SetSeedRandomlyParameterName]; public IFixedValueParameter TerminatorParameter => (IFixedValueParameter)Parameters[TerminatorParameterName]; public IFixedValueParameter InitialEvaluationsParameter => (IFixedValueParameter)Parameters[InitialEvaluationsParameterName]; public IConstrainedValueParameter InfillCriterionParameter => Parameters[InfillCriterionParameterName] as IConstrainedValueParameter; public IValueParameter InfillOptimizationAlgorithmParameter => Parameters[InfillOptimizationAlgorithmParameterName] as IValueParameter; public IValueParameter> RegressionAlgorithmParameter => Parameters[RegressionAlgorithmParameterName] as IValueParameter>; public IFixedValueParameter AnalyzerParameter => (IFixedValueParameter)Parameters[AnalyzerParameterName]; public IFixedValueParameter RemoveDuplicatesParameter => (IFixedValueParameter)Parameters[RemoveDuplicatesParamterName]; public IFixedValueParameter MaxModelSizeParameter => (IFixedValueParameter)Parameters[MaxModelSizeParameterName]; public IValueParameter InitialDatasetParameter => (IValueParameter)Parameters[InitialDatasetParameterName]; #endregion #region Properties public int Seed => SeedParameter.Value.Value; public bool SetSeedRandomly => SetSeedRandomlyParameter.Value.Value; public MultiTerminator Terminator => TerminatorParameter.Value; public MultiAnalyzer Analyzer => AnalyzerParameter.Value; public int InitialEvaluations => InitialEvaluationsParameter.Value.Value; public IInfillCriterion InfillCriterion => InfillCriterionParameter.Value; public Algorithm InfillOptimizationAlgorithm => InfillOptimizationAlgorithmParameter.Value; public IDataAnalysisAlgorithm RegressionAlgorithm => RegressionAlgorithmParameter.Value; public bool RemoveDuplicates => RemoveDuplicatesParameter.Value.Value; public int MaxModelSize => MaxModelSizeParameter.Value.Value; private SolutionsCreator SolutionsCreator => OperatorGraph.Iterate().OfType().First(); public IDataset InitialDataset => InitialDatasetParameter.Value; #endregion #region Operators [Storable] private OperatorList Operators; #region Preconfigured Analyzers [Storable] private BestAverageWorstQualityAnalyzer singleObjectiveQualityAnalyzer; [Storable] private DiscreteCorrelationAnalyzer correlationAnalyzer; [Storable] private DiscreteEvaluatedSolutionsAnalyzer sampleAnalyzer; [Storable] private ModelQualityAnalyzer modelAnalyzer; [Storable] private VariableVariabilityAnalyzer variabilityAnalyzer; [Storable] private FitnessClusteringAnalyzer fitnessClusterAnalyzer; #endregion #region Preconfigured Terminators [Storable] private ComparisonTerminator evaluationsTerminator; [Storable] private ExecutionTimeTerminator executionTimeTerminator; [Storable] private SingleObjectiveQualityTerminator qualityTerminator; #endregion #region Problem-dependent Operators [Storable] private DiscreteSampleCollector sampleCollector; [Storable] private DiscreteInfillSolver infillSolver; [Storable] private SolutionsCreator infillSolutionsCreator; #endregion #endregion #region Constructors [StorableConstructor] protected DiscreteAdaptiveSamplingAlgorithm(bool deserializing) : base(deserializing) { } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { Initialize(); } protected DiscreteAdaptiveSamplingAlgorithm(DiscreteAdaptiveSamplingAlgorithm original, Cloner cloner) : base(original, cloner) { singleObjectiveQualityAnalyzer = cloner.Clone(original.singleObjectiveQualityAnalyzer); evaluationsTerminator = cloner.Clone(original.evaluationsTerminator); qualityTerminator = cloner.Clone(original.qualityTerminator); executionTimeTerminator = cloner.Clone(original.executionTimeTerminator); sampleCollector = cloner.Clone(original.sampleCollector); infillSolver = cloner.Clone(original.infillSolver); infillSolutionsCreator = cloner.Clone(original.infillSolutionsCreator); correlationAnalyzer = cloner.Clone(original.correlationAnalyzer); sampleAnalyzer = cloner.Clone(original.sampleAnalyzer); modelAnalyzer = cloner.Clone(original.modelAnalyzer); fitnessClusterAnalyzer = cloner.Clone(original.fitnessClusterAnalyzer); Operators = cloner.Clone(original.Operators); Initialize(); } public override IDeepCloneable Clone(Cloner cloner) { return new DiscreteAdaptiveSamplingAlgorithm(this, cloner); } public DiscreteAdaptiveSamplingAlgorithm() { #region Add parameters var criteria = new ItemSet { new AugmentedExpectedImprovement(), new ExpectedImprovement(), new ExpectedQuality(), new ExpectedQuantileImprovement(), new MinimalQuantileCriterium(), new NeighbourDistance(), new PluginExpectedImprovement() }; var cmaes = new OffspringSelectionGeneticAlgorithm.OffspringSelectionGeneticAlgorithm { MaximumGenerations = new IntValue(300), PopulationSize = new IntValue(50), Problem = new DiscreteInfillProblem() }; var model = new GaussianProcessRegression { Problem = new RegressionProblem() }; model.CovarianceFunctionParameter.Value = new CovarianceRationalQuadraticIso(); Parameters.Add(new FixedValueParameter(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0))); Parameters.Add(new FixedValueParameter(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true))); Parameters.Add(new FixedValueParameter("Terminator", "The termination criteria that defines if the algorithm should continue or stop.", new MultiTerminator())); Parameters.Add(new FixedValueParameter(AnalyzerParameterName, "The operator used to analyze the solutions each iteration.", new MultiAnalyzer())); Parameters.Add(new FixedValueParameter(InitialEvaluationsParameterName, "The number of random solutions that are evaluated (in parallel) per iteration.", new IntValue(100))); Parameters.Add(new ConstrainedValueParameter(InfillCriterionParameterName, "Decision what value should decide the next sample", criteria, criteria.OfType().Single())); Parameters.Add(new ValueParameter>(RegressionAlgorithmParameterName, "The model used to approximate the problem", model)); Parameters.Add(new ValueParameter(InfillOptimizationAlgorithmParameterName, "The algorithm used to solve the expected improvement subproblem", cmaes)); Parameters.Add(new FixedValueParameter(RemoveDuplicatesParamterName, "Whether (almost) duplicate points in the dataset should be perturbed before evaluation (this greatly increases numerical stability for some model types)", new BoolValue(true))); Parameters.Add(new FixedValueParameter("Maximal Model Size", "The maximum number of sample points used to build the model", new IntValue(-1))); Parameters.Add(new ValueParameter(InitialDatasetParameterName, "The initial dataset that should be built upon.", new ModifiableDataset())); #endregion #region Create operators Operators = new OperatorList(); var randomCreator = new RandomCreator(); Operators.Add(randomCreator); var variableCreator = new VariableCreator { Name = "Initialize Variables" }; Operators.Add(variableCreator); var resultsCollector = new ResultsCollector(); Operators.Add(resultsCollector); var solutionCreator = new SolutionsCreator { Name = "Create Initial Solutions" }; Operators.Add(solutionCreator); var analyzerPlaceholder = new Placeholder { Name = "Analyzer (Placeholder)" }; Operators.Add(analyzerPlaceholder); var evaluationsCounter = new IntCounter { Name = "Increment EvaluatedSolutions" }; Operators.Add(evaluationsCounter); var solutionsCollectorProcessor = new UniformSubScopesProcessor { Name = "Collect Samples to Dataset" }; Operators.Add(solutionsCollectorProcessor); var phaseChecker = new ConditionalBranch { Name = "Inital Samples evaluated?" }; Operators.Add(phaseChecker); var initialPhaseChecker = new Comparator { Name = "Compare Initial Samples to evaluated Solutions" }; Operators.Add(initialPhaseChecker); var modelbuilder = new ModelBuilder { Name = "Build Model" }; Operators.Add(modelbuilder); sampleCollector = new DiscreteSampleCollector { Name = "Collect Sample" }; Operators.Add(sampleCollector); infillSolutionsCreator = new SolutionsCreator { Name = "Create Adaptive Solutions" }; Operators.Add(infillSolutionsCreator); infillSolver = new DiscreteInfillSolver(); Operators.Add(infillSolver); var subScopesRemover = new SubScopesRemover(); Operators.Add(subScopesRemover); var iterationsCounter = new IntCounter { Name = "Increment Iterations" }; Operators.Add(iterationsCounter); var terminationOperator = new TerminationOperator(); Operators.Add(terminationOperator); #endregion #region Wire operators const string iterationsVariableName = "Iterations"; const string evaluatedSolutionsVariableName = "EvaluatedSolutions"; const string datasetVariableName = "SampleSet"; const string modelVariableName = "Model"; const string initialPhaseVariableName = "InitialPhase"; const string infillBoundsVariableName = "InfillBounds"; OperatorGraph.InitialOperator = randomCreator; randomCreator.SeedParameter.Value = null; randomCreator.SeedParameter.ActualName = SeedParameter.Name; randomCreator.SetSeedRandomlyParameter.Value = null; randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name; randomCreator.Successor = variableCreator; variableCreator.CollectedValues.Add(new ValueParameter(iterationsVariableName, new IntValue(0))); variableCreator.CollectedValues.Add(new ValueParameter(evaluatedSolutionsVariableName, new IntValue(0))); variableCreator.CollectedValues.Add(new ValueParameter(datasetVariableName, new ModifiableDataset())); variableCreator.CollectedValues.Add(new ValueParameter(modelVariableName, "The regression solution representing the model for EGO", null)); variableCreator.CollectedValues.Add(new FixedValueParameter(initialPhaseVariableName, new BoolValue(false))); variableCreator.CollectedValues.Add(new ValueParameter(infillBoundsVariableName)); variableCreator.Successor = resultsCollector; resultsCollector.CollectedValues.Add(new LookupParameter(iterationsVariableName, "The current iteration number.")); resultsCollector.CollectedValues.Add(new LookupParameter(evaluatedSolutionsVariableName, "The current number of evaluated solutions.")); resultsCollector.CollectedValues.Add(new LookupParameter(datasetVariableName, "A dataset containing all evaluated solutions")); resultsCollector.Successor = phaseChecker; phaseChecker.ConditionParameter.ActualName = initialPhaseVariableName; phaseChecker.FalseBranch = solutionCreator; phaseChecker.TrueBranch = modelbuilder; #region Adaptive Phase modelbuilder.DatasetParameter.ActualName = datasetVariableName; modelbuilder.ModelParameter.ActualName = modelVariableName; modelbuilder.RegressionAlgorithmParameter.ActualName = RegressionAlgorithmParameter.Name; modelbuilder.Successor = infillSolutionsCreator; modelbuilder.MaxModelSizeParameter.ActualName = MaxModelSizeParameter.Name; infillSolutionsCreator.SolutionCreatorParameter.Value = infillSolver; infillSolutionsCreator.Successor = evaluationsCounter; infillSolutionsCreator.NumberOfSolutionsParameter.Value = new IntValue(1); infillSolver.InfillOptimizationAlgorithmParamter.ActualName = InfillOptimizationAlgorithmParameterName; infillSolver.ModelParameter.ActualName = modelVariableName; infillSolver.RemoveDuplicatesParameter.ActualName = RemoveDuplicatesParameter.Name; infillSolver.InfillBoundsParameter.ActualName = infillBoundsVariableName; #endregion #region Initial Phase solutionCreator.NumberOfSolutionsParameter.Value = new IntValue(1); solutionCreator.ParallelParameter.Value.Value = true; solutionCreator.Successor = evaluationsCounter; #endregion evaluationsCounter.ValueParameter.ActualName = evaluatedSolutionsVariableName; evaluationsCounter.Increment = null; evaluationsCounter.IncrementParameter.Value = new IntValue(1); evaluationsCounter.Successor = initialPhaseChecker; initialPhaseChecker.Comparison = new Comparison(ComparisonType.GreaterOrEqual); initialPhaseChecker.LeftSideParameter.ActualName = evaluatedSolutionsVariableName; initialPhaseChecker.RightSideParameter.ActualName = InitialEvaluationsParameterName; initialPhaseChecker.ResultParameter.ActualName = initialPhaseVariableName; initialPhaseChecker.Successor = analyzerPlaceholder; analyzerPlaceholder.OperatorParameter.ActualName = AnalyzerParameter.Name; analyzerPlaceholder.Successor = solutionsCollectorProcessor; solutionsCollectorProcessor.Operator = sampleCollector; solutionsCollectorProcessor.Depth.Value = 1; solutionsCollectorProcessor.Successor = subScopesRemover; sampleCollector.DatasetParameter.ActualName = datasetVariableName; subScopesRemover.RemoveAllSubScopes = true; subScopesRemover.Successor = iterationsCounter; iterationsCounter.ValueParameter.ActualName = "Iterations"; iterationsCounter.Increment = new IntValue(1); iterationsCounter.Successor = terminationOperator; terminationOperator.TerminatorParameter.ActualName = TerminatorParameter.Name; terminationOperator.ContinueBranch = phaseChecker; #endregion #region Create analyzers singleObjectiveQualityAnalyzer = new BestAverageWorstQualityAnalyzer(); Operators.Add(singleObjectiveQualityAnalyzer); correlationAnalyzer = new DiscreteCorrelationAnalyzer(); correlationAnalyzer.ModelParameter.ActualName = modelVariableName; Operators.Add(correlationAnalyzer); sampleAnalyzer = new DiscreteEvaluatedSolutionsAnalyzer(); sampleAnalyzer.PhaseParameter.ActualName = initialPhaseVariableName; Operators.Add(sampleAnalyzer); modelAnalyzer = new ModelQualityAnalyzer(); modelAnalyzer.ModelParameter.ActualName = modelVariableName; Operators.Add(modelAnalyzer); variabilityAnalyzer = new VariableVariabilityAnalyzer(); variabilityAnalyzer.DatasetParameter.ActualName = datasetVariableName; variabilityAnalyzer.InitialEvaluationsParameter.ActualName = InitialEvaluationsParameter.Name; Operators.Add(variabilityAnalyzer); fitnessClusterAnalyzer = new FitnessClusteringAnalyzer(); fitnessClusterAnalyzer.DatasetParameter.ActualName = datasetVariableName; Operators.Add(fitnessClusterAnalyzer); #endregion #region Create terminators evaluationsTerminator = new ComparisonTerminator("EvaluatedSolutions", ComparisonType.Less, new IntValue(1000)) { Name = "Evaluated solutions." }; Operators.Add(evaluationsTerminator); qualityTerminator = new SingleObjectiveQualityTerminator { Name = "Quality" }; Operators.Add(qualityTerminator); executionTimeTerminator = new ExecutionTimeTerminator(this, new TimeSpanValue(TimeSpan.FromMinutes(5))); Operators.Add(executionTimeTerminator); #endregion #region Parameterize UpdateAnalyzers(); ParameterizeAnalyzers(); ParameterizeStochasticOperators(Operators); UpdateTerminators(); #endregion Initialize(); } private void Initialize() { if (SingleObjectiveProblem != null) { SingleObjectiveProblem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged; } singleObjectiveQualityAnalyzer.CurrentBestQualityParameter.NameChanged += QualityAnalyzer_CurrentBestQualityParameter_NameChanged; RegisterParameterEvents(); } #endregion public override void Start(CancellationToken cancellationToken) { ParameterizeProblemSpecificOperators(); ((DiscreteInfillProblem)InfillOptimizationAlgorithm.Problem).InfillCriterion = InfillCriterion; ParameterizeCancellableOperators(cancellationToken); base.Start(cancellationToken); } public override void Stop() { if (InfillOptimizationAlgorithm.ExecutionState == ExecutionState.Started || InfillOptimizationAlgorithm.ExecutionState == ExecutionState.Paused) InfillOptimizationAlgorithm.Stop(); if (RegressionAlgorithm.ExecutionState == ExecutionState.Started || RegressionAlgorithm.ExecutionState == ExecutionState.Paused) RegressionAlgorithm.Stop(); base.Stop(); } public override void Pause() { if (InfillOptimizationAlgorithm.ExecutionState == ExecutionState.Started) InfillOptimizationAlgorithm.Pause(); if (RegressionAlgorithm.ExecutionState == ExecutionState.Started) RegressionAlgorithm.Pause(); base.Pause(); } #region Parameterization private void ParameterizeTerminators() { if (SingleObjectiveProblem != null) qualityTerminator.Parameterize(singleObjectiveQualityAnalyzer.CurrentBestQualityParameter, SingleObjectiveProblem); } private void ParameterizeAnalyzers() { foreach (var op in Operators.OfType()) { op.ResultsParameter.ActualName = "Results"; op.ResultsParameter.Hidden = true; } singleObjectiveQualityAnalyzer.ResultsParameter.ActualName = "Results"; singleObjectiveQualityAnalyzer.ResultsParameter.Hidden = true; singleObjectiveQualityAnalyzer.QualityParameter.Depth = 1; correlationAnalyzer.QualityParameter.Depth = 1; correlationAnalyzer.IntegerVectorParameter.Depth = 1; sampleAnalyzer.QualityParameter.Depth = 1; sampleAnalyzer.IntegerVectorParameter.Depth = 1; if (SingleObjectiveProblem == null) return; singleObjectiveQualityAnalyzer.MaximizationParameter.ActualName = SingleObjectiveProblem.MaximizationParameter.Name; singleObjectiveQualityAnalyzer.MaximizationParameter.Hidden = true; singleObjectiveQualityAnalyzer.QualityParameter.ActualName = SingleObjectiveProblem.Evaluator.QualityParameter.ActualName; singleObjectiveQualityAnalyzer.QualityParameter.Hidden = true; singleObjectiveQualityAnalyzer.BestKnownQualityParameter.ActualName = SingleObjectiveProblem.BestKnownQualityParameter.Name; singleObjectiveQualityAnalyzer.BestKnownQualityParameter.Hidden = true; correlationAnalyzer.QualityParameter.ActualName = SingleObjectiveProblem.Evaluator.QualityParameter.ActualName; correlationAnalyzer.QualityParameter.Hidden = true; sampleAnalyzer.QualityParameter.ActualName = SingleObjectiveProblem.Evaluator.QualityParameter.ActualName; sampleAnalyzer.QualityParameter.Hidden = true; } private void ParameterizeSolutionsCreators() { SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name; SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name; infillSolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name; ParameterizeStochasticOperators(new[] { SolutionsCreator, infillSolutionsCreator }); } private static void ParameterizeStochasticOperators(IEnumerable operators) { foreach (var op in operators.OfType()) { op.RandomParameter.ActualName = "Random"; op.RandomParameter.Hidden = true; } } private void ParameterizeProblemSpecificOperators() { if (SingleObjectiveProblem == null) throw new ArgumentException("Adaptive sampling requires a single objective problem"); infillSolver.MaximizationParameter.ActualName = SingleObjectiveProblem.MaximizationParameter.Name; var rcreator = Problem.SolutionCreator as IIntegerVectorCreator; if (rcreator == null) throw new ArgumentException("Discrete Adaptive sampling requires integer vectors as solution candidates"); infillSolver.LengthParameter.ActualName = rcreator.LengthParameter.ActualName; infillSolver.BoundsParameter.ActualName = rcreator.BoundsParameter.ActualName; infillSolver.LengthParameter.Value = rcreator.LengthParameter.Value; infillSolver.BoundsParameter.Value = rcreator.BoundsParameter.Value; infillSolver.IntegerVectorParameter.ActualName = rcreator.IntegerVectorParameter.ActualName; sampleCollector.IntegerVectorParameter.ActualName = rcreator.IntegerVectorParameter.ActualName; sampleCollector.QualityParameter.ActualName = SingleObjectiveProblem.Evaluator.QualityParameter.ActualName; correlationAnalyzer.IntegerVectorParameter.ActualName = rcreator.IntegerVectorParameter.ActualName; sampleAnalyzer.IntegerVectorParameter.ActualName = rcreator.IntegerVectorParameter.ActualName; } private void ParameterizeCancellableOperators(CancellationToken cancellation) { foreach (var op in Operators.OfType()) op.Cancellation = cancellation; } private void UnParameterizeCancellableOperators(CancellationToken cancellation) { foreach (var op in Operators.OfType()) op.Cancellation = CancellationToken.None; } #endregion #region Events private void RegisterParameterEvents() { InfillOptimizationAlgorithmParameter.ValueChanged += OnInfillAlgorithmChanged; InfillOptimizationAlgorithm.ProblemChanged += OnInfillProblemChanged; InfillCriterionParameter.ValueChanged += OnInfillCriterionChanged; } private void OnInfillCriterionChanged(object sender, EventArgs e) { ((DiscreteInfillProblem)InfillOptimizationAlgorithm.Problem).InfillCriterion = InfillCriterion; } private void OnInfillAlgorithmChanged(object sender, EventArgs e) { InfillOptimizationAlgorithm.Problem = new DiscreteInfillProblem { InfillCriterion = InfillCriterion }; InfillOptimizationAlgorithm.ProblemChanged -= OnInfillProblemChanged; //avoid double attaching InfillOptimizationAlgorithm.ProblemChanged += OnInfillProblemChanged; } private void OnInfillProblemChanged(object sender, EventArgs e) { //enforce an infill problem for the infill optimization algorithm InfillOptimizationAlgorithm.ProblemChanged -= OnInfillProblemChanged; InfillOptimizationAlgorithm.Problem = new DiscreteInfillProblem { InfillCriterion = InfillCriterion }; InfillOptimizationAlgorithm.ProblemChanged += OnInfillProblemChanged; } protected override void OnProblemChanged() { base.OnProblemChanged(); ParameterizeStochasticOperators(Problem.Operators); UpdateAnalyzers(); UpdateTerminators(); ParameterizeSolutionsCreators(); if (SingleObjectiveProblem != null) SingleObjectiveProblem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged; } protected override void RegisterProblemEvents() { base.RegisterProblemEvents(); var maximizationParameter = (IValueParameter)SingleObjectiveProblem?.MaximizationParameter; if (maximizationParameter != null) maximizationParameter.ValueChanged += MaximizationParameter_ValueChanged; } protected override void DeregisterProblemEvents() { var maximizationParameter = (IValueParameter)SingleObjectiveProblem?.MaximizationParameter; if (maximizationParameter != null) maximizationParameter.ValueChanged -= MaximizationParameter_ValueChanged; base.DeregisterProblemEvents(); } protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) { base.Problem_SolutionCreatorChanged(sender, e); ParameterizeStochasticOperators(Problem.SolutionCreator.ToEnumerable()); SingleObjectiveProblem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged; ParameterizeSolutionsCreators(); ParameterizeAnalyzers(); } protected override void Problem_EvaluatorChanged(object sender, EventArgs e) { base.Problem_EvaluatorChanged(sender, e); ParameterizeStochasticOperators(Problem.Operators); ParameterizeSolutionsCreators(); } protected override void Problem_OperatorsChanged(object sender, EventArgs e) { base.Problem_OperatorsChanged(sender, e); UpdateAnalyzers(); UpdateTerminators(); } private void MaximizationParameter_ValueChanged(object sender, EventArgs e) { ParameterizeAnalyzers(); ParameterizeTerminators(); } private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) { ParameterizeAnalyzers(); } private void QualityAnalyzer_CurrentBestQualityParameter_NameChanged(object sender, EventArgs e) { ParameterizeTerminators(); } #endregion #region Updates private void UpdateAnalyzers() { Analyzer.Operators.Clear(); if (SingleObjectiveProblem == null) return; foreach (var analyzer in Operators.OfType().Concat(SingleObjectiveProblem.Operators.OfType())) Analyzer.Operators.Add(analyzer, analyzer.EnabledByDefault); ParameterizeAnalyzers(); } private void UpdateTerminators() { var newTerminators = new Dictionary { { evaluationsTerminator, !Terminator.Operators.Contains(evaluationsTerminator) || Terminator.Operators.ItemChecked(evaluationsTerminator) }, { executionTimeTerminator, Terminator.Operators.Contains(executionTimeTerminator) && Terminator.Operators.ItemChecked(executionTimeTerminator) } }; if (SingleObjectiveProblem != null) { newTerminators.Add(qualityTerminator, Terminator.Operators.Contains(qualityTerminator) && Terminator.Operators.ItemChecked(qualityTerminator)); foreach (var terminator in Problem.Operators.OfType()) newTerminators.Add(terminator, !Terminator.Operators.Contains(terminator) || Terminator.Operators.ItemChecked(terminator)); } Terminator.Operators.Clear(); foreach (var newTerminator in newTerminators) Terminator.Operators.Add(newTerminator.Key, newTerminator.Value); ParameterizeTerminators(); } #endregion } }