#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; using System.Collections.Generic; using System.Linq; using HeuristicLab.Algorithms.OffspringSelectionGeneticAlgorithm; 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 HeuristicLab.Problems.DataAnalysis.Symbolic; namespace HeuristicLab.Algorithms.DataAnalysis.Symbolic { [Item("Symbolic Data Analysis Island Offspring Selection Genetic Algorithm", "A symbolic data analysis island offspring selection genetic algorithm.")] [Creatable("Data Analysis")] [StorableClass] public sealed class SymbolicDataAnalysisIslandOffspringSelectionGeneticAlgorithm : IslandOffspringSelectionGeneticAlgorithm { private const string FixedSamplesParameterName = "NumberOfFixedSamples"; private const string FixedSamplesPartitionParameterName = "FixedSamplesPartition"; private const string FixedSamplesPartitionsParameterName = "FixedSamplesPartitions"; private const string RandomSamplesParameterName = "NumberOfRandomSamples"; private const string EvaluatorParameterName = "IslandEvaluator"; private const string ProblemEvaluatorParameterName = "ProblemEvaluator"; #region Problem Properties public override Type ProblemType { get { return typeof(ISymbolicDataAnalysisSingleObjectiveProblem); } } public new ISymbolicDataAnalysisSingleObjectiveProblem Problem { get { return (ISymbolicDataAnalysisSingleObjectiveProblem)base.Problem; } set { base.Problem = value; } } #endregion #region parameters public IFixedValueParameter FixedSamplesParameter { get { return (IFixedValueParameter)Parameters[FixedSamplesParameterName]; } } public IValueParameter> FixedSamplesPartitionsParameter { get { return (IValueParameter>)Parameters[FixedSamplesPartitionsParameterName]; } } public IFixedValueParameter RandomSamplesParameter { get { return (IFixedValueParameter)Parameters[RandomSamplesParameterName]; } } public IValueParameter EvaluatorParameter { get { return (IValueParameter)Parameters[EvaluatorParameterName]; } } private ILookupParameter ProblemEvaluatorParameter { get { return (ILookupParameter)Parameters[ProblemEvaluatorParameterName]; } } #endregion #region properties public int FixedSamples { get { return FixedSamplesParameter.Value.Value; } set { FixedSamplesParameter.Value.Value = value; } } public ItemArray FixedSamplesPartitions { get { return FixedSamplesPartitionsParameter.Value; } set { FixedSamplesPartitionsParameter.Value = value; } } public int RandomSamples { get { return RandomSamplesParameter.Value.Value; } set { RandomSamplesParameter.Value.Value = value; } } #endregion [StorableConstructor] private SymbolicDataAnalysisIslandOffspringSelectionGeneticAlgorithm(bool deserializing) : base(deserializing) { } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { RegisterParameterEvents(); } private SymbolicDataAnalysisIslandOffspringSelectionGeneticAlgorithm(SymbolicDataAnalysisIslandOffspringSelectionGeneticAlgorithm original, Cloner cloner) : base(original, cloner) { RegisterParameterEvents(); } public override IDeepCloneable Clone(Cloner cloner) { return new SymbolicDataAnalysisIslandOffspringSelectionGeneticAlgorithm(this, cloner); } public SymbolicDataAnalysisIslandOffspringSelectionGeneticAlgorithm() : base() { Parameters.Add(new FixedValueParameter(FixedSamplesParameterName, "The number of fixed samples used for fitness calculation in each island.", new IntValue(0))); Parameters.Add(new ValueParameter>(FixedSamplesPartitionsParameterName, "The fixed samples partitions used for fitness calculation for every island.")); Parameters.Add(new FixedValueParameter(RandomSamplesParameterName, "The number of random samples used for fitness calculation in each island.", new IntValue(0))); Parameters.Add(new OptionalValueParameter(EvaluatorParameterName, "The evaluator of the algorithm.")); Parameters.Add(new LookupParameter(ProblemEvaluatorParameterName, "Internal parameter for name translation", "Evaluator")); ScopeTreeAssigner fixedSamplesPartitionCreator = new ScopeTreeAssigner(); fixedSamplesPartitionCreator.Name = "Create fixed evaluation partition"; fixedSamplesPartitionCreator.LeftSideParameter.ActualName = FixedSamplesPartitionParameterName; fixedSamplesPartitionCreator.RightSideParameter.ActualName = FixedSamplesPartitionsParameterName; SubScopesCreator insertionPoint = OperatorGraph.Iterate().OfType().First(); fixedSamplesPartitionCreator.Successor = insertionPoint.Successor; insertionPoint.Successor = fixedSamplesPartitionCreator; RegisterParameterEvents(); RecalculateFixedSamplesPartitions(); } private void RegisterParameterEvents() { if (Problem != null) Problem.FitnessCalculationPartition.ValueChanged += Problem_Reset; NumberOfIslandsParameter.ValueChanged += NumberOfIslandsParameter_ValueChanged; NumberOfIslandsParameter.Value.ValueChanged += (o, ev) => RecalculateFixedSamplesPartitions(); FixedSamplesParameter.Value.ValueChanged += (o, e) => { RecalculateFixedSamplesPartitions(); ReevaluateImmigrants = FixedSamples >= Problem.FitnessCalculationPartition.Size; }; RandomSamplesParameter.Value.ValueChanged += (o, e) => { ReevaluteElites = RandomSamples != 0; }; Analyzer.Operators.PropertyChanged += (o, e) => ParameterizeAnalyzers(); EvaluatorParameter.ValueChanged += (o, e) => ParameterizeEvaluator(); } protected override void ParameterizeSolutionsCreator() { base.ParameterizeSolutionsCreator(); SolutionsCreator.EvaluatorParameter.ActualName = EvaluatorParameterName; } protected override void ParameterizeMainLoop() { base.ParameterizeMainLoop(); MainLoop.EvaluatorParameter.ActualName = EvaluatorParameterName; MainLoop.QualityParameter.ActualName = EvaluatorParameter.Value.QualityParameter.ActualName; } protected override void ParameterizeAnalyzers() { base.ParameterizeAnalyzers(); foreach (var analyzer in Analyzer.Operators.OfType()) { IParameter evaluatorParameter; if (analyzer.Parameters.TryGetValue("Evaluator", out evaluatorParameter)) { ILookupParameter param = evaluatorParameter as ILookupParameter; if (evaluatorParameter != null) param.ActualName = ProblemEvaluatorParameterName; } } } private void ParameterizeEvaluator() { var evaluator = EvaluatorParameter.Value; var islandGAEvaluator = evaluator as SymbolicDataAnalysisIslandGAEvaluator; if (islandGAEvaluator != null) { islandGAEvaluator.RandomSamplesParameter.ActualName = RandomSamplesParameterName; } } private void NumberOfIslandsParameter_ValueChanged(object sender, EventArgs e) { NumberOfIslands.ValueChanged += (o, ev) => RecalculateFixedSamplesPartitions(); RecalculateFixedSamplesPartitions(); } protected override void Problem_Reset(object sender, EventArgs e) { FixedSamples = Problem.FitnessCalculationPartition.Size / NumberOfIslands.Value; base.Problem_Reset(sender, e); } protected override void OnProblemChanged() { Problem.FitnessCalculationPartition.ValueChanged += Problem_Reset; FixedSamples = Problem.FitnessCalculationPartition.Size / NumberOfIslands.Value; if (Problem != null && EvaluatorParameter.Value == null) { EvaluatorParameter.Value = new SymbolicDataAnalysisIslandGAEvaluator(); } else if (Problem == null) EvaluatorParameter.Value = null; ParameterizeStochasticOperator(EvaluatorParameter.Value); RecalculateFixedSamplesPartitions(); base.OnProblemChanged(); } private void RecalculateFixedSamplesPartitions() { if (Problem == null) { FixedSamplesPartitions = new ItemArray(Enumerable.Repeat(new IntRange(), NumberOfIslands.Value)); return; } var samplesStart = Problem.FitnessCalculationPartition.Start; var samplesEnd = Problem.FitnessCalculationPartition.End; var totalSamples = Problem.FitnessCalculationPartition.Size; var fixedSamples = FixedSamples; var islands = NumberOfIslands.Value; int offset = (int)Math.Ceiling(((double)(totalSamples - fixedSamples)) / (islands - 1)); List partitions = new List(); for (int i = 0; i < islands; i++) { var partitionStart = samplesStart + offset * i; partitions.Add(new IntRange(partitionStart, partitionStart + fixedSamples)); } //it can be the case that the last partitions exceeds the allowed samples //move the last partition forward. int exceedsSamples = partitions[partitions.Count - 1].End - samplesEnd; if (exceedsSamples > 0) { partitions[partitions.Count - 1].Start -= exceedsSamples; partitions[partitions.Count - 1].End -= exceedsSamples; } FixedSamplesPartitions = new ItemArray(partitions); } } }