#region License Information /* HeuristicLab * Copyright (C) 2002-2011 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 System.Text; using HeuristicLab.Operators; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Parameters; using HeuristicLab.Data; using HeuristicLab.Optimization.Operators; using HeuristicLab.Selection; using HeuristicLab.Optimization; namespace HeuristicLab.Algorithms.VariableNeighborhoodSearch { /// /// An operator which represents a variable neighborhood search. /// [Item("VariableNeighborhoodSearchMainLoop", "An operator which represents the main loop of a variable neighborhood search.")] [StorableClass] public sealed class VariableNeighborhoodSearchMainLoop : AlgorithmOperator { #region Parameter properties public ValueLookupParameter RandomParameter { get { return (ValueLookupParameter)Parameters["Random"]; } } public ValueLookupParameter MaximizationParameter { get { return (ValueLookupParameter)Parameters["Maximization"]; } } public LookupParameter QualityParameter { get { return (LookupParameter)Parameters["Quality"]; } } public ValueLookupParameter BestKnownQualityParameter { get { return (ValueLookupParameter)Parameters["BestKnownQuality"]; } } public ValueLookupParameter EvaluatorParameter { get { return (ValueLookupParameter)Parameters["Evaluator"]; } } public ValueLookupParameter MaximumIterationsParameter { get { return (ValueLookupParameter)Parameters["MaximumIterations"]; } } public ValueLookupParameter ResultsParameter { get { return (ValueLookupParameter)Parameters["Results"]; } } public ValueLookupParameter AnalyzerParameter { get { return (ValueLookupParameter)Parameters["Analyzer"]; } } public LookupParameter EvaluatedSolutionsParameter { get { return (LookupParameter)Parameters["EvaluatedSolutions"]; } } public ValueLookupParameter LocalImprovementParameter { get { return (ValueLookupParameter)Parameters["LocalImprovement"]; } } public ValueLookupParameter ShakingParameter { get { return (ValueLookupParameter)Parameters["Shaking"]; } } #endregion [StorableConstructor] private VariableNeighborhoodSearchMainLoop(bool deserializing) : base(deserializing) { } public VariableNeighborhoodSearchMainLoop() : base() { Initialize(); } private VariableNeighborhoodSearchMainLoop(VariableNeighborhoodSearchMainLoop original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new VariableNeighborhoodSearchMainLoop(this, cloner); } private void Initialize() { #region Create parameters Parameters.Add(new ValueLookupParameter("Random", "A pseudo random number generator.")); Parameters.Add(new ValueLookupParameter("Maximization", "True if the problem is a maximization problem, otherwise false.")); Parameters.Add(new LookupParameter("Quality", "The value which represents the quality of a solution.")); Parameters.Add(new ValueLookupParameter("BestKnownQuality", "The best known quality value found so far.")); Parameters.Add(new ValueLookupParameter("Evaluator", "The operator used to evaluate solutions. This operator is executed in parallel, if an engine is used which supports parallelization.")); Parameters.Add(new ValueLookupParameter("MaximumIterations", "The maximum number of generations which should be processed.")); Parameters.Add(new ValueLookupParameter("Results", "The variable collection where results should be stored.")); Parameters.Add(new ValueLookupParameter("Analyzer", "The operator used to analyze the solution.")); Parameters.Add(new LookupParameter("EvaluatedSolutions", "The number of evaluated solutions.")); Parameters.Add(new ValueLookupParameter("LocalImprovement", "The local improvement operation.")); Parameters.Add(new ValueLookupParameter("Shaking", "The shaking operation.")); #endregion #region Create operators VariableCreator variableCreator = new VariableCreator(); SubScopesProcessor subScopesProcessor0 = new SubScopesProcessor(); Assigner bestQualityInitializer = new Assigner(); Placeholder analyzer1 = new Placeholder(); ResultsCollector resultsCollector1 = new ResultsCollector(); CombinedOperator iteration = new CombinedOperator(); Assigner iterationInit = new Assigner(); ChildrenCreator createChild = new ChildrenCreator(); SubScopesProcessor childProcessor = new SubScopesProcessor(); ParentCopyCrossover parentCloner = new ParentCopyCrossover(); Assigner qualityAssigner = new Assigner(); Placeholder shaking = new Placeholder(); Placeholder localImprovement = new Placeholder(); Placeholder evaluator = new Placeholder(); IntCounter evalCounter = new IntCounter(); QualityComparator qualityComparator = new QualityComparator(); ConditionalBranch improvesQualityBranch = new ConditionalBranch(); ConditionalBranch improvesQualityBranch2 = new ConditionalBranch(); Assigner bestQualityUpdater = new Assigner(); ScopeCleaner cleaner = new ScopeCleaner(); ParentCopyCrossover originalRestorer = new ParentCopyCrossover(); IntCounter indexCounter = new IntCounter(); Assigner indexResetter = new Assigner(); SubScopesRemover remover1 = new SubScopesRemover(); SubScopesRemover remover2 = new SubScopesRemover(); Placeholder analyzer2 = new Placeholder(); ConditionalBranch indexTermination = new ConditionalBranch(); IntCounter iterationsCounter = new IntCounter(); Comparator iterationsComparator = new Comparator(); ConditionalBranch iterationsTermination = new ConditionalBranch(); variableCreator.CollectedValues.Add(new ValueParameter("OuterIterations", new IntValue(0))); variableCreator.CollectedValues.Add(new ValueParameter("Index", new DoubleValue(0))); variableCreator.CollectedValues.Add(new ValueParameter("Continue", new BoolValue(false))); variableCreator.CollectedValues.Add(new ValueParameter("IsBetter", new BoolValue(false))); variableCreator.CollectedValues.Add(new ValueParameter("BestQuality", new DoubleValue(0))); bestQualityInitializer.Name = "Initialize BestQuality"; bestQualityInitializer.LeftSideParameter.ActualName = "BestQuality"; bestQualityInitializer.RightSideParameter.ActualName = QualityParameter.Name; analyzer1.Name = "Analyzer (placeholder)"; analyzer1.OperatorParameter.ActualName = AnalyzerParameter.Name; resultsCollector1.CopyValue = new BoolValue(false); resultsCollector1.CollectedValues.Add(new LookupParameter("OuterIterations")); resultsCollector1.CollectedValues.Add(new LookupParameter("Best Quality", null, "BestQuality")); resultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name; iteration.Name = "Iteration"; iterationInit.Name = "Init iteration"; iterationInit.LeftSideParameter.ActualName = "Index"; iterationInit.RightSideParameter.Value = new IntValue(0); createChild.Name = "Create child"; createChild.ParentsPerChild.Value = 1; parentCloner.Name = "Copy parent"; qualityAssigner.Name = "Assign quality"; qualityAssigner.LeftSideParameter.ActualName = "OriginalQuality"; qualityAssigner.RightSideParameter.ActualName = QualityParameter.Name; shaking.Name = "Shaking operator (placeholder)"; shaking.OperatorParameter.ActualName = ShakingParameter.Name; localImprovement.Name = "Local improvement operator (placeholder)"; localImprovement.OperatorParameter.ActualName = LocalImprovementParameter.Name; evaluator.Name = "Evaluation operator (placeholder)"; evaluator.OperatorParameter.ActualName = EvaluatorParameter.Name; evalCounter.Name = "Count evaluateions"; evalCounter.Increment.Value = 1; evalCounter.ValueParameter.ActualName = EvaluatedSolutionsParameter.ActualName; qualityComparator.LeftSideParameter.ActualName = QualityParameter.Name; qualityComparator.RightSideParameter.ActualName = "OriginalQuality"; qualityComparator.ResultParameter.ActualName = "IsBetter"; improvesQualityBranch.ConditionParameter.ActualName = "IsBetter"; improvesQualityBranch2.ConditionParameter.ActualName = "IsBetter"; bestQualityUpdater.Name = "Update BestQuality"; bestQualityUpdater.LeftSideParameter.ActualName = "BestQuality"; bestQualityUpdater.RightSideParameter.ActualName = QualityParameter.Name; cleaner.Name = "Clean scope"; cleaner.ClearSubScopesParameter.Value = new BoolValue(false); originalRestorer.Name = "Restore original solution"; indexCounter.Name = "Count index"; indexCounter.Increment.Value = 1; indexCounter.ValueParameter.ActualName = "Index"; indexResetter.Name = "Reset index"; indexResetter.LeftSideParameter.ActualName = "Index"; indexResetter.RightSideParameter.Value = new IntValue(0); remover1.Name = remover2.Name = "Remove subscope"; analyzer2.Name = "Analyzer (placeholder)"; analyzer2.OperatorParameter.ActualName = AnalyzerParameter.Name; originalRestorer.Name = "Restore parent"; iterationsCounter.Name = "Iterations Counter"; iterationsCounter.Increment = new IntValue(1); iterationsCounter.ValueParameter.ActualName = "OuterIterations"; iterationsComparator.Name = "Iterations >= MaximumIterations"; iterationsComparator.Comparison = new Comparison(ComparisonType.GreaterOrEqual); iterationsComparator.LeftSideParameter.ActualName = "OuterIterations"; iterationsComparator.RightSideParameter.ActualName = MaximumIterationsParameter.Name; iterationsComparator.ResultParameter.ActualName = "Terminate"; iterationsTermination.Name = "Iterations Termination Condition"; iterationsTermination.ConditionParameter.ActualName = "Terminate"; indexTermination.Name = "Index Termination Condition"; indexTermination.ConditionParameter.ActualName = "Continue"; #endregion #region Create operator graph OperatorGraph.InitialOperator = variableCreator; variableCreator.Successor = analyzer1; analyzer1.Successor = subScopesProcessor0; subScopesProcessor0.Operators.Add(bestQualityInitializer); subScopesProcessor0.Successor = resultsCollector1; ///////// resultsCollector1.Successor = iteration; iteration.OperatorGraph.InitialOperator = iterationInit; iteration.Successor = iterationsCounter; iterationInit.Successor = createChild; createChild.Successor = childProcessor; childProcessor.Operators.Add(parentCloner); childProcessor.Successor = analyzer2; ///////// parentCloner.Successor = qualityAssigner; qualityAssigner.Successor = shaking; shaking.Successor = evaluator; evaluator.Successor = evalCounter; evalCounter.Successor = localImprovement; localImprovement.Successor = qualityComparator; qualityComparator.Successor = improvesQualityBranch; improvesQualityBranch.TrueBranch = bestQualityUpdater; improvesQualityBranch.FalseBranch = cleaner; bestQualityUpdater.Successor = indexResetter; indexResetter.Successor = remover1; cleaner.Successor = originalRestorer; originalRestorer.Successor = remover2; remover2.Successor = indexCounter; ///////// analyzer2.Successor = indexTermination; indexTermination.TrueBranch = improvesQualityBranch2; indexTermination.FalseBranch = null; improvesQualityBranch2.TrueBranch = null; improvesQualityBranch2.FalseBranch = createChild; iterationsCounter.Successor = iterationsComparator; iterationsComparator.Successor = iterationsTermination; iterationsTermination.TrueBranch = null; iterationsTermination.FalseBranch = iteration; #endregion } public override IOperation Apply() { if (LocalImprovementParameter.ActualValue == null || EvaluatorParameter.ActualValue == null) return null; return base.Apply(); } } }