#region License Information
/* HeuristicLab
* Copyright (C) 2002-2008 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.Text;
using System.Xml;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.SequentialEngine;
using HeuristicLab.Operators;
using HeuristicLab.Random;
using HeuristicLab.Logging;
using HeuristicLab.Selection;
namespace HeuristicLab.SGA {
public class SGA : ItemBase, IEditable {
#region Create Operators
public static void Create(IEngine engine) {
engine.OperatorGraph.Clear();
CombinedOperator co = CreateSGA();
co.Name = "SGA";
engine.OperatorGraph.AddOperator(co);
engine.OperatorGraph.InitialOperator = co;
engine.Reset();
}
private static CombinedOperator CreateSGA() {
CombinedOperator op = new CombinedOperator();
SequentialProcessor sp = new SequentialProcessor();
op.OperatorGraph.AddOperator(sp);
op.OperatorGraph.InitialOperator = sp;
CombinedOperator co1 = CreateVariableInjection();
co1.Name = "Variable Injection";
op.OperatorGraph.AddOperator(co1);
sp.AddSubOperator(co1);
// place holder for Problem Initializer
EmptyOperator eo1 = new EmptyOperator();
op.OperatorGraph.AddOperator(eo1);
co1.AddSubOperator(eo1);
CombinedOperator co2 = CreatePopulationInitialization();
co2.Name = "Population Initialization";
op.OperatorGraph.AddOperator(co2);
sp.AddSubOperator(co2);
// place holder for Solution Generator
EmptyOperator eo2 = new EmptyOperator();
op.OperatorGraph.AddOperator(eo2);
co2.AddSubOperator(eo2);
// place holder for Evaluator
EmptyOperator eo3 = new EmptyOperator();
op.OperatorGraph.AddOperator(eo3);
co2.AddSubOperator(eo3);
CombinedOperator co3 = CreateSGAMain();
co3.Name = "SGA Main";
op.OperatorGraph.AddOperator(co3);
sp.AddSubOperator(co3);
// place holder for Selector
EmptyOperator eo4 = new EmptyOperator();
op.OperatorGraph.AddOperator(eo4);
co3.AddSubOperator(eo4);
// place holder for Crossover
EmptyOperator eo5 = new EmptyOperator();
op.OperatorGraph.AddOperator(eo5);
co3.AddSubOperator(eo5);
// place holder for Mutator
EmptyOperator eo6 = new EmptyOperator();
op.OperatorGraph.AddOperator(eo6);
co3.AddSubOperator(eo6);
// place holder for Evaluator
co3.AddSubOperator(eo3);
return op;
}
private static CombinedOperator CreateVariableInjection() {
CombinedOperator op = new CombinedOperator();
SequentialProcessor sp = new SequentialProcessor();
op.OperatorGraph.AddOperator(sp);
op.OperatorGraph.InitialOperator = sp;
RandomInjector ri = new RandomInjector();
op.OperatorGraph.AddOperator(ri);
sp.AddSubOperator(ri);
OperatorExtractor oe = new OperatorExtractor();
oe.Name = "Problem Initializer";
oe.GetVariable("Name").GetValue().Data = "ProblemInitializer";
op.OperatorGraph.AddOperator(oe);
sp.AddSubOperator(oe);
VariableInjector vi = new VariableInjector();
vi.AddVariable(new Variable("PopulationSize", new IntData(100)));
vi.AddVariable(new Variable("EvaluatedSolutions", new IntData()));
vi.AddVariable(new Variable("Parents", new IntData(200)));
vi.AddVariable(new Variable("MutationRate", new DoubleData(0.05)));
vi.AddVariable(new Variable("Elites", new IntData(1)));
vi.AddVariable(new Variable("Generations", new IntData()));
vi.AddVariable(new Variable("MaximumGenerations", new IntData(1000)));
op.OperatorGraph.AddOperator(vi);
sp.AddSubOperator(vi);
op.GetVariable("InjectSubOperators").GetValue().Data = true;
op.GetVariable("SubOperatorNames").GetValue().Add(new StringData("ProblemInitializer"));
return op;
}
private static CombinedOperator CreatePopulationInitialization() {
CombinedOperator op = new CombinedOperator();
SequentialProcessor sp1 = new SequentialProcessor();
op.OperatorGraph.AddOperator(sp1);
op.OperatorGraph.InitialOperator = sp1;
SubScopesCreater ssc = new SubScopesCreater();
ssc.GetVariableInfo("SubScopes").ActualName = "PopulationSize";
op.OperatorGraph.AddOperator(ssc);
sp1.AddSubOperator(ssc);
UniformSequentialSubScopesProcessor ussp = new UniformSequentialSubScopesProcessor();
op.OperatorGraph.AddOperator(ussp);
sp1.AddSubOperator(ussp);
SequentialProcessor sp2 = new SequentialProcessor();
op.OperatorGraph.AddOperator(sp2);
ussp.AddSubOperator(sp2);
OperatorExtractor oe1 = new OperatorExtractor();
oe1.Name = "Solution Generator";
oe1.GetVariable("Name").GetValue().Data = "SolutionGenerator";
op.OperatorGraph.AddOperator(oe1);
sp2.AddSubOperator(oe1);
OperatorExtractor oe2 = new OperatorExtractor();
oe2.Name = "Evaluator";
oe2.GetVariable("Name").GetValue().Data = "Evaluator";
op.OperatorGraph.AddOperator(oe2);
sp2.AddSubOperator(oe2);
Counter c = new Counter();
c.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
op.OperatorGraph.AddOperator(c);
sp2.AddSubOperator(c);
Sorter s = new Sorter();
s.GetVariableInfo("Descending").ActualName = "Maximization";
s.GetVariableInfo("Value").ActualName = "Quality";
op.OperatorGraph.AddOperator(s);
sp1.AddSubOperator(s);
op.GetVariable("InjectSubOperators").GetValue().Data = true;
op.GetVariable("SubOperatorNames").GetValue().Add(new StringData("SolutionGenerator"));
op.GetVariable("SubOperatorNames").GetValue().Add(new StringData("Evaluator"));
return op;
}
private static CombinedOperator CreateSGAMain() {
CombinedOperator op = new CombinedOperator();
SequentialProcessor sp = new SequentialProcessor();
op.OperatorGraph.AddOperator(sp);
op.OperatorGraph.InitialOperator = sp;
OperatorExtractor oe = new OperatorExtractor();
oe.Name = "Selector";
oe.GetVariable("Name").GetValue().Data = "Selector";
op.OperatorGraph.AddOperator(oe);
sp.AddSubOperator(oe);
SequentialSubScopesProcessor ssp = new SequentialSubScopesProcessor();
op.OperatorGraph.AddOperator(ssp);
sp.AddSubOperator(ssp);
EmptyOperator eo = new EmptyOperator();
op.OperatorGraph.AddOperator(eo);
ssp.AddSubOperator(eo);
CombinedOperator co1 = CreateCreateChildren();
co1.Name = "Create Children";
op.OperatorGraph.AddOperator(co1);
ssp.AddSubOperator(co1);
CombinedOperator co2 = CreateReplacement();
co2.Name = "Replacement";
op.OperatorGraph.AddOperator(co2);
sp.AddSubOperator(co2);
QualityLogger ql = new QualityLogger();
op.OperatorGraph.AddOperator(ql);
sp.AddSubOperator(ql);
BestAverageWorstQualityCalculator bawqc = new BestAverageWorstQualityCalculator();
op.OperatorGraph.AddOperator(bawqc);
sp.AddSubOperator(bawqc);
DataCollector dc = new DataCollector();
ItemList names = dc.GetVariable("VariableNames").GetValue();
names.Add(new StringData("BestQuality"));
names.Add(new StringData("AverageQuality"));
names.Add(new StringData("WorstQuality"));
op.OperatorGraph.AddOperator(dc);
sp.AddSubOperator(dc);
LinechartInjector lci = new LinechartInjector();
lci.GetVariableInfo("Linechart").ActualName = "Quality Linechart";
lci.GetVariable("NumberOfLines").GetValue().Data = 3;
op.OperatorGraph.AddOperator(lci);
sp.AddSubOperator(lci);
Counter c = new Counter();
c.GetVariableInfo("Value").ActualName = "Generations";
op.OperatorGraph.AddOperator(c);
sp.AddSubOperator(c);
LessThanComparator ltc = new LessThanComparator();
ltc.GetVariableInfo("LeftSide").ActualName = "Generations";
ltc.GetVariableInfo("RightSide").ActualName = "MaximumGenerations";
ltc.GetVariableInfo("Result").ActualName = "GenerationsCondition";
op.OperatorGraph.AddOperator(ltc);
sp.AddSubOperator(ltc);
ConditionalBranch cb = new ConditionalBranch();
cb.GetVariableInfo("Condition").ActualName = "GenerationsCondition";
op.OperatorGraph.AddOperator(cb);
sp.AddSubOperator(cb);
cb.AddSubOperator(sp);
op.GetVariable("InjectSubOperators").GetValue().Data = true;
op.GetVariable("SubOperatorNames").GetValue().Add(new StringData("Selector"));
op.GetVariable("SubOperatorNames").GetValue().Add(new StringData("Crossover"));
op.GetVariable("SubOperatorNames").GetValue().Add(new StringData("Mutator"));
op.GetVariable("SubOperatorNames").GetValue().Add(new StringData("Evaluator"));
return op;
}
private static CombinedOperator CreateCreateChildren() {
CombinedOperator op = new CombinedOperator();
SequentialProcessor sp1 = new SequentialProcessor();
op.OperatorGraph.AddOperator(sp1);
op.OperatorGraph.InitialOperator = sp1;
OperatorExtractor oe1 = new OperatorExtractor();
oe1.Name = "Crossover";
oe1.GetVariable("Name").GetValue().Data = "Crossover";
op.OperatorGraph.AddOperator(oe1);
sp1.AddSubOperator(oe1);
UniformSequentialSubScopesProcessor ussp = new UniformSequentialSubScopesProcessor();
op.OperatorGraph.AddOperator(ussp);
sp1.AddSubOperator(ussp);
SequentialProcessor sp2 = new SequentialProcessor();
op.OperatorGraph.AddOperator(sp2);
ussp.AddSubOperator(sp2);
StochasticBranch hb = new StochasticBranch();
hb.GetVariableInfo("Probability").ActualName = "MutationRate";
op.OperatorGraph.AddOperator(hb);
sp2.AddSubOperator(hb);
OperatorExtractor oe2 = new OperatorExtractor();
oe2.Name = "Mutator";
oe2.GetVariable("Name").GetValue().Data = "Mutator";
op.OperatorGraph.AddOperator(oe2);
hb.AddSubOperator(oe2);
OperatorExtractor oe3 = new OperatorExtractor();
oe3.Name = "Evaluator";
oe3.GetVariable("Name").GetValue().Data = "Evaluator";
op.OperatorGraph.AddOperator(oe3);
sp2.AddSubOperator(oe3);
Counter c = new Counter();
c.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
op.OperatorGraph.AddOperator(c);
sp2.AddSubOperator(c);
Sorter s = new Sorter();
s.GetVariableInfo("Descending").ActualName = "Maximization";
s.GetVariableInfo("Value").ActualName = "Quality";
op.OperatorGraph.AddOperator(s);
sp1.AddSubOperator(s);
return op;
}
private static CombinedOperator CreateReplacement() {
CombinedOperator op = new CombinedOperator();
SequentialProcessor sp1 = new SequentialProcessor();
op.OperatorGraph.AddOperator(sp1);
op.OperatorGraph.InitialOperator = sp1;
SequentialSubScopesProcessor ssp = new SequentialSubScopesProcessor();
op.OperatorGraph.AddOperator(ssp);
sp1.AddSubOperator(ssp);
SequentialProcessor sp2 = new SequentialProcessor();
op.OperatorGraph.AddOperator(sp2);
ssp.AddSubOperator(sp2);
LeftSelector ls = new LeftSelector();
ls.GetVariableInfo("Selected").ActualName = "Elites";
op.OperatorGraph.AddOperator(ls);
sp2.AddSubOperator(ls);
RightReducer rr = new RightReducer();
op.OperatorGraph.AddOperator(rr);
sp2.AddSubOperator(rr);
SequentialProcessor sp3 = new SequentialProcessor();
op.OperatorGraph.AddOperator(sp3);
ssp.AddSubOperator(sp3);
RightSelector rs = new RightSelector();
rs.GetVariableInfo("Selected").ActualName = "Elites";
op.OperatorGraph.AddOperator(rs);
sp3.AddSubOperator(rs);
LeftReducer lr = new LeftReducer();
op.OperatorGraph.AddOperator(lr);
sp3.AddSubOperator(lr);
MergingReducer mr = new MergingReducer();
op.OperatorGraph.AddOperator(mr);
sp1.AddSubOperator(mr);
Sorter s = new Sorter();
s.GetVariableInfo("Descending").ActualName = "Maximization";
s.GetVariableInfo("Value").ActualName = "Quality";
op.OperatorGraph.AddOperator(s);
sp1.AddSubOperator(s);
return op;
}
#endregion
#region Properties
private IEngine myEngine;
public IEngine Engine {
get { return myEngine; }
}
private BoolData mySetSeedRandomly;
public bool SetSeedRandomly {
get { return mySetSeedRandomly.Data; }
set { mySetSeedRandomly.Data = value; }
}
private IntData mySeed;
public int Seed {
get { return mySeed.Data; }
set { mySeed.Data = value; }
}
private IntData myPopulationSize;
private IntData myParents;
public int PopulationSize {
get { return myPopulationSize.Data; }
set {
myPopulationSize.Data = value;
myParents.Data = value * 2;
}
}
private IntData myMaximumGenerations;
public int MaximumGenerations {
get { return myMaximumGenerations.Data; }
set { myMaximumGenerations.Data = value; }
}
private DoubleData myMutationRate;
public double MutationRate {
get { return myMutationRate.Data; }
set { myMutationRate.Data = value; }
}
private IntData myElites;
public int Elites {
get { return myElites.Data; }
set { myElites.Data = value; }
}
private CombinedOperator mySGA;
private IOperator myVariableInjection;
public IOperator ProblemInitializer {
get { return myVariableInjection.SubOperators[0]; }
set {
mySGA.OperatorGraph.RemoveOperator(ProblemInitializer.Guid);
mySGA.OperatorGraph.AddOperator(value);
myVariableInjection.AddSubOperator(value, 0);
}
}
private IOperator myPopulationInitialization;
public IOperator SolutionGenerator {
get { return myPopulationInitialization.SubOperators[0]; }
set {
mySGA.OperatorGraph.RemoveOperator(SolutionGenerator.Guid);
mySGA.OperatorGraph.AddOperator(value);
myPopulationInitialization.AddSubOperator(value, 0);
}
}
public IOperator Evaluator {
get { return myPopulationInitialization.SubOperators[1]; }
set {
mySGA.OperatorGraph.RemoveOperator(Evaluator.Guid);
mySGA.OperatorGraph.AddOperator(value);
myPopulationInitialization.AddSubOperator(value, 1);
mySGAMain.AddSubOperator(value, 3);
}
}
private IOperator mySGAMain;
public IOperator Selector {
get { return mySGAMain.SubOperators[0]; }
set {
mySGA.OperatorGraph.RemoveOperator(Selector.Guid);
mySGA.OperatorGraph.AddOperator(value);
mySGAMain.AddSubOperator(value, 0);
}
}
public IOperator Crossover {
get { return mySGAMain.SubOperators[1]; }
set {
mySGA.OperatorGraph.RemoveOperator(Crossover.Guid);
mySGA.OperatorGraph.AddOperator(value);
mySGAMain.AddSubOperator(value, 1);
}
}
public IOperator Mutator {
get { return mySGAMain.SubOperators[2]; }
set {
mySGA.OperatorGraph.RemoveOperator(Mutator.Guid);
mySGA.OperatorGraph.AddOperator(value);
mySGAMain.AddSubOperator(value, 2);
}
}
#endregion
public SGA() {
myEngine = new SequentialEngine.SequentialEngine();
Create(myEngine);
SetReferences();
}
public override IView CreateView() {
return new SGAEditor(this);
}
public virtual IEditor CreateEditor() {
return new SGAEditor(this);
}
public override object Clone(IDictionary clonedObjects) {
SGA clone = new SGA();
clonedObjects.Add(Guid, clone);
clone.myEngine = (IEngine)Auxiliary.Clone(Engine, clonedObjects);
return clone;
}
#region SetReferences Method
private void SetReferences() {
// SGA
CombinedOperator co1 = (CombinedOperator)Engine.OperatorGraph.InitialOperator;
mySGA = co1;
// SequentialProcessor in SGA
SequentialProcessor sp1 = (SequentialProcessor)co1.OperatorGraph.InitialOperator;
// Variable Injection
CombinedOperator co2 = (CombinedOperator)sp1.SubOperators[0];
myVariableInjection = co2;
// SequentialProcessor in Variable Injection
SequentialProcessor sp2 = (SequentialProcessor)co2.OperatorGraph.InitialOperator;
// RandomInjector
RandomInjector ri = (RandomInjector)sp2.SubOperators[0];
mySetSeedRandomly = ri.GetVariable("SetSeedRandomly").GetValue();
mySeed = ri.GetVariable("Seed").GetValue();
// VariableInjector
VariableInjector vi = (VariableInjector)sp2.SubOperators[2];
myPopulationSize = vi.GetVariable("PopulationSize").GetValue();
myParents = vi.GetVariable("Parents").GetValue();
myMaximumGenerations = vi.GetVariable("MaximumGenerations").GetValue();
myMutationRate = vi.GetVariable("MutationRate").GetValue();
myElites = vi.GetVariable("Elites").GetValue();
// Population Initialization
CombinedOperator co3 = (CombinedOperator)sp1.SubOperators[1];
myPopulationInitialization = co3;
// SGA Main
CombinedOperator co4 = (CombinedOperator)sp1.SubOperators[2];
mySGAMain = co4;
}
#endregion
#region Persistence Methods
public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary persistedObjects) {
XmlNode node = base.GetXmlNode(name, document, persistedObjects);
node.AppendChild(PersistenceManager.Persist("Engine", Engine, document, persistedObjects));
return node;
}
public override void Populate(XmlNode node, IDictionary restoredObjects) {
base.Populate(node, restoredObjects);
myEngine = (IEngine)PersistenceManager.Restore(node.SelectSingleNode("Engine"), restoredObjects);
SetReferences();
}
#endregion
}
}