Index: branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/SolutionSamplingOperator.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/SolutionSamplingOperator.cs	(revision 14776)
+++ branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/SolutionSamplingOperator.cs	(revision 14776)
@@ -0,0 +1,75 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding.SolutionModel {
+  [Item("Solution Sampling Operator", "Creates new solutions by sampling from a given model.")]
+  [StorableClass]
+  public class SolutionSamplingOperator : InstrumentedOperator {
+    
+    public ILookupParameter<UnivariateModel> ModelParameter {
+      get { return (ILookupParameter<UnivariateModel>)Parameters["Model"]; }
+    }
+
+    public IValueLookupParameter<IntValue> NumberOfSampledSolutionsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["NumberOfSampledSolutions"]; }
+    }
+
+    public ILookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+
+    [StorableConstructor]
+    protected SolutionSamplingOperator(bool deserializing) : base() { }
+    protected SolutionSamplingOperator(SolutionSamplingOperator original, Cloner cloner)
+      : base(original, cloner) { }
+    public SolutionSamplingOperator() {
+      Parameters.Add(new LookupParameter<UnivariateModel>("Model", "The model that is being trained by this operator."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("NumberOfSampledSolutions", "The amount of solutions that should be created through sampling."));
+      Parameters.Add(new LookupParameter<BinaryVector>("BinaryVector", "The vector which should be manipulated."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SolutionSamplingOperator(this, cloner);
+    }
+
+    public override IOperation InstrumentedApply() {
+      var model = ModelParameter.ActualValue;
+      var samples = NumberOfSampledSolutionsParameter.ActualValue.Value;
+      var solutionName = BinaryVectorParameter.TranslatedName;
+      var scope = ExecutionContext.Scope;
+      for (var i = 0; i < samples; i++) {
+        var solution = model.Sample();
+        var solutionScope = new Scope(scope.SubScopes.Count.ToString());
+        solutionScope.Variables.Add(new Variable(solutionName, solution));
+        scope.SubScopes.Add(solutionScope);
+      }
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/BiasedModelTrainer.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/BiasedModelTrainer.cs	(revision 14666)
+++ 	(revision )
@@ -1,65 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Linq;
-using HeuristicLab.Algorithms.MemPR.Interfaces;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.BinaryVectorEncoding;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Algorithms.MemPR.Binary.SolutionModel.Univariate {
-  [Item("Biased Univariate Model Trainer (binary)", "", ExcludeGenericTypeInfo = true)]
-  [StorableClass]
-  public class BiasedModelTrainer<TContext> : ParameterizedNamedItem, ISolutionModelTrainer<TContext>
-    where TContext : IPopulationBasedHeuristicAlgorithmContext<ISingleObjectiveHeuristicOptimizationProblem, BinaryVector>, ISolutionModelContext<BinaryVector> {
-    
-    public bool Bias { get { return true; } }
-
-    [Storable]
-    private IValueParameter<EnumValue<ModelBiasOptions>> modelBiasParameter;
-    public ModelBiasOptions ModelBias {
-      get { return modelBiasParameter.Value.Value; }
-      set { modelBiasParameter.Value.Value = value; }
-    }
-
-    [StorableConstructor]
-    protected BiasedModelTrainer(bool deserializing) : base(deserializing) { }
-    protected BiasedModelTrainer(BiasedModelTrainer<TContext> original, Cloner cloner)
-      : base(original, cloner) {
-      modelBiasParameter = cloner.Clone(original.modelBiasParameter);
-    }
-    public BiasedModelTrainer() {
-      Parameters.Add(modelBiasParameter = new ValueParameter<EnumValue<ModelBiasOptions>>("Model Bias", "What kind of bias towards better individuals is chosen."));
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new BiasedModelTrainer<TContext>(this, cloner);
-    }
-
-    public void TrainModel(TContext context) {
-      context.Model = Trainer.TrainBiased(ModelBias, context.Random, context.Maximization, context.Population.Select(x => x.Solution), context.Population.Select(x => x.Fitness));
-    }
-  }
-}
Index: branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnbiasedModelTrainer.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnbiasedModelTrainer.cs	(revision 14666)
+++ 	(revision )
@@ -1,54 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Linq;
-using HeuristicLab.Algorithms.MemPR.Interfaces;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.BinaryVectorEncoding;
-using HeuristicLab.Optimization;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Algorithms.MemPR.Binary.SolutionModel.Univariate {
-  [Item("Unbiased Univariate Model Trainer (binary)", "", ExcludeGenericTypeInfo = true)]
-  [StorableClass]
-  public class UniasedModelTrainer<TContext> : NamedItem, ISolutionModelTrainer<TContext>
-    where TContext : IPopulationBasedHeuristicAlgorithmContext<ISingleObjectiveHeuristicOptimizationProblem, BinaryVector>, ISolutionModelContext<BinaryVector> {
-
-    public bool Bias { get { return false; } }
-
-    [StorableConstructor]
-    protected UniasedModelTrainer(bool deserializing) : base(deserializing) { }
-    protected UniasedModelTrainer(UniasedModelTrainer<TContext> original, Cloner cloner) : base(original, cloner) { }
-    public UniasedModelTrainer() {
-      Name = ItemName;
-      Description = ItemDescription;
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new UniasedModelTrainer<TContext>(this, cloner);
-    }
-
-    public void TrainModel(TContext context) {
-      context.Model = Trainer.TrainUnbiased(context.Random, context.Population.Select(x => x.Solution));
-    }
-  }
-}
Index: branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModel.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModel.cs	(revision 14776)
+++ branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModel.cs	(revision 14776)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding.SolutionModel {
+  [Item("Univariate solution model (binary)", "")]
+  [StorableClass]
+  public sealed class UnivariateModel : Item, ISolutionModel<BinaryVector> {
+    [Storable]
+    public DoubleArray Probabilities { get; set; }
+    [Storable]
+    public IRandom Random { get; set; }
+
+    [StorableConstructor]
+    private UnivariateModel(bool deserializing) : base(deserializing) { }
+    private UnivariateModel(UnivariateModel original, Cloner cloner)
+      : base(original, cloner) {
+      Probabilities = cloner.Clone(original.Probabilities);
+      Random = cloner.Clone(original.Random);
+    }
+    public UnivariateModel(IRandom random, int N) : this(random, Enumerable.Range(0, N).Select(x => 0.5).ToArray()) { }
+    public UnivariateModel(IRandom random, double[] probabilities) {
+      Probabilities = new DoubleArray(probabilities);
+      Random = random;
+    }
+    public UnivariateModel(IRandom random, DoubleArray probabilties) {
+      Probabilities = probabilties;
+      Random = random;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UnivariateModel(this, cloner);
+    }
+
+    public BinaryVector Sample() {
+      var vec = new BinaryVector(Probabilities.Length);
+      for (var i = 0; i < Probabilities.Length; i++)
+        vec[i] = Random.NextDouble() < Probabilities[i];
+      return vec;
+    }
+  }
+}
Index: branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainer.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainer.cs	(revision 14776)
+++ branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainer.cs	(revision 14776)
@@ -0,0 +1,146 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding.SolutionModel {
+  public static class UnivariateModelTrainer {
+    /// <summary>
+    /// Creates a univariate sampling model out of a ranked population.
+    /// The first solution in <paramref name="rankedPopulation"/> is the 
+    /// highest influential one, the last solution has the least influence.
+    /// </summary>
+    /// <param name="random">The model is stochastic and will use this RNG for sampling.</param>
+    /// <param name="maximization">Whether higher or lower qualities are better</param>
+    /// <param name="population">The population that is ranked from highest influential to least influential, e.g. best to worst.</param>
+    /// <param name="qualities">The solution quality of the respective solution.</param>
+    /// <returns>The sampling model which is created with the given population.</returns>
+    public static UnivariateModel TrainWithRankBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {
+      var popSize = 0;
+      double[] model = null;
+      var pop = population.Zip(qualities, (b, q) => new { Solution = b, Fitness = q });
+      foreach (var ind in maximization ? pop.OrderBy(x => x.Fitness) : pop.OrderByDescending(x => x.Fitness)) {
+        // from worst to best, worst solution has 1 vote, best solution N votes
+        popSize++;
+        if (model == null) model = new double[ind.Solution.Length];
+        for (var x = 0; x < model.Length; x++) {
+          if (ind.Solution[x]) model[x] += popSize;
+        }
+      }
+      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
+      // normalize to [0;1]
+      var factor = 2.0 / (popSize + 1);
+      for (var i = 0; i < model.Length; i++) {
+        model[i] *= factor / popSize;
+      }
+      return new UnivariateModel(random, model);
+    }
+
+    /// <summary>
+    /// Creates a univariate sampling model out of solutions and their given fitness.
+    /// The best solution's influence is proportional to its fitness, while the worst
+    /// solution does not have an influence at all (except if the fitness of worst and
+    /// best are equal).
+    /// </summary>
+    /// <param name="random">The model is stochastic and makes use of this RNG instance for sampling.</param>
+    /// <param name="maximization">Whether higher fitness values are better or lower ones.</param>
+    /// <param name="population">The solutions that will be used to create the model.</param>
+    /// <param name="qualities">The solutions' associated qualities.</param>
+    /// <returns>The sampling model which is created with the given population.</returns>
+    public static UnivariateModel TrainWithFitnessBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {
+      var proportions = PrepareProportional(qualities, true, !maximization);
+      var factor = 1.0 / proportions.Sum();
+      double[] model = null;
+      foreach (var ind in population.Zip(proportions, (p, q) => new { Solution = p, Proportion = q })) {
+        if (model == null) model = new double[ind.Solution.Length];
+        for (var x = 0; x < model.Length; x++) {
+          if (ind.Solution[x]) model[x] += ind.Proportion * factor;
+        }
+      }
+      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
+      return new UnivariateModel(random, model);
+    }
+
+    /// <summary>
+    /// Creates a univariate sampling model out of solutions. Each of the solutions
+    /// has the same influence on the model.
+    /// </summary>
+    /// <param name="random">The model is stochastic and will make use of this RNG instance.</param>
+    /// <param name="population">The solutions that are used to create the model.</param>
+    /// <returns>The model created from the population.</returns>
+    public static UnivariateModel TrainUnbiased(IRandom random, IEnumerable<BinaryVector> population) {
+      double[] model = null;
+      var popSize = 0;
+      foreach (var p in population) {
+        popSize++;
+        if (model == null) model = new double[p.Length];
+        for (var x = 0; x < model.Length; x++) {
+          if (p[x]) model[x]++;
+        }
+      }
+      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
+      // normalize to [0;1]
+      var factor = 1.0 / popSize;
+      for (var x = 0; x < model.Length; x++) {
+        model[x] *= factor;
+      }
+      return new UnivariateModel(random, model);
+    }
+
+    // TODO: make PrepareProportional public in EnumerableExtensions
+    private static double[] PrepareProportional(IEnumerable<double> weights, bool windowing, bool inverseProportional) {
+      double maxValue = double.MinValue, minValue = double.MaxValue;
+      double[] valueArray = weights.ToArray();
+
+      for (int i = 0; i < valueArray.Length; i++) {
+        if (valueArray[i] > maxValue) maxValue = valueArray[i];
+        if (valueArray[i] < minValue) minValue = valueArray[i];
+      }
+      if (minValue == maxValue) {  // all values are equal
+        for (int i = 0; i < valueArray.Length; i++) {
+          valueArray[i] = 1.0;
+        }
+      } else {
+        if (windowing) {
+          if (inverseProportional) InverseProportionalScale(valueArray, maxValue);
+          else ProportionalScale(valueArray, minValue);
+        } else {
+          if (minValue < 0.0) throw new InvalidOperationException("Proportional selection without windowing does not work with values < 0.");
+          if (inverseProportional) InverseProportionalScale(valueArray, 2 * maxValue);
+        }
+      }
+      return valueArray;
+    }
+    private static void ProportionalScale(double[] values, double minValue) {
+      for (int i = 0; i < values.Length; i++) {
+        values[i] = values[i] - minValue;
+      }
+    }
+    private static void InverseProportionalScale(double[] values, double maxValue) {
+      for (int i = 0; i < values.Length; i++) {
+        values[i] = maxValue - values[i];
+      }
+    }
+  }
+}
Index: branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainingOperator.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainingOperator.cs	(revision 14776)
+++ branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateModelTrainingOperator.cs	(revision 14776)
@@ -0,0 +1,118 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding.SolutionModel {
+  public enum ModelBiasOptions {
+    Unbiased,
+    RankBiased,
+    FitnessBiased
+  };
+
+  [Item("Univariate Model Training Operator", "Adds a univariate solution sampling model to the scope.")]
+  [StorableClass]
+  public class UnivariateModelTrainingOperator : InstrumentedOperator, IStochasticOperator, ISingleObjectiveOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public IScopeTreeLookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (IScopeTreeLookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+
+    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<UnivariateModel> ModelParameter {
+      get { return (ILookupParameter<UnivariateModel>)Parameters["Model"]; }
+    }
+
+    public IValueParameter<EnumValue<ModelBiasOptions>> ModelBiasParameter {
+      get { return (IValueParameter<EnumValue<ModelBiasOptions>>)Parameters["ModelBias"]; }
+    }
+
+    public ModelBiasOptions ModelBias {
+      get { return ModelBiasParameter.Value.Value; }
+      set { ModelBiasParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected UnivariateModelTrainingOperator(bool deserializing) : base() { }
+    protected UnivariateModelTrainingOperator(UnivariateModelTrainingOperator original, Cloner cloner)
+      : base(original, cloner) { }
+    public UnivariateModelTrainingOperator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use for sampling from the model."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "Whether or not solution qualities are to be maximized."));
+      Parameters.Add(new ScopeTreeLookupParameter<BinaryVector>("BinaryVector", "The population of solutions to create the model."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The fitness values of the solutions."));
+      Parameters.Add(new LookupParameter<UnivariateModel>("Model", "The model that is being trained by this operator."));
+      Parameters.Add(new ValueParameter<EnumValue<ModelBiasOptions>>("ModelBias", "The type of bias that is used to created the model.", new EnumValue<ModelBiasOptions>(ModelBiasOptions.Unbiased)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UnivariateModelTrainingOperator(this, cloner);
+    }
+
+    public override IOperation InstrumentedApply() {
+      var random = RandomParameter.ActualValue;
+      var population = BinaryVectorParameter.ActualValue;
+      var biasType = ModelBiasParameter.Value.Value;
+      UnivariateModel model = null;
+      switch (biasType) {
+        case ModelBiasOptions.Unbiased:
+          model = UnivariateModelTrainer.TrainUnbiased(random, population);
+          break;
+        case ModelBiasOptions.RankBiased: {
+            var qualities = QualityParameter.ActualValue;
+            var maximization = MaximizationParameter.ActualValue.Value;
+            model = UnivariateModelTrainer.TrainWithRankBias(random, maximization, population,
+              qualities.Select(x => x.Value));
+          }
+          break;
+        case ModelBiasOptions.FitnessBiased: {
+            var qualities = QualityParameter.ActualValue;
+            var maximization = MaximizationParameter.ActualValue.Value;
+            model = UnivariateModelTrainer.TrainWithFitnessBias(random, maximization, population,
+              qualities.Select(x => x.Value));
+          }
+          break;
+        default: throw new InvalidOperationException(string.Format("Unknown bias type {0}", biasType));
+      }
+      ModelParameter.ActualValue = model;
+      return base.InstrumentedApply();
+    }
+  }
+}
Index: branches/PerformanceComparison/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/SolutionModel/Univariate/UnivariateSolutionModel.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnivariateSolutionModel.cs	(revision 14666)
+++ 	(revision )
@@ -1,125 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 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 <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Algorithms.MemPR.Interfaces;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.BinaryVectorEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Random;
-
-namespace HeuristicLab.Algorithms.MemPR.Binary.SolutionModel.Univariate {
-  [Item("Univariate solution model (binary)", "")]
-  [StorableClass]
-  public sealed class UnivariateModel : Item, ISolutionModel<BinaryVector> {
-    [Storable]
-    public DoubleArray Probabilities { get; set; }
-    [Storable]
-    public IRandom Random { get; set; }
-
-    [StorableConstructor]
-    private UnivariateModel(bool deserializing) : base(deserializing) { }
-    private UnivariateModel(UnivariateModel original, Cloner cloner)
-      : base(original, cloner) {
-      Probabilities = cloner.Clone(original.Probabilities);
-      Random = cloner.Clone(original.Random);
-    }
-    public UnivariateModel(IRandom random, int N) : this(random, Enumerable.Range(0, N).Select(x => 0.5).ToArray()) { }
-    public UnivariateModel(IRandom random, double[] probabilities) {
-      Probabilities = new DoubleArray(probabilities);
-      Random = random;
-    }
-    public UnivariateModel(IRandom random, DoubleArray probabilties) {
-      Probabilities = probabilties;
-      Random = random;
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new UnivariateModel(this, cloner);
-    }
-
-    public BinaryVector Sample() {
-      var vec = new BinaryVector(Probabilities.Length);
-      for (var i = 0; i < Probabilities.Length; i++)
-        vec[i] = Random.NextDouble() < Probabilities[i];
-      return vec;
-    }
-
-    public static ISolutionModel<BinaryVector> CreateWithoutBias(IRandom random, IEnumerable<BinaryVector> population) {
-      double[] model = null;
-      var popSize = 0;
-      foreach (var p in population) {
-        popSize++;
-        if (model == null) model = new double[p.Length];
-        for (var x = 0; x < model.Length; x++) {
-          if (p[x]) model[x]++;
-        }
-      }
-      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
-      // normalize to [0;1]
-      var factor = 1.0 / popSize;
-      for (var x = 0; x < model.Length; x++) {
-        model[x] *= factor;
-      }
-      return new UnivariateModel(random, model);
-    }
-
-    public static ISolutionModel<BinaryVector> CreateWithRankBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {
-      var popSize = 0;
-
-      double[] model = null;
-      var pop = population.Zip(qualities, (b, q) => new { Solution = b, Fitness = q });
-      foreach (var ind in maximization ? pop.OrderBy(x => x.Fitness) : pop.OrderByDescending(x => x.Fitness)) {
-        // from worst to best, worst solution has 1 vote, best solution N votes
-        popSize++;
-        if (model == null) model = new double[ind.Solution.Length];
-        for (var x = 0; x < model.Length; x++) {
-          if (ind.Solution[x]) model[x] += popSize;
-        }
-      }
-      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
-      // normalize to [0;1]
-      var factor = 2.0 / (popSize + 1);
-      for (var i = 0; i < model.Length; i++) {
-        model[i] *= factor / popSize;
-      }
-      return new UnivariateModel(random, model);
-    }
-
-    public static ISolutionModel<BinaryVector> CreateWithFitnessBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {
-      var proportions = Util.Auxiliary.PrepareProportional(qualities, true, !maximization);
-      var factor = 1.0 / proportions.Sum();
-      double[] model = null;
-      foreach (var ind in population.Zip(proportions, (p, q) => new { Solution = p, Proportion = q })) {
-        if (model == null) model = new double[ind.Solution.Length];
-        for (var x = 0; x < model.Length; x++) {
-          if (ind.Solution[x]) model[x] += ind.Proportion * factor;
-        }
-      }
-      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
-      return new UnivariateModel(random, model);
-    }
-  }
-}
