#region License Information /* HeuristicLab * Copyright (C) 2002-2010 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.Linq; using HeuristicLab.Analysis; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.RealVectorEncoding; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Optimization.Operators; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.PluginInfrastructure; using HeuristicLab.Random; namespace HeuristicLab.Algorithms.ParticleSwarmOptimization { [Item("Particle Swarm Optimization", "A particle swarm optimization algorithm based on the description in Pedersen, M.E.H. (2010). PhD thesis. University of Southampton.")] [Creatable("Algorithms")] [StorableClass] public class ParticleSwarmOptimization : EngineAlgorithm { #region Problem Properties public override Type ProblemType { get { return typeof(ISingleObjectiveProblem); } } public new ISingleObjectiveProblem Problem { get { return (ISingleObjectiveProblem)base.Problem; } set { base.Problem = value; } } public MultiAnalyzer Analyzer { get { return AnalyzerParameter.Value; } set { AnalyzerParameter.Value = value; } } public ValueModifierSelector OmegaUpdater { get { return OmegaUpdaterParameter.Value; } set { OmegaUpdaterParameter.Value = value; } } public WeightedValueModifierSelector VelocityBoundsUpdater { get { return VelocityBoundsUpdaterParameter.Value; } set { VelocityBoundsUpdaterParameter.Value = value; } } #endregion #region Parameter Properties public ValueParameter SeedParameter { get { return (ValueParameter)Parameters["Seed"]; } } public ValueParameter SetSeedRandomlyParameter { get { return (ValueParameter)Parameters["SetSeedRandomly"]; } } public ValueParameter SwarmSizeParameter { get { return (ValueParameter)Parameters["SwarmSize"]; } } public ValueParameter MaxIterationsParameter { get { return (ValueParameter)Parameters["MaxIterations"]; } } public ValueParameter OmegaParameter { get { return (ValueParameter)Parameters["Omega"]; } } public ValueParameter Phi_PParameter { get { return (ValueParameter)Parameters["Phi_P"]; } } public ValueParameter Phi_GParameter { get { return (ValueParameter)Parameters["Phi_G"]; } } public ValueParameter AnalyzerParameter { get { return (ValueParameter)Parameters["Analyzer"]; } } public ValueLookupParameter VelocityBoundsParameter { get { return (ValueLookupParameter)Parameters["VelocityBounds"]; } } public ConstrainedValueParameter ParticleUpdaterParameter { get { return (ConstrainedValueParameter)Parameters["ParticleUpdater"]; } } public ConstrainedValueParameter TopologyInitializerParameter { get { return (ConstrainedValueParameter)Parameters["TopologyInitializer"]; } } public ConstrainedValueParameter TopologyUpdaterParameter { get { return (ConstrainedValueParameter)Parameters["TopologyUpdater"]; } } public ValueParameter VelocityBoundsUpdaterParameter { get { return (ValueParameter)Parameters["VelocityBoundsUpdater"]; } } public ValueParameter OmegaUpdaterParameter { get { return (ValueParameter)Parameters["OmegaUpdater"]; } } #endregion #region Properties [Storable] private BestAverageWorstQualityAnalyzer qualityAnalyzer; //[Storable] //private IDiscreteDoubleValueModifier omegaModifier; #endregion [StorableConstructor] protected ParticleSwarmOptimization(bool deserializing) : base(deserializing) { } protected ParticleSwarmOptimization(ParticleSwarmOptimization original, Cloner cloner) : base(original, cloner) { qualityAnalyzer = cloner.Clone(original.qualityAnalyzer); //omegaModifier = cloner.Clone(original.omegaModifier); } public ParticleSwarmOptimization() : base() { Parameters.Add(new ValueParameter("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0))); Parameters.Add(new ValueParameter("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true))); Parameters.Add(new ValueParameter("SwarmSize", "Size of the particle swarm.", new IntValue(10))); Parameters.Add(new ValueParameter("MaxIterations", "Maximal number of iterations.", new IntValue(1000))); Parameters.Add(new ValueParameter("Analyzer", "The operator used to analyze each generation.", new MultiAnalyzer())); Parameters.Add(new ValueParameter("Omega", "Weight for particle's velocity vector.", new DoubleValue(-0.2))); Parameters.Add(new ValueParameter("Phi_P", "Weight for particle's personal best position.", new DoubleValue(-0.01))); Parameters.Add(new ValueParameter("Phi_G", "Weight for global best position.", new DoubleValue(3.7))); Parameters.Add(new ValueLookupParameter("VelocityBounds", "Maximum Velocity in every dimension", new DoubleMatrix(new double[,] { { -1, 1 } }))); Parameters.Add(new ConstrainedValueParameter("ParticleUpdater", "Operator that calculates new position and velocity of a particle", new ItemSet(ApplicationManager.Manager.GetInstances()))); Parameters.Add(new ConstrainedValueParameter("TopologyInitializer", "Creates neighborhood description vectors", new ItemSet(ApplicationManager.Manager.GetInstances()))); Parameters.Add(new ConstrainedValueParameter("TopologyUpdater", "Updates the neighborhood description vectors", new ItemSet(ApplicationManager.Manager.GetInstances()))); //Parameters.Add(new ValueParameter("ParameterUpdater", "Updates the algorithm parameters according to some strategy", // new MultiParameterUpdater())); Parameters.Add(new ValueParameter("OmegaUpdater", "Updates the omega parameter", new ValueModifierSelector())); Parameters.Add(new ValueParameter("VelocityBoundsUpdater", "Adjusts the velocity bounds", new WeightedValueModifierSelector())); ParticleUpdaterParameter.ActualValue = ParticleUpdaterParameter.ValidValues.SingleOrDefault(v => v.GetType() == typeof(TotallyConnectedParticleUpdater)); TopologyInitializerParameter.ActualValue = TopologyInitializerParameter.ValidValues.SingleOrDefault(v => v.GetType() == typeof(EmptyTopologyInitializer)); RandomCreator randomCreator = new RandomCreator(); VariableCreator variableCreator = new VariableCreator(); SolutionsCreator solutionsCreator = new SolutionsCreator(); CombinedOperator particleCreator = new CombinedOperator(); Placeholder evaluatorPlaceholder = new Placeholder(); Assigner bestPersonalQualityAssigner = new Assigner(); BestPointInitializer bestPositionInitializer = new BestPointInitializer(); Placeholder topologyInitializerPlaceholder = new Placeholder(); NeighborUpdater neighborUpdater = new NeighborUpdater(); Placeholder analyzerPlaceholder = new Placeholder(); UniformSubScopesProcessor uniformSubScopeProcessor = new UniformSubScopesProcessor(); Placeholder particleUpdaterPlaceholder = new Placeholder(); Placeholder topologyUpdaterPlaceholder = new Placeholder(); UniformSubScopesProcessor uniformSubscopesProcessor2 = new UniformSubScopesProcessor(); NeighborUpdater neighborUpdater2 = new NeighborUpdater(); Placeholder evaluatorPlaceholder2 = new Placeholder(); SwarmUpdater swarmUpdater = new SwarmUpdater(); Placeholder analyzerPlaceholder2 = new Placeholder(); IntCounter currentIterationCounter = new IntCounter(); Comparator currentIterationComparator = new Comparator(); ConditionalBranch conditionalBranch = new ConditionalBranch(); Placeholder velocityBoundsUpdaterPlaceholder = new Placeholder(); Placeholder omegaUpdaterPlaceholder = new Placeholder(); OperatorGraph.InitialOperator = randomCreator; randomCreator.SetSeedRandomlyParameter.Value = null; randomCreator.SeedParameter.Value = null; randomCreator.Successor = variableCreator; variableCreator.CollectedValues.Add(new ValueParameter("CurrentIteration", new IntValue(0))); variableCreator.Successor = solutionsCreator; solutionsCreator.NumberOfSolutionsParameter.ActualName = "SwarmSize"; solutionsCreator.EvaluatorParameter.Value = evaluatorPlaceholder; solutionsCreator.SolutionCreatorParameter.Value = particleCreator; solutionsCreator.Successor = bestPositionInitializer; InitializeParticleCreator(particleCreator); evaluatorPlaceholder.Name = "(Evaluator)"; evaluatorPlaceholder.OperatorParameter.ActualName = "Evaluator"; evaluatorPlaceholder.Successor = bestPersonalQualityAssigner; bestPersonalQualityAssigner.LeftSideParameter.ActualName = "PersonalBestQuality"; bestPersonalQualityAssigner.RightSideParameter.ActualName = "Quality"; bestPositionInitializer.Successor = topologyInitializerPlaceholder; topologyInitializerPlaceholder.Name = "(TopologyInitializer)"; topologyInitializerPlaceholder.OperatorParameter.ActualName = "TopologyInitializer"; topologyInitializerPlaceholder.Successor = neighborUpdater; neighborUpdater.Successor = analyzerPlaceholder; analyzerPlaceholder.Name = "(Analyzer)"; analyzerPlaceholder.OperatorParameter.ActualName = "Analyzer"; analyzerPlaceholder.Successor = uniformSubScopeProcessor; uniformSubScopeProcessor.Operator = particleUpdaterPlaceholder; uniformSubScopeProcessor.Successor = topologyUpdaterPlaceholder; particleUpdaterPlaceholder.Name = "(ParticleUpdater)"; particleUpdaterPlaceholder.OperatorParameter.ActualName = "ParticleUpdater"; particleUpdaterPlaceholder.Successor = evaluatorPlaceholder2; evaluatorPlaceholder2.Name = "(Evaluator)"; evaluatorPlaceholder2.OperatorParameter.ActualName = "Evaluator"; topologyUpdaterPlaceholder.Name = "(TopologyUpdater)"; topologyUpdaterPlaceholder.OperatorParameter.ActualName = "TopologyUpdater"; topologyUpdaterPlaceholder.Successor = neighborUpdater2; neighborUpdater2.Successor = uniformSubscopesProcessor2; uniformSubscopesProcessor2.Operator = swarmUpdater; uniformSubscopesProcessor2.Successor = analyzerPlaceholder2; analyzerPlaceholder2.Name = "(Analyzer)"; analyzerPlaceholder2.OperatorParameter.ActualName = "Analyzer"; analyzerPlaceholder2.Successor = currentIterationCounter; currentIterationCounter.Name = "CurrentIteration++"; currentIterationCounter.ValueParameter.ActualName = "CurrentIteration"; currentIterationCounter.Successor = omegaUpdaterPlaceholder; omegaUpdaterPlaceholder.Name = "(Omega Updater)"; omegaUpdaterPlaceholder.OperatorParameter.ActualName = "OmegaUpdater"; omegaUpdaterPlaceholder.Successor = velocityBoundsUpdaterPlaceholder; velocityBoundsUpdaterPlaceholder.Name = "(Velocity Bounds Updater)"; velocityBoundsUpdaterPlaceholder.OperatorParameter.ActualName = "VelocityBoundsUpdater"; velocityBoundsUpdaterPlaceholder.Successor = currentIterationComparator; currentIterationComparator.LeftSideParameter.ActualName = "CurrentIteration"; currentIterationComparator.Comparison = new Comparison(ComparisonType.Less); currentIterationComparator.RightSideParameter.ActualName = "MaxIterations"; currentIterationComparator.ResultParameter.ActualName = "ContinueIteration"; currentIterationComparator.Successor = conditionalBranch; conditionalBranch.Name = "ContinueIteration?"; conditionalBranch.ConditionParameter.ActualName = "ContinueIteration"; conditionalBranch.TrueBranch = uniformSubScopeProcessor; InitializeAnalyzers(); InitializeUpdaters(); UpdateAnalyzers(); } private static void InitializeParticleCreator(CombinedOperator particleCreator) { Placeholder positionCreator = new Placeholder(); Assigner personalBestPositionAssigner = new Assigner(); UniformRandomRealVectorCreator velocityCreator = new UniformRandomRealVectorCreator(); particleCreator.Name = "Particle Creator"; particleCreator.OperatorGraph.InitialOperator = positionCreator; positionCreator.Name = "(SolutionCreator)"; positionCreator.OperatorParameter.ActualName = "SolutionCreator"; positionCreator.Successor = personalBestPositionAssigner; personalBestPositionAssigner.LeftSideParameter.ActualName = "PersonalBestPoint"; personalBestPositionAssigner.RightSideParameter.ActualName = "Point"; personalBestPositionAssigner.Successor = velocityCreator; velocityCreator.LengthParameter.ActualName = "ProblemSize"; velocityCreator.BoundsParameter.ActualName = "VelocityBounds"; velocityCreator.RealVectorParameter.ActualName = "Velocity"; } public override IDeepCloneable Clone(Cloner cloner) { return new ParticleSwarmOptimization(this, cloner); } public override void Prepare() { if (Problem != null) base.Prepare(); } #region Events protected override void OnProblemChanged() { UpdateAnalyzers(); ParameterizeAnalyzers(); Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged); base.OnProblemChanged(); } #endregion #region Helpers private void InitializeParticleUpdaters() { } private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) { } private void InitializeAnalyzers() { qualityAnalyzer = new BestAverageWorstQualityAnalyzer(); ParameterizeAnalyzers(); } private void InitializeUpdaters() { OmegaUpdater.ValueParameter.ActualName = OmegaParameter.Name; foreach (IDiscreteDoubleValueModifier op in ApplicationManager.Manager.GetInstances()) { OmegaUpdater.ModifierParameter.ValidValues.Add(op); op.EndIndexParameter.ActualName = MaxIterationsParameter.Name; op.StartIndexParameter.Value = new IntValue(0); op.IndexParameter.ActualName = "CurrentIteration"; op.ValueParameter.ActualName = OmegaUpdater.ValueParameter.ActualName; op.StartValueParameter.Value = new DoubleValue(OmegaParameter.Value.Value); op.EndValueParameter.Value = new DoubleValue(-2); } VelocityBoundsUpdater.ValueParameter.ActualName = VelocityBoundsParameter.Name; foreach (IDiscreteDoubleValueModifier op in ApplicationManager.Manager.GetInstances()) { VelocityBoundsUpdater.ModifierParameter.ValidValues.Add(op); op.EndIndexParameter.ActualName = MaxIterationsParameter.Name; op.StartIndexParameter.Value = new IntValue(0); op.IndexParameter.ActualName = "CurrentIteration"; op.ValueParameter.ActualName = VelocityBoundsUpdater.ScaleParameter.Name; op.StartValueParameter.Value = new DoubleValue(VelocityBoundsUpdater.ScaleParameter.Value.Value); op.EndValueParameter.Value = new DoubleValue(0); } } private void ParameterizeAnalyzers() { if (Problem != null) { qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name; qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName; qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name; } } private void UpdateAnalyzers() { Analyzer.Operators.Clear(); if (Problem != null) { foreach (IAnalyzer analyzer in Problem.Operators.OfType()) Analyzer.Operators.Add(analyzer); } Analyzer.Operators.Add(qualityAnalyzer); } #endregion } }