Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.GP.Algorithms/3.2/AlgorithmBase.cs @ 2530

Last change on this file since 2530 was 2385, checked in by gkronber, 15 years ago

Implemented #762 (ValidationQuality improvment progress as additional stopping criterion for default StructId Engines)

File size: 21.8 KB
RevLine 
[1230]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
[2222]24using System.Xml;
[1230]25using HeuristicLab.Core;
[2222]26using HeuristicLab.Data;
27using HeuristicLab.Evolutionary;
28using HeuristicLab.Logging;
[1230]29using HeuristicLab.Operators;
30using HeuristicLab.Random;
31using HeuristicLab.Selection;
[2331]32using HeuristicLab.GP.Operators;
[1230]33
[2331]34namespace HeuristicLab.GP.Algorithms {
35  public abstract class AlgorithmBase : ItemBase {
[1857]36    public virtual string Name { get { return "GP"; } }
37    public virtual string Description { get { return "TODO"; } }
38
[1231]39    public virtual double MutationRate {
[1287]40      get { return GetVariableInjector().GetVariable("MutationRate").GetValue<DoubleData>().Data; }
41      set { GetVariableInjector().GetVariable("MutationRate").GetValue<DoubleData>().Data = value; }
[1230]42    }
[1231]43    public virtual int PopulationSize {
[1287]44      get { return GetVariableInjector().GetVariable("PopulationSize").GetValue<IntData>().Data; }
45      set { GetVariableInjector().GetVariable("PopulationSize").GetValue<IntData>().Data = value; }
[1230]46    }
47
[2335]48    public virtual int MaxGenerations {
49      get { return GetVariableInjector().GetVariable("MaxGenerations").GetValue<IntData>().Data; }
50      set { GetVariableInjector().GetVariable("MaxGenerations").GetValue<IntData>().Data = value; }
[1230]51    }
52
[1231]53    public virtual int Elites {
[1287]54      get { return GetVariableInjector().GetVariable("Elites").GetValue<IntData>().Data; }
55      set { GetVariableInjector().GetVariable("Elites").GetValue<IntData>().Data = value; }
[1230]56    }
57
[1231]58    public virtual int MaxTreeSize {
[1287]59      get { return GetVariableInjector().GetVariable("MaxTreeSize").GetValue<IntData>().Data; }
60      set { GetVariableInjector().GetVariable("MaxTreeSize").GetValue<IntData>().Data = value; }
[1230]61    }
62
[2335]63    public virtual int MinTreeSize {
64      get { return GetVariableInjector().GetVariable("MinTreeSize").GetValue<IntData>().Data; }
65      set { GetVariableInjector().GetVariable("MinTreeSize").GetValue<IntData>().Data = value; }
66    }
67
[1231]68    public virtual int MaxTreeHeight {
[1287]69      get { return GetVariableInjector().GetVariable("MaxTreeHeight").GetValue<IntData>().Data; }
70      set { GetVariableInjector().GetVariable("MaxTreeHeight").GetValue<IntData>().Data = value; }
[1230]71    }
72
[1231]73    public virtual int Parents {
[1287]74      get { return GetVariableInjector().GetVariable("Parents").GetValue<IntData>().Data; }
75      set { GetVariableInjector().GetVariable("Parents").GetValue<IntData>().Data = value; }
[1231]76    }
77
[2335]78    public virtual bool SetSeedRandomly {
79      get { return GetRandomInjector().GetVariable("SetSeedRandomly").GetValue<BoolData>().Data; }
80      set { GetRandomInjector().GetVariable("SetSeedRandomly").GetValue<BoolData>().Data = value; }
81    }
82
83    public virtual int RandomSeed {
84      get { return GetRandomInjector().GetVariable("Seed").GetValue<IntData>().Data; }
85      set { GetRandomInjector().GetVariable("Seed").GetValue<IntData>().Data = value; }
86    }
87
88    public virtual IOperator ProblemInjector {
89      get { return GetInitializationOperator().SubOperators[0]; }
90      set {
91        value.Name = "ProblemInjector";
92        IOperator init = GetInitializationOperator();
93        init.RemoveSubOperator(0);
94        init.AddSubOperator(value, 0);
95      }
96    }
97
98    public virtual IOperator FunctionLibraryInjector {
99      get { return GetInitializationOperator().SubOperators[1]; }
100      set {
101        value.Name = "FunctionLibraryInjector";
102        IOperator init = GetInitializationOperator();
103        init.RemoveSubOperator(1);
104        init.AddSubOperator(value, 1);
105      }
106    }
107
[2377]108    private IEngine engine;
[1230]109    public IEngine Engine {
110      get { return engine; }
[2377]111      protected set { engine = value; }
[1230]112    }
113
114    public AlgorithmBase() {
115      engine = new SequentialEngine.SequentialEngine();
116      CombinedOperator algo = CreateAlgorithm();
117      engine.OperatorGraph.AddOperator(algo);
118      engine.OperatorGraph.InitialOperator = algo;
[1287]119      SetSeedRandomly = true;
120      Elites = 1;
121      MutationRate = 0.15;
122      PopulationSize = 1000;
[2335]123      MaxGenerations = 100;
[1287]124      MaxTreeSize = 100;
[2335]125      MinTreeSize = 1;
[1287]126      MaxTreeHeight = 10;
127      Parents = 2000;
[1230]128    }
129
[1287]130    protected internal virtual CombinedOperator CreateAlgorithm() {
[1230]131      CombinedOperator algo = new CombinedOperator();
[2361]132      algo.Name = Name;
[1230]133      SequentialProcessor seq = new SequentialProcessor();
[2361]134      seq.Name = Name;
[2335]135      IOperator init = CreateInitializationOperator();
136      init.AddSubOperator(CreateProblemInjector());
137      init.AddSubOperator(CreateFunctionLibraryInjector());
138      seq.AddSubOperator(init);
[1230]139
[2335]140      IOperator initPopulation = CreateInitialPopulationGenerator();
141      initPopulation.AddSubOperator(CreateRandomSolutionGenerator());
142      initPopulation.AddSubOperator(CreateInitialPopulationEvaluator());
143      seq.AddSubOperator(initPopulation);
[1230]144
145      IOperator mainLoop = CreateMainLoop();
[2335]146      mainLoop.AddSubOperator(CreateSelectionOperator());
147      mainLoop.AddSubOperator(CreateCrossoverOperator());
148      mainLoop.AddSubOperator(CreateManipulationOperator());
149      mainLoop.AddSubOperator(CreateEvaluationOperator());
150      mainLoop.AddSubOperator(CreateTerminationCondition());
[1230]151      seq.AddSubOperator(mainLoop);
152
[2335]153      IOperator postProcess = CreatePostProcessingOperator();
154      seq.AddSubOperator(postProcess);
[1230]155
156      algo.OperatorGraph.AddOperator(seq);
157      algo.OperatorGraph.InitialOperator = seq;
158      return algo;
159    }
160
[2335]161    #region global init
162    protected virtual IOperator CreateInitializationOperator() {
163      CombinedOperator init = new CombinedOperator();
164      init.Name = "Initialization";
165      SequentialProcessor seq = new SequentialProcessor();
166      seq.AddSubOperator(CreateRandomInjector());
167      seq.AddSubOperator(CreateGlobalInjector());
[2328]168
[2335]169      OperatorExtractor probInjectorExtractor = new OperatorExtractor();
170      probInjectorExtractor.Name = "ProblemInjector";
171      probInjectorExtractor.GetVariableInfo("Operator").ActualName = "ProblemInjector";
172      seq.AddSubOperator(probInjectorExtractor);
173
174      OperatorExtractor funLibInjectorExtractor = new OperatorExtractor();
175      funLibInjectorExtractor.Name = "FunctionLibraryInjector";
176      funLibInjectorExtractor.GetVariableInfo("Operator").ActualName = "FunctionLibraryInjector";
177      seq.AddSubOperator(funLibInjectorExtractor);
178
179      init.OperatorGraph.AddOperator(seq);
180      init.OperatorGraph.InitialOperator = seq;
181      return init;
[1287]182    }
[1230]183
[2335]184    protected virtual IOperator CreateRandomInjector() {
185      RandomInjector randomInjector = new RandomInjector();
186      randomInjector.Name = "Random Injector";
187      return randomInjector;
[2331]188    }
[1230]189
[2335]190    protected virtual VariableInjector CreateGlobalInjector() {
[1230]191      VariableInjector injector = new VariableInjector();
192      injector.Name = "Global Injector";
193      injector.AddVariable(new HeuristicLab.Core.Variable("Generations", new IntData(0)));
[2335]194      injector.AddVariable(new HeuristicLab.Core.Variable("MaxGenerations", new IntData()));
[1287]195      injector.AddVariable(new HeuristicLab.Core.Variable("MutationRate", new DoubleData()));
196      injector.AddVariable(new HeuristicLab.Core.Variable("PopulationSize", new IntData()));
197      injector.AddVariable(new HeuristicLab.Core.Variable("Elites", new IntData()));
[1230]198      injector.AddVariable(new HeuristicLab.Core.Variable("Maximization", new BoolData(false)));
[1287]199      injector.AddVariable(new HeuristicLab.Core.Variable("MaxTreeHeight", new IntData()));
200      injector.AddVariable(new HeuristicLab.Core.Variable("MaxTreeSize", new IntData()));
[2335]201      injector.AddVariable(new HeuristicLab.Core.Variable("MinTreeSize", new IntData()));
[1230]202      injector.AddVariable(new HeuristicLab.Core.Variable("EvaluatedSolutions", new IntData(0)));
203      injector.AddVariable(new HeuristicLab.Core.Variable("TotalEvaluatedNodes", new DoubleData(0)));
[1287]204      injector.AddVariable(new HeuristicLab.Core.Variable("Parents", new IntData()));
[1230]205      return injector;
206    }
207
208
[2335]209    protected virtual IOperator CreateProblemInjector() {
210      return new EmptyOperator();
211    }
212
213    protected virtual IOperator CreateFunctionLibraryInjector() {
214      return new EmptyOperator();
215    }
216    #endregion
217
218    #region population init
219    private IOperator CreateInitialPopulationGenerator() {
220      CombinedOperator initPopulation = new CombinedOperator();
221      initPopulation.Name = "Init population";
[1230]222      SequentialProcessor seq = new SequentialProcessor();
223      SubScopesCreater subScopesCreater = new SubScopesCreater();
224      subScopesCreater.GetVariableInfo("SubScopes").ActualName = "PopulationSize";
225      UniformSequentialSubScopesProcessor subScopesProc = new UniformSequentialSubScopesProcessor();
226      SequentialProcessor individualSeq = new SequentialProcessor();
227      OperatorExtractor treeCreater = new OperatorExtractor();
228      treeCreater.Name = "Tree generator (extr.)";
[2335]229      treeCreater.GetVariableInfo("Operator").ActualName = "Solution generator";
230
[1230]231      OperatorExtractor evaluator = new OperatorExtractor();
232      evaluator.Name = "Evaluator (extr.)";
233      evaluator.GetVariableInfo("Operator").ActualName = "Evaluator";
234      Counter evalCounter = new Counter();
235      evalCounter.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
236      Sorter sorter = new Sorter();
237      sorter.GetVariableInfo("Descending").ActualName = "Maximization";
238      sorter.GetVariableInfo("Value").ActualName = "Quality";
239
240      seq.AddSubOperator(subScopesCreater);
241      seq.AddSubOperator(subScopesProc);
242      seq.AddSubOperator(sorter);
243
244      subScopesProc.AddSubOperator(individualSeq);
245      individualSeq.AddSubOperator(treeCreater);
246      individualSeq.AddSubOperator(evaluator);
247      individualSeq.AddSubOperator(evalCounter);
248
[2335]249      initPopulation.OperatorGraph.AddOperator(seq);
250      initPopulation.OperatorGraph.InitialOperator = seq;
251      return initPopulation;
[1230]252    }
253
[2335]254    protected virtual IOperator CreateRandomSolutionGenerator() {
255      ProbabilisticTreeCreator treeCreator = new ProbabilisticTreeCreator();
256      treeCreator.Name = "Solution generator";
257      return treeCreator;
258    }
259
260    protected virtual IOperator CreateInitialPopulationEvaluator() {
261      return new EmptyOperator();
262    }
263    #endregion
264
265    #region mainloop
266    protected virtual IOperator CreateMainLoop() {
[1230]267      CombinedOperator main = new CombinedOperator();
[2335]268      main.Name = "Main";
[1230]269      SequentialProcessor seq = new SequentialProcessor();
270      IOperator childCreater = CreateChildCreater();
271      IOperator replacement = CreateReplacement();
272
273      BestAverageWorstQualityCalculator qualityCalculator = new BestAverageWorstQualityCalculator();
[1287]274      IOperator loggingOperator = CreateLoggingOperator();
[1230]275      Counter counter = new Counter();
276      counter.GetVariableInfo("Value").ActualName = "Generations";
277
[2335]278      OperatorExtractor terminationCriterionExtractor = new OperatorExtractor();
279      terminationCriterionExtractor.Name = "TerminationCondition (extr.)";
280      terminationCriterionExtractor.GetVariableInfo("Operator").ActualName = "TerminationCondition";
281
282      ConditionalBranch loop = new ConditionalBranch();
283      loop.Name = "Main loop";
284      loop.GetVariableInfo("Condition").ActualName = "TerminationCriterion";
285      loop.AddSubOperator(new EmptyOperator());
286      loop.AddSubOperator(seq);
287
[1230]288      seq.AddSubOperator(childCreater);
289      seq.AddSubOperator(replacement);
290      seq.AddSubOperator(qualityCalculator);
[2335]291      seq.AddSubOperator(CreateGenerationStepHook());
[1287]292      seq.AddSubOperator(loggingOperator);
[1230]293      seq.AddSubOperator(counter);
[2335]294      seq.AddSubOperator(terminationCriterionExtractor);
295      seq.AddSubOperator(loop);
[1230]296
297      main.OperatorGraph.AddOperator(seq);
298      main.OperatorGraph.InitialOperator = seq;
299      return main;
300    }
301
[2335]302    protected virtual IOperator CreateChildCreater() {
[1230]303      CombinedOperator childCreater = new CombinedOperator();
304      childCreater.Name = "Create children";
305      SequentialProcessor seq = new SequentialProcessor();
306      OperatorExtractor selector = new OperatorExtractor();
307      selector.Name = "Selector (extr.)";
308      selector.GetVariableInfo("Operator").ActualName = "Selector";
[1335]309
[1230]310      SequentialSubScopesProcessor seqScopesProc = new SequentialSubScopesProcessor();
311      EmptyOperator emptyOpt = new EmptyOperator();
312      SequentialProcessor selectedProc = new SequentialProcessor();
[1335]313      ChildrenInitializer childInitializer = new ChildrenInitializer();
314      ((IntData)childInitializer.GetVariable("ParentsPerChild").Value).Data = 2;
315
[1230]316      OperatorExtractor crossover = new OperatorExtractor();
317      crossover.Name = "Crossover (extr.)";
318      crossover.GetVariableInfo("Operator").ActualName = "Crossover";
319      UniformSequentialSubScopesProcessor individualProc = new UniformSequentialSubScopesProcessor();
320      SequentialProcessor individualSeqProc = new SequentialProcessor();
321      StochasticBranch cond = new StochasticBranch();
322      cond.GetVariableInfo("Probability").ActualName = "MutationRate";
323      OperatorExtractor manipulator = new OperatorExtractor();
324      manipulator.Name = "Manipulator (extr.)";
325      manipulator.GetVariableInfo("Operator").ActualName = "Manipulator";
326      OperatorExtractor evaluator = new OperatorExtractor();
327      evaluator.Name = "Evaluator (extr.)";
328      evaluator.GetVariableInfo("Operator").ActualName = "Evaluator";
329      Counter evalCounter = new Counter();
330      evalCounter.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
[1335]331      SubScopesRemover parentRefRemover = new SubScopesRemover();
[1230]332
333      Sorter sorter = new Sorter();
334      sorter.GetVariableInfo("Descending").ActualName = "Maximization";
335      sorter.GetVariableInfo("Value").ActualName = "Quality";
336
337
338      seq.AddSubOperator(selector);
339      seq.AddSubOperator(seqScopesProc);
340      seqScopesProc.AddSubOperator(emptyOpt);
341      seqScopesProc.AddSubOperator(selectedProc);
[1335]342      selectedProc.AddSubOperator(childInitializer);
[1230]343      selectedProc.AddSubOperator(individualProc);
344      individualProc.AddSubOperator(individualSeqProc);
[1335]345      individualSeqProc.AddSubOperator(crossover);
[1230]346      individualSeqProc.AddSubOperator(cond);
347      cond.AddSubOperator(manipulator);
348      individualSeqProc.AddSubOperator(evaluator);
349      individualSeqProc.AddSubOperator(evalCounter);
[1335]350      individualSeqProc.AddSubOperator(parentRefRemover);
[1230]351      selectedProc.AddSubOperator(sorter);
352
353      childCreater.OperatorGraph.AddOperator(seq);
354      childCreater.OperatorGraph.InitialOperator = seq;
355      return childCreater;
356    }
357
[2335]358    protected virtual IOperator CreateReplacement() {
359      CombinedOperator replacement = new CombinedOperator();
360      replacement.Name = "Replacement";
361      SequentialProcessor seq = new SequentialProcessor();
362      SequentialSubScopesProcessor seqScopeProc = new SequentialSubScopesProcessor();
363      SequentialProcessor selectedProc = new SequentialProcessor();
364      LeftSelector leftSelector = new LeftSelector();
365      leftSelector.GetVariableInfo("Selected").ActualName = "Elites";
366      RightReducer rightReducer = new RightReducer();
[2270]367
[2335]368      SequentialProcessor remainingProc = new SequentialProcessor();
369      RightSelector rightSelector = new RightSelector();
370      rightSelector.GetVariableInfo("Selected").ActualName = "Elites";
371      LeftReducer leftReducer = new LeftReducer();
372      MergingReducer mergingReducer = new MergingReducer();
373      Sorter sorter = new Sorter();
374      sorter.GetVariableInfo("Descending").ActualName = "Maximization";
375      sorter.GetVariableInfo("Value").ActualName = "Quality";
[2041]376
[2335]377      seq.AddSubOperator(seqScopeProc);
378      seqScopeProc.AddSubOperator(selectedProc);
379      selectedProc.AddSubOperator(leftSelector);
380      selectedProc.AddSubOperator(rightReducer);
[2328]381
[2335]382      seqScopeProc.AddSubOperator(remainingProc);
383      remainingProc.AddSubOperator(rightSelector);
384      remainingProc.AddSubOperator(leftReducer);
385      seq.AddSubOperator(mergingReducer);
386      seq.AddSubOperator(sorter);
387      replacement.OperatorGraph.AddOperator(seq);
388      replacement.OperatorGraph.InitialOperator = seq;
389      return replacement;
[1906]390    }
391
[2335]392    protected virtual IOperator CreateLoggingOperator() {
393      CombinedOperator loggingOperator = new CombinedOperator();
394      loggingOperator.Name = "Logging";
395      SequentialProcessor seq = new SequentialProcessor();
396
397      DataCollector collector = new DataCollector();
398      ItemList<StringData> names = collector.GetVariable("VariableNames").GetValue<ItemList<StringData>>();
399      names.Add(new StringData("BestQuality"));
400      names.Add(new StringData("AverageQuality"));
401      names.Add(new StringData("WorstQuality"));
402      LinechartInjector lineChartInjector = new LinechartInjector();
403      lineChartInjector.GetVariableInfo("Linechart").ActualName = "Quality Linechart";
404      lineChartInjector.GetVariable("NumberOfLines").GetValue<IntData>().Data = 3;
405      QualityLogger qualityLogger = new QualityLogger();
406
407      seq.AddSubOperator(collector);
408      seq.AddSubOperator(lineChartInjector);
409      seq.AddSubOperator(qualityLogger);
410
411      loggingOperator.OperatorGraph.AddOperator(seq);
412      loggingOperator.OperatorGraph.InitialOperator = seq;
413      return loggingOperator;
414    }
415
416    protected virtual IOperator CreateGenerationStepHook() {
417      return new EmptyOperator();
418    }
419
420    protected virtual IOperator CreateTerminationCondition() {
421      CombinedOperator terminationCriterion = new CombinedOperator();
422      terminationCriterion.Name = "TerminationCondition";
423      SequentialProcessor seq = new SequentialProcessor();
424      GreaterThanComparator comparator = new GreaterThanComparator();
425      comparator.GetVariableInfo("LeftSide").ActualName = "Generations";
426      comparator.GetVariableInfo("RightSide").ActualName = "MaxGenerations";
427      comparator.GetVariableInfo("Result").ActualName = "TerminationCriterion";
428
429      seq.AddSubOperator(comparator);
430      terminationCriterion.OperatorGraph.AddOperator(seq);
431      terminationCriterion.OperatorGraph.InitialOperator = seq;
432      return terminationCriterion;
433    }
434
435    protected virtual IOperator CreateEvaluationOperator() {
436      return new EmptyOperator();
437    }
438
439    protected virtual IOperator CreateManipulationOperator() {
440      ChangeNodeTypeManipulation manipulator = new ChangeNodeTypeManipulation();
441      manipulator.Name = "Manipulator";
442      return manipulator;
443    }
444
445    protected virtual IOperator CreateCrossoverOperator() {
446      StandardCrossOver crossover = new StandardCrossOver();
447      crossover.Name = "Crossover";
448      return crossover;
449    }
450
451    protected virtual IOperator CreateSelectionOperator() {
452      TournamentSelector selector = new TournamentSelector();
453      selector.GetVariableInfo("Selected").ActualName = "Parents";
454      selector.GetVariable("GroupSize").Value = new IntData(7);
455      selector.Name = "Selector";
456      return selector;
457    }
458
459    #endregion
460
461    protected virtual IOperator CreatePostProcessingOperator() {
462      return new EmptyOperator();
463    }
464
465    protected virtual IOperator GetVariableInjector() {
466      CombinedOperator init = (CombinedOperator)GetInitializationOperator();
467      return init.OperatorGraph.InitialOperator.SubOperators[1];
[1230]468    }
469
[2335]470    protected virtual IOperator GetRandomInjector() {
471      CombinedOperator init = (CombinedOperator)GetInitializationOperator();
472      return init.OperatorGraph.InitialOperator.SubOperators[0];
[1287]473    }
474
[2335]475    protected virtual IOperator GetInitializationOperator() {
[2377]476      CombinedOperator algo = (CombinedOperator)Engine.OperatorGraph.InitialOperator;
477      return algo.OperatorGraph.InitialOperator.SubOperators[0];
[2335]478    }
479
[1230]480    #region Persistence Methods
[2377]481    public override object Clone(IDictionary<Guid, object> clonedObjects) {
482      AlgorithmBase clone = (AlgorithmBase)base.Clone(clonedObjects);
483      clone.engine = (IEngine)Auxiliary.Clone(Engine, clonedObjects);
484      return clone;
485    }
486
[1230]487    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
488      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
489      node.AppendChild(PersistenceManager.Persist("Engine", Engine, document, persistedObjects));
490      return node;
491    }
492    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
493      base.Populate(node, restoredObjects);
[2377]494      engine = (IEngine)PersistenceManager.Restore(node.SelectSingleNode("Engine"), restoredObjects);
[1230]495    }
496    #endregion
[2385]497
498
499    public static IOperator CombineTerminationCriterions(IOperator criterion1, IOperator criterion2) {
500      ConditionalBranch branch = new ConditionalBranch();
501      branch.GetVariableInfo("Condition").ActualName = "TerminationCriterion";
502      branch.AddSubOperator(new EmptyOperator());
503      branch.AddSubOperator(criterion2);
504
505      SequentialProcessor seq = new SequentialProcessor();
506      seq.AddSubOperator(criterion1);
507      seq.AddSubOperator(branch);
508
509      return seq;
510    }
[1230]511  }
512}
Note: See TracBrowser for help on using the repository browser.