Free cookie consent management tool by TermsFeed Policy Generator

Changeset 5560 for trunk


Ignore:
Timestamp:
02/24/11 17:08:11 (12 years ago)
Author:
mkofler
Message:

#852: Code refactoring. Created new interfaces and moved operators to respective projects as suggested in A. Beham's review. Work in progress.

Location:
trunk/sources
Files:
18 added
10 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/HeuristicLab.Algorithms.ParticleSwarmOptimization-3.3.csproj

    r5426 r5560  
    107107  <ItemGroup>
    108108    <Compile Include="BestPointInitializer.cs" />
    109     <Compile Include="IDiscreteDoubleMatrixModifier.cs" />
    110     <Compile Include="IGlobalParticleUpdater.cs" />
    111     <Compile Include="ILocalParticleUpdater.cs" />
    112109    <Compile Include="MultiPSOTopologyUpdater.cs" />
     110    <Compile Include="ParticleSwarmOptimizationMainLoop.cs" />
    113111    <Compile Include="VelocityBoundsModifier.cs" />
    114112    <Compile Include="RandomTopologyInitializer.cs" />
    115113    <Compile Include="VonNeumannTopologyInitializer.cs" />
    116114    <Compile Include="RingTopologyInitializer.cs" />
    117     <Compile Include="ITopologyUpdater.cs" />
    118115    <Compile Include="NeighborUpdater.cs" />
    119116    <Compile Include="TopologyInitializer.cs" />
    120     <Compile Include="ITopologyInitializer.cs" />
    121     <Compile Include="NeighborhoodParticleUpdater.cs" />
    122     <Compile Include="IParticleUpdater.cs" />
    123     <Compile Include="TotallyConnectedParticleUpdater.cs" />
    124117    <Compile Include="HeuristicLabAlgorithmsParticleSwarmOptimizationPlugin.cs" />
    125118    <Compile Include="ParticleSwarmOptimization.cs" />
    126119    <Compile Include="Properties\AssemblyInfo.cs" />
    127     <Compile Include="ParticleUpdater.cs" />
    128     <Compile Include="SwarmUpdater.cs" />
    129120  </ItemGroup>
    130121  <ItemGroup>
  • trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/HeuristicLabAlgorithmsParticleSwarmOptimizationPlugin.cs.frame

    r5446 r5560  
    3434  [PluginDependency("HeuristicLab.Data", "3.3")]
    3535  [PluginDependency("HeuristicLab.Encodings.RealVectorEncoding", "3.3")]
    36   [PluginDependency("HeuristicLab.Encodings.IntegerVectorEncoding", "3.3")]
    3736  [PluginDependency("HeuristicLab.Operators", "3.3")]
    3837  [PluginDependency("HeuristicLab.Optimization", "3.3")]
  • trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/MultiPSOTopologyUpdater.cs

    r5435 r5560  
    2525using HeuristicLab.Core;
    2626using HeuristicLab.Data;
    27 using HeuristicLab.Encodings.IntegerVectorEncoding;
    2827using HeuristicLab.Operators;
     28using HeuristicLab.Optimization;
    2929using HeuristicLab.Parameters;
    3030using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    3131
    3232namespace HeuristicLab.Algorithms.ParticleSwarmOptimization {
    33   [Item("Multi PSO Topology Initializer/Updater", "Splits swarm into swarmsize / (nrOfConnections + 1) non-overlapping sub-swarms. Swarms are re-grouped every regroupingPeriod iteration. The operator is implemented as described in Liang, J.J. and Suganthan, P.N 2005. Dynamic multi-swarm particle swarm optimizer. IEEE Swarm Intelligence Symposium, pp. 124-129.")]
     33  [Item("Multi PSO Topology Updater", "Splits swarm into swarmsize / (nrOfConnections + 1) non-overlapping sub-swarms. Swarms are re-grouped every regroupingPeriod iteration. The operator is implemented as described in Liang, J.J. and Suganthan, P.N 2005. Dynamic multi-swarm particle swarm optimizer. IEEE Swarm Intelligence Symposium, pp. 124-129.")]
    3434  [StorableClass]
    35   public sealed class MultiPSOTopologyUpdater : SingleSuccessorOperator, ITopologyUpdater, ITopologyInitializer {
     35  public sealed class MultiPSOTopologyUpdater : SingleSuccessorOperator, ITopologyUpdater {
    3636    public override bool CanChangeName {
    3737      get { return false; }
     
    4848      get { return (ILookupParameter<IntValue>)Parameters["SwarmSize"]; }
    4949    }
    50     public IScopeTreeLookupParameter<IntegerVector> NeighborsParameter {
    51       get { return (IScopeTreeLookupParameter<IntegerVector>)Parameters["Neighbors"]; }
     50    public IScopeTreeLookupParameter<IntArray> NeighborsParameter {
     51      get { return (IScopeTreeLookupParameter<IntArray>)Parameters["Neighbors"]; }
    5252    }
    5353    public ILookupParameter<IntValue> CurrentIterationParameter {
     
    6969      get { return SwarmSizeParameter.ActualValue.Value; }
    7070    }
    71     private ItemArray<IntegerVector> Neighbors {
     71    private ItemArray<IntArray> Neighbors {
    7272      get { return NeighborsParameter.ActualValue; }
    7373      set { NeighborsParameter.ActualValue = value; }
     
    8484    private MultiPSOTopologyUpdater(bool deserializing) : base(deserializing) { }
    8585    private MultiPSOTopologyUpdater(MultiPSOTopologyUpdater original, Cloner cloner) : base(original, cloner) { }
     86   
    8687    public MultiPSOTopologyUpdater()
    8788      : base() {
     
    8990      Parameters.Add(new ValueLookupParameter<IntValue>("NrOfConnections", "Nr of connected neighbors.", new IntValue(3)));
    9091      Parameters.Add(new LookupParameter<IntValue>("SwarmSize", "Number of particles in the swarm."));
    91       Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Neighbors", "The list of neighbors for each particle."));
     92      Parameters.Add(new ScopeTreeLookupParameter<IntArray>("Neighbors", "The list of neighbors for each particle."));
    9293      Parameters.Add(new LookupParameter<IntValue>("CurrentIteration", "The current iteration of the algorithm."));
    9394      Parameters.Add(new ValueLookupParameter<IntValue>("RegroupingPeriod", "Update interval (=iterations) for regrouping of neighborhoods.", new IntValue(5)));
     
    100101    // Splits the swarm into non-overlapping sub swarms
    101102    public override IOperation Apply() {
    102       if (CurrentIteration % RegroupingPeriod == 0) {
    103         ItemArray<IntegerVector> neighbors = new ItemArray<IntegerVector>(SwarmSize);
     103      if (CurrentIteration > 0 && CurrentIteration % RegroupingPeriod == 0) {
     104        ItemArray<IntArray> neighbors = new ItemArray<IntArray>(SwarmSize);
    104105        Dictionary<int, List<int>> neighborsPerParticle = new Dictionary<int, List<int>>();
    105106        for (int i = 0; i < SwarmSize; i++) {
     
    135136
    136137        for (int particle = 0; particle < neighborsPerParticle.Count; particle++) {
    137           neighbors[particle] = new IntegerVector(neighborsPerParticle[particle].ToArray());
     138          neighbors[particle] = new IntArray(neighborsPerParticle[particle].ToArray());
    138139        }
    139140        Neighbors = neighbors;
  • trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/NeighborUpdater.cs

    r5445 r5560  
    2424using HeuristicLab.Core;
    2525using HeuristicLab.Data;
    26 using HeuristicLab.Encodings.IntegerVectorEncoding;
    2726using HeuristicLab.Encodings.RealVectorEncoding;
    2827using HeuristicLab.Operators;
     
    4241      get { return (IScopeTreeLookupParameter<RealVector>)Parameters["Point"]; }
    4342    }
    44     public IScopeTreeLookupParameter<IntegerVector> NeighborsParameter {
    45       get { return (IScopeTreeLookupParameter<IntegerVector>)Parameters["Neighbors"]; }
     43    public IScopeTreeLookupParameter<IntArray> NeighborsParameter {
     44      get { return (IScopeTreeLookupParameter<IntArray>)Parameters["Neighbors"]; }
    4645    }
    4746    public IScopeTreeLookupParameter<RealVector> BestNeighborPointParameter {
     
    6059      get { return PointsParameter.ActualValue; }
    6160    }
    62     private ItemArray<IntegerVector> Neighbors {
     61    private ItemArray<IntArray> Neighbors {
    6362      get { return NeighborsParameter.ActualValue; }
    6463    }
     
    8079    private NeighborUpdater(NeighborUpdater original, Cloner cloner) : base(original, cloner) { }
    8180    public NeighborUpdater() {
    82       Parameters.Add(new ScopeTreeLookupParameter<RealVector>("Point", "The position of the particle."));
    83       Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Neighbors", "The list of neighbors for each particle."));
     81      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("RealVector", "The position of the particle."));
     82      Parameters.Add(new ScopeTreeLookupParameter<IntArray>("Neighbors", "The list of neighbors for each particle."));
    8483      Parameters.Add(new ScopeTreeLookupParameter<RealVector>("BestNeighborPoint", "The position of the best neighboring particle."));
    8584      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The list of qualities of all particles."));
  • trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/ParticleSwarmOptimization.cs

    r5445 r5560  
    5353      set { AnalyzerParameter.Value = value; }
    5454    }
    55     public IDiscreteDoubleValueModifier OmegaUpdater {
    56       get { return OmegaUpdaterParameter.Value; }
    57       set { OmegaUpdaterParameter.Value = value; }
    58     }
    59     public IDiscreteDoubleMatrixModifier VelocityBoundsUpdater {
    60       get { return VelocityBoundsUpdaterParameter.Value; }
    61       set { VelocityBoundsUpdaterParameter.Value = value; }
     55    public IDiscreteDoubleValueModifier InertiaUpdater {
     56      get { return InertiaUpdaterParameter.Value; }
     57      set { InertiaUpdaterParameter.Value = value; }
    6258    }
    6359    #endregion
     
    7672      get { return (IValueParameter<IntValue>)Parameters["MaxIterations"]; }
    7773    }
    78     public IValueParameter<DoubleValue> OmegaParameter {
    79       get { return (IValueParameter<DoubleValue>)Parameters["Omega"]; }
    80     }
    81     public IValueParameter<DoubleValue> Phi_PParameter {
    82       get { return (IValueParameter<DoubleValue>)Parameters["Phi_P"]; }
    83     }
    84     public IValueParameter<DoubleValue> Phi_GParameter {
    85       get { return (IValueParameter<DoubleValue>)Parameters["Phi_G"]; }
     74    public IValueParameter<DoubleValue> InertiaParameter {
     75      get { return (IValueParameter<DoubleValue>)Parameters["Inertia"]; }
     76    }
     77    public IValueParameter<DoubleValue> PersonalBestAttractionParameter {
     78      get { return (IValueParameter<DoubleValue>)Parameters["PersonalBestAttraction"]; }
     79    }
     80    public IValueParameter<DoubleValue> NeighborsBestAttractionParameter {
     81      get { return (IValueParameter<DoubleValue>)Parameters["NeighborsBestAttraction"]; }
    8682    }
    8783    public IValueParameter<MultiAnalyzer> AnalyzerParameter {
    8884      get { return (IValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
    8985    }
    90     public IValueLookupParameter<DoubleMatrix> VelocityBoundsParameter {
    91       get { return (IValueLookupParameter<DoubleMatrix>)Parameters["VelocityBounds"]; }
     86    public ConstrainedValueParameter<IParticleCreator> ParticleCreatorParameter {
     87      get { return (ConstrainedValueParameter<IParticleCreator>)Parameters["ParticleCreator"]; }
    9288    }
    9389    public ConstrainedValueParameter<IParticleUpdater> ParticleUpdaterParameter {
     
    10096      get { return (OptionalConstrainedValueParameter<ITopologyUpdater>)Parameters["TopologyUpdater"]; }
    10197    }
    102     public OptionalConstrainedValueParameter<IDiscreteDoubleMatrixModifier> VelocityBoundsUpdaterParameter {
    103       get { return (OptionalConstrainedValueParameter<IDiscreteDoubleMatrixModifier>)Parameters["VelocityBoundsUpdater"]; }
    104     }
    105     public OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier> OmegaUpdaterParameter {
    106       get { return (OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["OmegaUpdater"]; }
     98    public OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier> InertiaUpdaterParameter {
     99      get { return (OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["InertiaUpdater"]; }
    107100    }
    108101    #endregion
     
    114107    [Storable]
    115108    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
     109
     110    [Storable]
     111    private SolutionsCreator solutionsCreator;
     112
     113    [Storable]
     114    private ParticleSwarmOptimizationMainLoop mainLoop;
    116115
    117116    public ITopologyInitializer TopologyInitializer {
     
    125124    }
    126125
     126    public IParticleCreator ParticleCreator {
     127      get { return ParticleCreatorParameter.Value; }
     128      set { ParticleCreatorParameter.Value = value; }
     129    }
     130
    127131    public IParticleUpdater ParticleUpdater {
    128132      get { return ParticleUpdaterParameter.Value; }
    129133      set { ParticleUpdaterParameter.Value = value; }
    130134    }
    131 
    132135    #endregion
    133136
     
    137140      : base(original, cloner) {
    138141      qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
     142      solutionsCreator = cloner.Clone(original.solutionsCreator);
     143      mainLoop = cloner.Clone(original.mainLoop);
    139144      Initialize();
    140145    }
     
    146151      Parameters.Add(new ValueParameter<IntValue>("MaxIterations", "Maximal number of iterations.", new IntValue(1000)));
    147152      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze each generation.", new MultiAnalyzer()));
    148       Parameters.Add(new ValueParameter<DoubleValue>("Omega", "Weight for particle's velocity vector.", new DoubleValue(-0.2)));
    149       Parameters.Add(new ValueParameter<DoubleValue>("Phi_P", "Weight for particle's personal best position.", new DoubleValue(-0.01)));
    150       Parameters.Add(new ValueParameter<DoubleValue>("Phi_G", "Weight for global best position.", new DoubleValue(3.7)));
    151       Parameters.Add(new ValueLookupParameter<DoubleMatrix>("VelocityBounds", "Maximum Velocity in every dimension", new DoubleMatrix(new double[,] { { -1, 1 } })));
    152       Parameters.Add(new ConstrainedValueParameter<IParticleUpdater>("ParticleUpdater", "Operator that calculates new position and velocity of a particle"));
    153       Parameters.Add(new OptionalConstrainedValueParameter<ITopologyInitializer>("TopologyInitializer", "Creates neighborhood description vectors"));
    154       Parameters.Add(new OptionalConstrainedValueParameter<ITopologyUpdater>("TopologyUpdater", "Updates the neighborhood description vectors"));
    155       Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>("OmegaUpdater", "Updates the omega parameter"));
    156       Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleMatrixModifier>("VelocityBoundsUpdater", "Adjusts the velocity bounds."));
    157       ParticleUpdaterParameter.ActualValue = ParticleUpdaterParameter.ValidValues.SingleOrDefault(v => v.GetType() == typeof(TotallyConnectedParticleUpdater));
     153      Parameters.Add(new ValueParameter<DoubleValue>("Inertia", "Inertia weight on a particle's movement (omega).", new DoubleValue(-0.2)));
     154      Parameters.Add(new ValueParameter<DoubleValue>("PersonalBestAttraction", "Weight for particle's pull towards its personal best soution (phi_p).", new DoubleValue(-0.01)));
     155      Parameters.Add(new ValueParameter<DoubleValue>("NeighborsBestAttraction", "Weight for pull towards the neighborhood best solution or global best solution in case of a totally connected topology (phi_g).", new DoubleValue(3.7)));
     156      Parameters.Add(new ConstrainedValueParameter<IParticleCreator>("ParticleCreator", "Operator creates a new particle."));
     157      Parameters.Add(new ConstrainedValueParameter<IParticleUpdater>("ParticleUpdater", "Operator that updates a particle."));
     158      Parameters.Add(new OptionalConstrainedValueParameter<ITopologyInitializer>("TopologyInitializer", "Creates neighborhood description vectors."));
     159      Parameters.Add(new OptionalConstrainedValueParameter<ITopologyUpdater>("TopologyUpdater", "Updates the neighborhood description vectors."));
     160      Parameters.Add(new OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>("InertiaUpdater", "Updates the omega parameter."));
    158161
    159162      RandomCreator randomCreator = new RandomCreator();
    160163      VariableCreator variableCreator = new VariableCreator();
    161       SolutionsCreator solutionsCreator = new SolutionsCreator();
    162       CombinedOperator particleCreator = new CombinedOperator();
    163       Placeholder evaluatorPlaceholder = new Placeholder();
    164       Assigner bestPersonalQualityAssigner = new Assigner();
    165       BestPointInitializer bestPositionInitializer = new BestPointInitializer();
     164      solutionsCreator = new SolutionsCreator();
    166165      Placeholder topologyInitializerPlaceholder = new Placeholder();
    167       NeighborUpdater neighborUpdater = new NeighborUpdater();
     166      ResultsCollector resultsCollector = new ResultsCollector();
    168167      Placeholder analyzerPlaceholder = new Placeholder();
    169       UniformSubScopesProcessor uniformSubScopeProcessor = new UniformSubScopesProcessor();
    170       Placeholder particleUpdaterPlaceholder = new Placeholder();
    171       Placeholder topologyUpdaterPlaceholder = new Placeholder();
    172       UniformSubScopesProcessor uniformSubscopesProcessor2 = new UniformSubScopesProcessor();
    173       UniformSubScopesProcessor evaluationProcessor = new UniformSubScopesProcessor();
    174       NeighborUpdater neighborUpdater2 = new NeighborUpdater();
    175       Placeholder evaluatorPlaceholder2 = new Placeholder();
    176       SwarmUpdater swarmUpdater = new SwarmUpdater();
    177       Placeholder analyzerPlaceholder2 = new Placeholder();
    178       IntCounter currentIterationCounter = new IntCounter();
    179       Comparator currentIterationComparator = new Comparator();
    180       ConditionalBranch conditionalBranch = new ConditionalBranch();
    181       Placeholder velocityBoundsUpdaterPlaceholder = new Placeholder();
    182       Placeholder omegaUpdaterPlaceholder = new Placeholder();
     168      RealVectorSwarmUpdater swarmUpdater = new RealVectorSwarmUpdater();
     169      mainLoop = new ParticleSwarmOptimizationMainLoop();
    183170
    184171      OperatorGraph.InitialOperator = randomCreator;
     
    192179
    193180      solutionsCreator.NumberOfSolutionsParameter.ActualName = "SwarmSize";
    194       solutionsCreator.EvaluatorParameter.Value = evaluatorPlaceholder;
    195       solutionsCreator.SolutionCreatorParameter.Value = particleCreator;
    196       solutionsCreator.Successor = bestPositionInitializer;
    197 
    198       InitializeParticleCreator(particleCreator);
    199 
    200       evaluatorPlaceholder.Name = "(Evaluator)";
    201       evaluatorPlaceholder.OperatorParameter.ActualName = "Evaluator";
    202       evaluatorPlaceholder.Successor = bestPersonalQualityAssigner;
    203 
    204       bestPersonalQualityAssigner.LeftSideParameter.ActualName = "PersonalBestQuality";
    205       bestPersonalQualityAssigner.RightSideParameter.ActualName = "Quality";
    206 
    207       bestPositionInitializer.Successor = topologyInitializerPlaceholder;
     181      ParameterizeSolutionsCreator();
     182      solutionsCreator.Successor = topologyInitializerPlaceholder;
    208183
    209184      topologyInitializerPlaceholder.Name = "(TopologyInitializer)";
    210185      topologyInitializerPlaceholder.OperatorParameter.ActualName = "TopologyInitializer";
    211       topologyInitializerPlaceholder.Successor = neighborUpdater;
    212 
    213       neighborUpdater.Successor = analyzerPlaceholder;
    214 
    215       analyzerPlaceholder.Name = "(Analyzer)";
    216       analyzerPlaceholder.OperatorParameter.ActualName = "Analyzer";
    217       analyzerPlaceholder.Successor = uniformSubScopeProcessor;
    218 
    219       uniformSubScopeProcessor.Operator = particleUpdaterPlaceholder;
    220       uniformSubScopeProcessor.Successor = evaluationProcessor;
    221 
    222       particleUpdaterPlaceholder.Name = "(ParticleUpdater)";
    223       particleUpdaterPlaceholder.OperatorParameter.ActualName = "ParticleUpdater";
    224 
    225       evaluationProcessor.Parallel = new BoolValue(true);
    226       evaluationProcessor.Operator = evaluatorPlaceholder2;
    227       evaluationProcessor.Successor = topologyUpdaterPlaceholder;
    228 
    229       evaluatorPlaceholder2.Name = "(Evaluator)";
    230       evaluatorPlaceholder2.OperatorParameter.ActualName = "Evaluator";
    231 
    232       topologyUpdaterPlaceholder.Name = "(TopologyUpdater)";
    233       topologyUpdaterPlaceholder.OperatorParameter.ActualName = "TopologyUpdater";
    234       topologyUpdaterPlaceholder.Successor = neighborUpdater2;
    235 
    236       neighborUpdater2.Successor = uniformSubscopesProcessor2;
    237 
    238       uniformSubscopesProcessor2.Operator = swarmUpdater;
    239       uniformSubscopesProcessor2.Successor = analyzerPlaceholder2;
    240 
    241       analyzerPlaceholder2.Name = "(Analyzer)";
    242       analyzerPlaceholder2.OperatorParameter.ActualName = "Analyzer";
    243       analyzerPlaceholder2.Successor = currentIterationCounter;
    244 
    245       currentIterationCounter.Name = "CurrentIteration++";
    246       currentIterationCounter.ValueParameter.ActualName = "CurrentIteration";
    247       currentIterationCounter.Successor = omegaUpdaterPlaceholder;
    248 
    249       omegaUpdaterPlaceholder.Name = "(Omega Updater)";
    250       omegaUpdaterPlaceholder.OperatorParameter.ActualName = "OmegaUpdater";
    251       omegaUpdaterPlaceholder.Successor = velocityBoundsUpdaterPlaceholder;
    252 
    253       velocityBoundsUpdaterPlaceholder.Name = "(Velocity Bounds Updater)";
    254       velocityBoundsUpdaterPlaceholder.OperatorParameter.ActualName = "VelocityBoundsUpdater";
    255       velocityBoundsUpdaterPlaceholder.Successor = currentIterationComparator;
    256 
    257       currentIterationComparator.LeftSideParameter.ActualName = "CurrentIteration";
    258       currentIterationComparator.Comparison = new Comparison(ComparisonType.Less);
    259       currentIterationComparator.RightSideParameter.ActualName = "MaxIterations";
    260       currentIterationComparator.ResultParameter.ActualName = "ContinueIteration";
    261       currentIterationComparator.Successor = conditionalBranch;
    262 
    263       conditionalBranch.Name = "ContinueIteration?";
    264       conditionalBranch.ConditionParameter.ActualName = "ContinueIteration";
    265       conditionalBranch.TrueBranch = uniformSubScopeProcessor;
     186      topologyInitializerPlaceholder.Successor = swarmUpdater;
     187
     188      swarmUpdater.Successor = resultsCollector;
     189
     190      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Iterations", null, "CurrentIteration"));
     191      //resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Current Inertia", null, "Inertia"));
     192      //resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Evaluated Solutions", null, "EvaluatedSolutions"));
     193      resultsCollector.ResultsParameter.ActualName = "Results";
     194      resultsCollector.Successor = mainLoop;
     195
     196      mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
     197      mainLoop.InertiaParameter.ActualName = InertiaParameter.Name;
     198      mainLoop.MaxIterationsParameter.ActualName = MaxIterationsParameter.Name;
     199      mainLoop.NeighborsBestAttractionParameter.ActualName = NeighborsBestAttractionParameter.Name;
     200      mainLoop.InertiaUpdaterParameter.ActualName = InertiaUpdaterParameter.Name;
     201      mainLoop.ParticleUpdaterParameter.ActualName = ParticleUpdaterParameter.Name;
     202      mainLoop.PersonalBestAttractionParameter.ActualName = PersonalBestAttractionParameter.Name;
     203      mainLoop.RandomParameter.ActualName = randomCreator.RandomParameter.ActualName;
     204      mainLoop.SwarmSizeParameter.ActualName = SwarmSizeParameter.Name;
     205      mainLoop.TopologyUpdaterParameter.ActualName = TopologyUpdaterParameter.Name;
     206      mainLoop.RandomParameter.ActualName = randomCreator.RandomParameter.ActualName;
     207      mainLoop.ResultsParameter.ActualName = "Results";
     208      mainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
     209     // mainLoop.EvaluatedMovesParameter.ActualName = "EvaluatedMoves";
    266210
    267211      InitializeAnalyzers();
    268       InitVelocityBoundsUpdater();
     212      ////InitVelocityBoundsUpdater();
     213      InitializeParticleCreator();
     214      ParameterizeSolutionsCreator();
    269215      UpdateAnalyzers();
    270       UpdateOmegaUpdater();
    271       InitOmegaUpdater();
     216      UpdateInertiaUpdater();
     217      InitInertiaUpdater();
    272218      UpdateTopologyInitializer();
    273219      Initialize();
     220      ParameterizeMainLoop();
    274221    }
    275222
     
    284231
    285232    public override void Prepare() {
    286       if (Problem != null) {
     233      if (Problem != null && ParticleCreator != null && ParticleUpdater != null) {
    287234        base.Prepare();
    288         if (OmegaUpdater != null && OmegaUpdater.StartValueParameter.Value != null) {
    289           this.OmegaParameter.ActualValue = new DoubleValue(OmegaUpdaterParameter.Value.StartValueParameter.Value.Value);
     235        if (InertiaUpdater != null && InertiaUpdater.StartValueParameter.Value != null) {
     236          this.InertiaParameter.ActualValue = new DoubleValue(InertiaUpdaterParameter.Value.StartValueParameter.Value.Value);
    290237        }
    291         if (VelocityBoundsUpdater != null && VelocityBoundsUpdater.StartValueParameter.Value != null && VelocityBoundsParameter.Value != null) {
    292           DoubleMatrix matrix = VelocityBoundsParameter.Value;
    293           for (int i = 0; i < matrix.Rows; i++) {
    294             matrix[i, 0] = -VelocityBoundsUpdater.StartValueParameter.Value.Value;
    295             matrix[i, 1] = VelocityBoundsUpdater.StartValueParameter.Value.Value;
    296           }
    297         }
     238        //if (VelocityBoundsUpdater != null && VelocityBoundsUpdater.StartValueParameter.Value != null && VelocityBoundsParameter.Value != null) {
     239        //  DoubleMatrix matrix = VelocityBoundsParameter.Value;
     240        //  for (int i = 0; i < matrix.Rows; i++) {
     241        //    matrix[i, 0] = -VelocityBoundsUpdater.StartValueParameter.Value.Value;
     242        //    matrix[i, 1] = VelocityBoundsUpdater.StartValueParameter.Value.Value;
     243        //  }
     244        //}
    298245      }
    299246    }
     
    303250      UpdateAnalyzers();
    304251      ParameterizeAnalyzers();
     252      UpdateTopologyParameters();
     253      InitializeParticleCreator();
     254      ParameterizeSolutionsCreator();
    305255      base.OnProblemChanged();
    306256    }
     
    310260    }
    311261
    312     void VelocityBoundsUpdaterParameter_ValueChanged(object sender, EventArgs e) {
    313       if (VelocityBoundsParameter.Value != null) {
    314         foreach (IDiscreteDoubleMatrixModifier matrixOp in VelocityBoundsUpdaterParameter.Value.ScalingOperatorParameter.ValidValues) {
    315           matrixOp.ValueParameter.ActualName = VelocityBoundsUpdater.ScaleParameter.Name;
    316           matrixOp.StartValueParameter.Value = new DoubleValue(VelocityBoundsUpdater.ScaleParameter.ActualValue.Value);
    317         }
    318       }
    319     }
     262    //void VelocityBoundsUpdaterParameter_ValueChanged(object sender, EventArgs e) {
     263    //  if (VelocityBoundsParameter.Value != null) {
     264    //    foreach (IDiscreteDoubleMatrixModifier matrixOp in VelocityBoundsUpdaterParameter.Value.ScalingOperatorParameter.ValidValues) {
     265    //      matrixOp.ValueParameter.ActualName = VelocityBoundsUpdater.ScaleParameter.Name;
     266    //      matrixOp.StartValueParameter.Value = new DoubleValue(VelocityBoundsUpdater.ScaleParameter.ActualValue.Value);
     267    //    }
     268    //  }
     269    //}
    320270    #endregion
    321271
     
    325275    }
    326276
    327     private static void InitializeParticleCreator(CombinedOperator particleCreator) {
    328       Placeholder positionCreator = new Placeholder();
    329       Assigner personalBestPositionAssigner = new Assigner();
    330       UniformRandomRealVectorCreator velocityCreator = new UniformRandomRealVectorCreator();
    331 
    332       particleCreator.Name = "Particle Creator";
    333       particleCreator.OperatorGraph.InitialOperator = positionCreator;
    334 
    335       positionCreator.Name = "(SolutionCreator)";
    336       positionCreator.OperatorParameter.ActualName = "SolutionCreator";
    337       positionCreator.Successor = personalBestPositionAssigner;
    338 
    339       personalBestPositionAssigner.LeftSideParameter.ActualName = "PersonalBestPoint";
    340       personalBestPositionAssigner.RightSideParameter.ActualName = "Point";
    341       personalBestPositionAssigner.Successor = velocityCreator;
    342 
    343       velocityCreator.LengthParameter.ActualName = "ProblemSize";
    344       velocityCreator.BoundsParameter.ActualName = "VelocityBounds";
    345       velocityCreator.RealVectorParameter.ActualName = "Velocity";
     277    private void InitializeParticleCreator() {
     278      if (Problem != null) {
     279        IParticleCreator oldParticleCreator = ParticleCreator;
     280        ParticleCreatorParameter.ValidValues.Clear();
     281        foreach (IParticleCreator Creator in Problem.Operators.OfType<IParticleCreator>().OrderBy(x => x.Name)) {
     282          ParticleCreatorParameter.ValidValues.Add(Creator);
     283        }
     284        if (oldParticleCreator != null) {
     285          IParticleCreator creator = ParticleCreatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleCreator.GetType());
     286          if (creator != null) ParticleCreator = creator;
     287        } 
     288      }
    346289    }
    347290
     
    368311    }
    369312
    370     private void InitVelocityBoundsUpdater() {
    371       foreach (IDiscreteDoubleMatrixModifier matrixOp in ApplicationManager.Manager.GetInstances<IDiscreteDoubleMatrixModifier>()) {
    372         VelocityBoundsUpdaterParameter.ValidValues.Add(matrixOp);
    373         matrixOp.ValueParameter.ActualName = VelocityBoundsParameter.Name;
    374         matrixOp.EndIndexParameter.ActualName = MaxIterationsParameter.Name;
    375         matrixOp.StartIndexParameter.Value = new IntValue(0);
    376         matrixOp.IndexParameter.ActualName = "CurrentIteration";
    377         matrixOp.EndValueParameter.Value = new DoubleValue(0);
    378       }
    379       VelocityBoundsUpdaterParameter.ValueChanged += new EventHandler(VelocityBoundsUpdaterParameter_ValueChanged);
    380     }
    381 
    382     private void InitOmegaUpdater() {
    383       foreach (IDiscreteDoubleValueModifier updater in OmegaUpdaterParameter.ValidValues) {
     313    //private void InitVelocityBoundsUpdater() {
     314    //  foreach (IDiscreteDoubleMatrixModifier matrixOp in ApplicationManager.Manager.GetInstances<IDiscreteDoubleMatrixModifier>()) {
     315    //    VelocityBoundsUpdaterParameter.ValidValues.Add(matrixOp);
     316    //    matrixOp.ValueParameter.ActualName = VelocityBoundsParameter.Name;
     317    //    matrixOp.EndIndexParameter.ActualName = MaxIterationsParameter.Name;
     318    //    matrixOp.StartIndexParameter.Value = new IntValue(0);
     319    //    matrixOp.IndexParameter.ActualName = "CurrentIteration";
     320    //    matrixOp.EndValueParameter.Value = new DoubleValue(0);
     321    //  }
     322    //  VelocityBoundsUpdaterParameter.ValueChanged += new EventHandler(VelocityBoundsUpdaterParameter_ValueChanged);
     323    //}
     324
     325    private void InitInertiaUpdater() {
     326      foreach (IDiscreteDoubleValueModifier updater in InertiaUpdaterParameter.ValidValues) {
    384327        updater.EndIndexParameter.ActualName = MaxIterationsParameter.Name;
    385328        updater.StartIndexParameter.Value = new IntValue(0);
    386329        updater.IndexParameter.ActualName = "CurrentIteration";
    387         updater.ValueParameter.ActualName = OmegaParameter.Name;
     330        updater.ValueParameter.ActualName = InertiaParameter.Name;
    388331        updater.StartValueParameter.Value = new DoubleValue(1);
    389332        updater.EndValueParameter.Value = new DoubleValue(0);
     
    391334    }
    392335
    393     private void UpdateOmegaUpdater() {
    394       IDiscreteDoubleValueModifier oldOmegaUpdater = OmegaUpdater;
    395       OmegaUpdaterParameter.ValidValues.Clear();
     336    private void UpdateInertiaUpdater() {
     337      IDiscreteDoubleValueModifier oldInertiaUpdater = InertiaUpdater;
     338      InertiaUpdaterParameter.ValidValues.Clear();
    396339      foreach (IDiscreteDoubleValueModifier updater in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name)) {
    397         OmegaUpdaterParameter.ValidValues.Add(updater);
    398       }
    399       if (oldOmegaUpdater != null) {
    400         IDiscreteDoubleValueModifier updater = OmegaUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldOmegaUpdater.GetType());
    401         if (updater != null) OmegaUpdaterParameter.Value = updater;
     340        InertiaUpdaterParameter.ValidValues.Add(updater);
     341      }
     342      if (oldInertiaUpdater != null) {
     343        IDiscreteDoubleValueModifier updater = InertiaUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldInertiaUpdater.GetType());
     344        if (updater != null) InertiaUpdaterParameter.Value = updater;
    402345      }
    403346    }
     
    418361      IParticleUpdater oldParticleUpdater = ParticleUpdater;
    419362      ClearTopologyParameters();
    420       if (TopologyInitializer != null) {
    421         foreach (ITopologyUpdater topologyUpdater in ApplicationManager.Manager.GetInstances<ITopologyUpdater>())
    422           TopologyUpdaterParameter.ValidValues.Add(topologyUpdater);
    423         foreach (IParticleUpdater particleUpdater in ApplicationManager.Manager.GetInstances<ILocalParticleUpdater>())
    424           ParticleUpdaterParameter.ValidValues.Add(particleUpdater);
    425       } else {
    426         foreach (IParticleUpdater particleUpdater in ApplicationManager.Manager.GetInstances<IGlobalParticleUpdater>())
    427           ParticleUpdaterParameter.ValidValues.Add(particleUpdater);
    428       }
    429       if (oldTopologyUpdater != null) {
    430         ITopologyUpdater newTopologyUpdater = TopologyUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleUpdater.GetType());
    431         if (newTopologyUpdater != null) TopologyUpdater = newTopologyUpdater;
    432       }
    433       if (oldParticleUpdater != null) {
    434         IParticleUpdater newParticleUpdater = ParticleUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleUpdater.GetType());
    435         if (newParticleUpdater != null) ParticleUpdater = newParticleUpdater;
     363      if (Problem != null) {
     364        if (TopologyInitializer != null) {
     365          foreach (ITopologyUpdater topologyUpdater in ApplicationManager.Manager.GetInstances<ITopologyUpdater>())
     366            TopologyUpdaterParameter.ValidValues.Add(topologyUpdater);
     367          foreach (IParticleUpdater particleUpdater in Problem.Operators.OfType<ILocalParticleUpdater>().OrderBy(x => x.Name))
     368            ParticleUpdaterParameter.ValidValues.Add(particleUpdater);
     369        } else {
     370          foreach (IParticleUpdater particleUpdater in Problem.Operators.OfType<IGlobalParticleUpdater>().OrderBy(x => x.Name))
     371            ParticleUpdaterParameter.ValidValues.Add(particleUpdater);
     372        }
     373        if (oldTopologyUpdater != null) {
     374          ITopologyUpdater newTopologyUpdater = TopologyUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleUpdater.GetType());
     375          if (newTopologyUpdater != null) TopologyUpdater = newTopologyUpdater;
     376        }
     377        if (oldParticleUpdater != null) {
     378          IParticleUpdater newParticleUpdater = ParticleUpdaterParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldParticleUpdater.GetType());
     379          if (newParticleUpdater != null) ParticleUpdater = newParticleUpdater;
     380        }
    436381      }
    437382    }
     
    441386      ParticleUpdaterParameter.ValidValues.Clear();
    442387    }
     388
     389    private void ParameterizeSolutionsCreator() {
     390      if (Problem != null) {
     391        solutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
     392        solutionsCreator.SolutionCreatorParameter.ActualName = ParticleCreatorParameter.Name;
     393      }
     394    }
     395
     396    private void ParameterizeMainLoop() {
     397      mainLoop.MaxIterationsParameter.ActualName = MaxIterationsParameter.Name;
     398    }
    443399    #endregion
    444400
  • trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/RandomTopologyInitializer.cs

    r5445 r5560  
    2525using HeuristicLab.Core;
    2626using HeuristicLab.Data;
    27 using HeuristicLab.Encodings.IntegerVectorEncoding;
    2827using HeuristicLab.Parameters;
    2928using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     
    6665
    6766    public override IOperation Apply() {
    68       ItemArray<IntegerVector> neighbors = new ItemArray<IntegerVector>(SwarmSize);
     67      ItemArray<IntArray> neighbors = new ItemArray<IntArray>(SwarmSize);
    6968      for (int i = 0; i < SwarmSize; i++) {
    7069        var numbers = Enumerable.Range(0, SwarmSize).ToList();
     
    7675          numbers.RemoveAt(index);
    7776        }
    78         neighbors[i] = new IntegerVector(selectedNumbers.ToArray());
     77        neighbors[i] = new IntArray(selectedNumbers.ToArray());
    7978      }
    8079      Neighbors = neighbors;
  • trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/RingTopologyInitializer.cs

    r5445 r5560  
    2222using HeuristicLab.Common;
    2323using HeuristicLab.Core;
    24 using HeuristicLab.Encodings.IntegerVectorEncoding;
    2524using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     25using HeuristicLab.Data;
    2626
    2727namespace HeuristicLab.Algorithms.ParticleSwarmOptimization {
     
    4343
    4444    public override IOperation Apply() {
    45       ItemArray<IntegerVector> neighbors = new ItemArray<IntegerVector>(SwarmSize);
     45      ItemArray<IntArray> neighbors = new ItemArray<IntArray>(SwarmSize);
    4646      for (int i = 0; i < SwarmSize; i++) {
    47         neighbors[i] = new IntegerVector(new[] { (SwarmSize + i - 1) % SwarmSize, (i + 1) % SwarmSize });
     47        neighbors[i] = new IntArray(new[] { (SwarmSize + i - 1) % SwarmSize, (i + 1) % SwarmSize });
    4848      }
    4949      Neighbors = neighbors;
  • trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/TopologyInitializer.cs

    r5445 r5560  
    2323using HeuristicLab.Core;
    2424using HeuristicLab.Data;
    25 using HeuristicLab.Encodings.IntegerVectorEncoding;
    2625using HeuristicLab.Operators;
     26using HeuristicLab.Optimization;
    2727using HeuristicLab.Parameters;
    2828using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     
    3737
    3838    #region Parameters
    39     public IScopeTreeLookupParameter<IntegerVector> NeighborsParameter {
    40       get { return (IScopeTreeLookupParameter<IntegerVector>)Parameters["Neighbors"]; }
     39    public IScopeTreeLookupParameter<IntArray> NeighborsParameter {
     40      get { return (IScopeTreeLookupParameter<IntArray>)Parameters["Neighbors"]; }
    4141    }
     42
    4243    public ILookupParameter<IntValue> SwarmSizeParameter {
    4344      get { return (ILookupParameter<IntValue>)Parameters["SwarmSize"]; }
     
    4748
    4849    #region Parameter Values
    49     protected ItemArray<IntegerVector> Neighbors {
     50    protected ItemArray<IntArray> Neighbors {
    5051      get { return NeighborsParameter.ActualValue; }
    5152      set { NeighborsParameter.ActualValue = value; }
     
    6061    protected TopologyInitializer(bool deserializing) : base(deserializing) { }
    6162    protected TopologyInitializer(TopologyInitializer original, Cloner cloner) : base(original, cloner) { }
     63   
    6264    public TopologyInitializer() {
    63       Parameters.Add(new ScopeTreeLookupParameter<IntegerVector>("Neighbors", "The list of neighbors for each particle."));
     65      Parameters.Add(new ScopeTreeLookupParameter<IntArray>("Neighbors", "The list of neighbors for each particle."));
    6466      Parameters.Add(new LookupParameter<IntValue>("SwarmSize", "Number of particles in the swarm."));
    6567    }
    6668    #endregion
    67 
    6869  }
    6970
  • trunk/sources/HeuristicLab.Algorithms.ParticleSwarmOptimization/3.3/VonNeumannTopologyInitializer.cs

    r5445 r5560  
    2222using HeuristicLab.Common;
    2323using HeuristicLab.Core;
    24 using HeuristicLab.Encodings.IntegerVectorEncoding;
    2524using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     25using HeuristicLab.Data;
    2626
    2727namespace HeuristicLab.Algorithms.ParticleSwarmOptimization {
     
    4444
    4545    public override IOperation Apply() {
    46       ItemArray<IntegerVector> neighbors = new ItemArray<IntegerVector>(SwarmSize);
     46      ItemArray<IntArray> neighbors = new ItemArray<IntArray>(SwarmSize);
    4747      for (int i = 0; i < SwarmSize; i++) {
    48         neighbors[i] = new IntegerVector(new[] {
     48        neighbors[i] = new IntArray(new[] {
    4949          (SwarmSize + i-2) % SwarmSize,
    5050          (SwarmSize + i-1) % SwarmSize,
  • trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/HeuristicLab.Encodings.RealVectorEncoding-3.3.csproj

    r5385 r5560  
    104104  </ItemGroup>
    105105  <ItemGroup>
     106    <Compile Include="ParticleOperators\RealVectorParticleCreator.cs" />
    106107    <Compile Include="Crossovers\BlendAlphaBetaCrossover.cs" />
    107108    <Compile Include="Interfaces\IRealVectorManipulator.cs" />
     
    111112    <Compile Include="BoundsChecker.cs" />
    112113    <Compile Include="Creators\UniformRandomRealVectorCreator.cs" />
     114    <Compile Include="Interfaces\IRealVectorParticleCreator.cs" />
     115    <Compile Include="Interfaces\IRealVectorParticleUpdater.cs" />
     116    <Compile Include="Interfaces\IRealVectorSwarmUpdater.cs" />
    113117    <Compile Include="Manipulators\SelfAdaptiveNormalAllPositionsManipulator.cs" />
     118    <Compile Include="ParticleOperators\RealVectorNeighborhoodParticleUpdater.cs" />
     119    <Compile Include="ParticleOperators\RealVectorParticleUpdater.cs" />
     120    <Compile Include="ParticleOperators\RealVectorSwarmUpdater.cs" />
     121    <Compile Include="ParticleOperators\RealVectorTotallyConnectedParticleUpdater.cs" />
    114122    <Compile Include="RealVectorCreator.cs" />
    115123    <Compile Include="RealVectorCrossover.cs" />
     
    230238    </BootstrapperPackage>
    231239  </ItemGroup>
     240  <ItemGroup />
    232241  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    233242  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
  • trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj

    r5422 r5560  
    114114    <Compile Include="Algorithm.cs" />
    115115    <Compile Include="BatchRun.cs" />
     116    <Compile Include="Interfaces\IDiscreteDoubleMatrixModifier.cs" />
     117    <Compile Include="Interfaces\IGlobalParticleUpdater.cs" />
     118    <Compile Include="Interfaces\ILocalParticleUpdater.cs" />
    116119    <Compile Include="Interfaces\IMultiAnalyzer.cs" />
    117120    <Compile Include="Interfaces\IIterationBasedOperator.cs" />
     121    <Compile Include="Interfaces\IParticleCreator.cs" />
     122    <Compile Include="Interfaces\IParticleUpdater.cs" />
     123    <Compile Include="Interfaces\ISwarmUpdater.cs" />
     124    <Compile Include="Interfaces\ITopologyInitializer.cs" />
     125    <Compile Include="Interfaces\ITopologyUpdater.cs" />
    118126    <Compile Include="MultiObjectiveProblem.cs" />
    119127    <Compile Include="Problem.cs" />
  • trunk/sources/HeuristicLab.Problems.TestFunctions/3.3/SingleObjectiveTestFunctionProblem.cs

    r5445 r5560  
    403403        op.RealVectorParameter.ActualName = SolutionCreator.RealVectorParameter.ActualName;
    404404      }
     405      foreach (IRealVectorParticleCreator op in Operators.OfType<IRealVectorParticleCreator>()) {
     406        op.RealVectorParameter.ActualName = SolutionCreator.RealVectorParameter.ActualName;
     407        op.BoundsParameter.ActualName = BoundsParameter.Name;
     408        op.ProblemSizeParameter.ActualName = ProblemSizeParameter.Name;
     409      }
     410      foreach (IRealVectorParticleUpdater op in Operators.OfType<IRealVectorParticleUpdater>()) {
     411        op.RealVectorParameter.ActualName = SolutionCreator.RealVectorParameter.ActualName;
     412        op.BoundsParameter.ActualName = BoundsParameter.Name;
     413      }
    405414    }
    406415    private void UpdateStrategyVectorBounds() {
Note: See TracChangeset for help on using the changeset viewer.