#region License Information /* HeuristicLab * Copyright (C) 2002-2015 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 HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; namespace HeuristicLab.Selection { [Item("GenderSpecificSelection", "Brings two parents together by sampling each with a different selection scheme (Wagner, S. and Affenzeller, M. 2005. SexualGA: Gender-Specific Selection for Genetic Algorithms. Proceedings of the 9th World Multi-Conference on Systemics, Cybernetics and Informatics (WMSCI), pp. 76-81).")] [StorableType("55A56CE1-B80C-4B57-BFDA-8ADF79B74EF0")] public class GenderSpecificSelector : AlgorithmOperator, ISingleObjectiveSelector, IStochasticOperator { #region Parameters public IValueLookupParameter MaximizationParameter { get { return (IValueLookupParameter)Parameters["Maximization"]; } } public ILookupParameter> QualityParameter { get { return (ILookupParameter>)Parameters["Quality"]; } } public IValueLookupParameter NumberOfSelectedSubScopesParameter { get { return (IValueLookupParameter)Parameters["NumberOfSelectedSubScopes"]; } } protected IValueLookupParameter CopySelectedParameter { get { return (IValueLookupParameter)Parameters["CopySelected"]; } } public ILookupParameter RandomParameter { get { return (ILookupParameter)Parameters["Random"]; } } public ValueParameter FemaleSelectorParameter { get { return (ValueParameter)Parameters["FemaleSelector"]; } } public ValueParameter MaleSelectorParameter { get { return (ValueParameter)Parameters["MaleSelector"]; } } #endregion #region Properties public BoolValue Maximization { get { return MaximizationParameter.Value; } set { MaximizationParameter.Value = value; } } public IntValue NumberOfSelectedSubScopes { get { return NumberOfSelectedSubScopesParameter.Value; } set { NumberOfSelectedSubScopesParameter.Value = value; } } public BoolValue CopySelected { get { return CopySelectedParameter.Value; } set { CopySelectedParameter.Value = value; } } public ISelector FemaleSelector { get { return FemaleSelectorParameter.Value; } set { FemaleSelectorParameter.Value = value; } } public ISelector MaleSelector { get { return MaleSelectorParameter.Value; } set { MaleSelectorParameter.Value = value; } } #endregion [StorableConstructor] protected GenderSpecificSelector(bool deserializing) : base(deserializing) { } protected GenderSpecificSelector(GenderSpecificSelector original, Cloner cloner) : base(original, cloner) { Initialize(); } public GenderSpecificSelector() : base() { #region Create parameters Parameters.Add(new ValueLookupParameter("Maximization", "True if the problem is a maximization problem.")); Parameters.Add(new ScopeTreeLookupParameter("Quality", "The quality of the solutions.")); Parameters.Add(new ValueLookupParameter("NumberOfSelectedSubScopes", "The number of scopes that should be selected.")); Parameters.Add(new ValueLookupParameter("CopySelected", "True if the scopes should be copied, false if they should be moved.", new BoolValue(true))); Parameters.Add(new LookupParameter("Random", "The random number generator to use.")); Parameters.Add(new ValueParameter("FemaleSelector", "The selection operator to select the first parent.")); Parameters.Add(new ValueParameter("MaleSelector", "The selection operator to select the second parent.")); CopySelectedParameter.Hidden = true; #endregion #region Create operators Placeholder femaleSelector = new Placeholder(); SubScopesProcessor maleSelection = new SubScopesProcessor(); Placeholder maleSelector = new Placeholder(); EmptyOperator empty = new EmptyOperator(); RightChildReducer rightChildReducer = new RightChildReducer(); SubScopesMixer subScopesMixer = new SubScopesMixer(); femaleSelector.OperatorParameter.ActualName = "FemaleSelector"; maleSelector.OperatorParameter.ActualName = "MaleSelector"; subScopesMixer.Partitions = new IntValue(2); #endregion #region Create operator graph OperatorGraph.InitialOperator = femaleSelector; femaleSelector.Successor = maleSelection; maleSelection.Operators.Add(maleSelector); maleSelection.Operators.Add(empty); maleSelection.Successor = rightChildReducer; rightChildReducer.Successor = subScopesMixer; #endregion Initialize(); } public override IDeepCloneable Clone(Cloner cloner) { return new GenderSpecificSelector(this, cloner); } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { Initialize(); } /// /// Sets how many sub-scopes male and female selectors should select. /// /// Thrown when returns an odd number. /// Returns Apply of . public override IOperation Apply() { int count = NumberOfSelectedSubScopesParameter.ActualValue.Value; if (count % 2 > 0) throw new InvalidOperationException(Name + ": There must be an equal number of sub-scopes to be selected."); FemaleSelector.NumberOfSelectedSubScopesParameter.Value = new IntValue(count / 2); MaleSelector.NumberOfSelectedSubScopesParameter.Value = new IntValue(count / 2); return base.Apply(); } #region Events private void SelectorParameter_ValueChanged(object sender, EventArgs e) { IValueParameter selectorParam = (sender as IValueParameter); if (selectorParam != null) ParameterizeSelector(selectorParam.Value); } #endregion #region Helpers private void Initialize() { FemaleSelectorParameter.ValueChanged += new EventHandler(SelectorParameter_ValueChanged); MaleSelectorParameter.ValueChanged += new EventHandler(SelectorParameter_ValueChanged); if (FemaleSelector == null) FemaleSelector = new ProportionalSelector(); if (MaleSelector == null) MaleSelector = new RandomSelector(); } private void ParameterizeSelector(ISelector selector) { selector.CopySelected = new BoolValue(true); IStochasticOperator stoOp = (selector as IStochasticOperator); if (stoOp != null) stoOp.RandomParameter.ActualName = RandomParameter.Name; ISingleObjectiveSelector soSelector = (selector as ISingleObjectiveSelector); if (soSelector != null) { soSelector.MaximizationParameter.ActualName = MaximizationParameter.Name; soSelector.QualityParameter.ActualName = QualityParameter.Name; } } #endregion } }