Index: /trunk/sources/HeuristicLab.Common.Resources/3.2/HeuristicLabCommonResourcesPlugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Common.Resources/3.2/HeuristicLabCommonResourcesPlugin.cs.frame	(revision 3417)
+++ /trunk/sources/HeuristicLab.Common.Resources/3.2/HeuristicLabCommonResourcesPlugin.cs.frame	(revision 3418)
@@ -25,5 +25,5 @@
 using HeuristicLab.PluginInfrastructure;
 
-namespace HeuristicLab.Communication.Data {
+namespace HeuristicLab.Common.Resources {
   [Plugin("HeuristicLab.Common.Resources", "3.2.0.$WCREV$")]
   [PluginFile("HeuristicLab.Common.Resources-3.2.dll", PluginFileType.Assembly)]
Index: /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj	(revision 3417)
+++ /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj	(revision 3418)
@@ -135,4 +135,8 @@
       <Name>HeuristicLab.Operators-3.3</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization.Operators\3.3\HeuristicLab.Optimization.Operators-3.3.csproj">
+      <Project>{25087811-F74C-4128-BC86-8324271DA13E}</Project>
+      <Name>HeuristicLab.Optimization.Operators-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
       <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
Index: /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLabEncodingsBinaryVectorEncodingPlugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLabEncodingsBinaryVectorEncodingPlugin.cs.frame	(revision 3417)
+++ /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLabEncodingsBinaryVectorEncodingPlugin.cs.frame	(revision 3418)
@@ -34,4 +34,5 @@
   [PluginDependency("HeuristicLab.Operators", "3.3")]
   [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
   [PluginDependency("HeuristicLab.Parameters", "3.3")]
   [PluginDependency("HeuristicLab.Persistence", "3.3")]
Index: /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveTabuMaker.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveTabuMaker.cs	(revision 3417)
+++ /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Moves/OneBitflipMove/OneBitflipMoveTabuMaker.cs	(revision 3418)
@@ -26,4 +26,5 @@
 using HeuristicLab.Operators;
 using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/PermutationMultiCrossover.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/PermutationMultiCrossover.cs	(revision 3418)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Crossovers/PermutationMultiCrossover.cs	(revision 3418)
@@ -0,0 +1,78 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Encodings.PermutationEncoding.Crossovers {
+  public class PermutationMultiCrossover : MultiCrossover<IPermutationCrossover>, IPermutationCrossover {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<ItemArray<Permutation>> ParentsParameter {
+      get { return (ILookupParameter<ItemArray<Permutation>>)Parameters["Parents"]; }
+    }
+
+    public ILookupParameter<Permutation> ChildParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Child"]; }
+    }
+
+    [StorableConstructor]
+    private PermutationMultiCrossover(bool deserializing) : base(deserializing) { }
+    public PermutationMultiCrossover()
+      : base() {
+      Parameters.Add(new SubScopesLookupParameter<Permutation>("Parents", "The parent permutations which should be crossed."));
+      ParentsParameter.ActualName = "Permutation";
+      Parameters.Add(new LookupParameter<Permutation>("Child", "The child permutation resulting from the crossover."));
+      ChildParameter.ActualName = "Permutation";
+
+      Initialize();
+      ParameterizeCrossovers();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void Initialize() {
+      Operators.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IPermutationCrossover>>(Operators_ItemsAdded);
+    }
+
+    private void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IPermutationCrossover>> e) {
+      ParameterizeCrossovers();
+    }
+
+    private void ParameterizeCrossovers() {
+      foreach (IPermutationCrossover crossover in Operators) {
+        crossover.ChildParameter.ActualName = ChildParameter.Name;
+        crossover.ParentsParameter.ActualName = ParentsParameter.Name;
+      }
+      foreach (IStochasticOperator crossover in Operators) {
+        crossover.RandomParameter.ActualName = RandomParameter.Name;
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 3417)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 3418)
@@ -91,4 +91,5 @@
     <Compile Include="Crossovers\OrderCrossover2.cs" />
     <Compile Include="Crossovers\PartiallyMatchedCrossover.cs" />
+    <Compile Include="Crossovers\PermutationMultiCrossover.cs" />
     <Compile Include="Crossovers\PositionBasedCrossover.cs" />
     <Compile Include="HeuristicLabEncodingsPermutationEncodingPlugin.cs" />
@@ -169,4 +170,8 @@
       <Name>HeuristicLab.Operators-3.3</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization.Operators\3.3\HeuristicLab.Optimization.Operators-3.3.csproj">
+      <Project>{25087811-F74C-4128-BC86-8324271DA13E}</Project>
+      <Name>HeuristicLab.Optimization.Operators-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
       <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLabEncodingsPermutationEncodingPlugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLabEncodingsPermutationEncodingPlugin.cs.frame	(revision 3417)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLabEncodingsPermutationEncodingPlugin.cs.frame	(revision 3418)
@@ -34,4 +34,5 @@
   [PluginDependency("HeuristicLab.Operators", "3.3")]
   [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
   [PluginDependency("HeuristicLab.Parameters", "3.3")]
   [PluginDependency("HeuristicLab.Persistence", "3.3")]
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveTabuMaker.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveTabuMaker.cs	(revision 3417)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveTabuMaker.cs	(revision 3418)
@@ -26,4 +26,5 @@
 using HeuristicLab.Operators;
 using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveTabuMaker.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveTabuMaker.cs	(revision 3417)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoOpt/InversionMoveTabuMaker.cs	(revision 3418)
@@ -26,4 +26,5 @@
 using HeuristicLab.Operators;
 using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
Index: /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/HeuristicLab.Encodings.RealVectorEncoding-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/HeuristicLab.Encodings.RealVectorEncoding-3.3.csproj	(revision 3417)
+++ /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/HeuristicLab.Encodings.RealVectorEncoding-3.3.csproj	(revision 3418)
@@ -157,4 +157,8 @@
       <Name>HeuristicLab.Operators-3.3</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization.Operators\3.3\HeuristicLab.Optimization.Operators-3.3.csproj">
+      <Project>{25087811-F74C-4128-BC86-8324271DA13E}</Project>
+      <Name>HeuristicLab.Optimization.Operators-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
       <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
Index: /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/HeuristicLabEncodingsRealVectorEncodingPlugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/HeuristicLabEncodingsRealVectorEncodingPlugin.cs.frame	(revision 3417)
+++ /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/HeuristicLabEncodingsRealVectorEncodingPlugin.cs.frame	(revision 3418)
@@ -34,4 +34,5 @@
   [PluginDependency("HeuristicLab.Operators", "3.3")]
   [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
   [PluginDependency("HeuristicLab.Parameters", "3.3")]
   [PluginDependency("HeuristicLab.Persistence", "3.3")]
Index: /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Moves/AdditiveMoveTabuMaker.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Moves/AdditiveMoveTabuMaker.cs	(revision 3417)
+++ /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Moves/AdditiveMoveTabuMaker.cs	(revision 3418)
@@ -26,4 +26,5 @@
 using HeuristicLab.Operators;
 using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
Index: /trunk/sources/HeuristicLab.Operators/3.3/HeuristicLab.Operators-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Operators/3.3/HeuristicLab.Operators-3.3.csproj	(revision 3417)
+++ /trunk/sources/HeuristicLab.Operators/3.3/HeuristicLab.Operators-3.3.csproj	(revision 3418)
@@ -97,4 +97,5 @@
     <Compile Include="ScopeCleaner.cs" />
     <Compile Include="StochasticBranch.cs" />
+    <Compile Include="StochasticMultiBranch.cs" />
     <Compile Include="SubScopesCreator.cs" />
     <Compile Include="SubScopesMixer.cs" />
Index: /trunk/sources/HeuristicLab.Operators/3.3/StochasticMultiBranch.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators/3.3/StochasticMultiBranch.cs	(revision 3417)
+++ /trunk/sources/HeuristicLab.Operators/3.3/StochasticMultiBranch.cs	(revision 3418)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -22,7 +22,12 @@
 using System;
 using System.Collections.Generic;
-using System.Text;
+using System.Collections.ObjectModel;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Operators {
@@ -30,53 +35,117 @@
   /// Branch of operators that have different probabilities to get executed.
   /// </summary>
-  public class StochasticMultiBranch : OperatorBase {
-    ///<inheritdoc select="summary"/>
-    public override string Description {
-      get { return @"TODO\r\nOperator description still missing ..."; }
+  [Item("StochasticMultiBranch", "Branch of operators that have different probabilities to get executed.")]
+  [StorableClass]
+  public class StochasticMultiBranch : MultiOperator<IOperator> {
+    public ValueLookupParameter<DoubleArray> ProbabilitiesParameter {
+      get { return (ValueLookupParameter<DoubleArray>)Parameters["Probabilities"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
     }
 
+    public DoubleArray Probabilities {
+      get { return ProbabilitiesParameter.Value; }
+      set { ProbabilitiesParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    public StochasticMultiBranch(bool deserializing) : base() { }
     /// <summary>
-    /// Initializes a new instance of <see cref="StochasticMultiBranch"/> with two variable infos
+    /// Initializes a new instance of <see cref="StochasticMultiBranch"/> with two parameters
     /// (<c>Probabilities</c> and <c>Random</c>).
     /// </summary>
     public StochasticMultiBranch()
       : base() {
-      AddVariableInfo(new VariableInfo("Probabilities", "The probabilities, that define how likely each suboperator/graph is executed. This array must sum to 1", typeof(DoubleArrayData), VariableKind.In));
-      AddVariableInfo(new VariableInfo("Random", "The pseudo random-generator, used for any random-decision.", typeof(IRandom), VariableKind.In));
+      Parameters.Add(new ValueLookupParameter<DoubleArray>("Probabilities", "The array of relative probabilities for each operator.", new DoubleArray()));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Initialize();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void Initialize() {
+      Operators.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IOperator>>(Operators_ItemsAdded);
+      Operators.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<IOperator>>(Operators_ItemsRemoved);
+      Operators.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<IOperator>>(Operators_ItemsMoved);
+    }
+
+    void Operators_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOperator>> e) {
+      if (Probabilities != null) {
+        DoubleArray oldProb = (DoubleArray)Probabilities.Clone();
+        foreach (IndexedItem<IOperator> old in e.OldItems) {
+          foreach (IndexedItem<IOperator> item in e.Items) {
+            if (old.Value == item.Value && item.Index < Probabilities.Length && old.Index < oldProb.Length)
+              Probabilities[item.Index] = oldProb[old.Index];
+          }
+        }
+      }
+    }
+
+    void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOperator>> e) {
+      if (Probabilities != null && Probabilities.Length > Operators.Count) {
+        List<double> probs = new List<double>(Probabilities.Cast<DoubleValue>().Select(x => x.Value));
+        var sorted = e.Items.OrderByDescending(x => x.Index);
+        foreach (IndexedItem<IOperator> item in sorted)
+          if (probs.Count > item.Index) probs.RemoveAt(item.Index);
+        Probabilities = new DoubleArray(probs.ToArray());
+      }
+    }
+
+    private void Operators_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IndexedItem<IOperator>> e) {
+      if (Probabilities != null && Probabilities.Length < Operators.Count) {
+        DoubleArray probs = new DoubleArray(Operators.Count);
+        double avg = 0;
+        if (Probabilities.Length > 0) {
+          for (int i = 0; i < Probabilities.Length; i++)
+            avg += Probabilities[i];
+          avg /= (double)Probabilities.Length;
+        } else avg = 1;
+
+        var added = e.Items.OrderBy(x => x.Index).ToList();
+        int insertCount = 0;
+        for (int i = 0; i < Operators.Count; i++) {
+          if (insertCount < added.Count && i == added[insertCount].Index) {
+            probs[i] = avg;
+            insertCount++;
+          } else if (i - insertCount < Probabilities.Length) {
+            probs[i] = Probabilities[i - insertCount];
+          } else probs[i] = avg;
+        }
+        Probabilities = probs;
+      }
     }
 
     /// <summary>
-    /// Applies an operator of the branches to the specified <paramref name="scope"/> with a 
+    /// Applies an operator of the branches to the current scope with a 
     /// specific probability.
     /// </summary>
     /// <exception cref="InvalidOperationException">Thrown when the list of probabilites does not
-    /// match the number of operators or if there was another problem with the list of probabilities.</exception>
-    /// <param name="scope">The scope to apply the operators on.</param>
-    /// <returns>A new <see cref="AtomicOperation"/> with a specific operator, depending 
-    /// on its probability, applied on the given <paramref name="scope"/>.</returns>
-    public override IOperation Apply(IScope scope) {
-      IRandom random = GetVariableValue<IRandom>("Random", scope, true);
-      DoubleArrayData probabilities = GetVariableValue<DoubleArrayData>("Probabilities", scope, true);
-      if(probabilities.Data.Length != SubOperators.Count) {
+    /// match the number of operators.</exception>
+    /// <returns>A new operation with the operator that was selected followed by the current operator's successor.</returns>
+    public override IOperation Apply() {
+      IRandom random = RandomParameter.ActualValue;
+      DoubleArray probabilities = ProbabilitiesParameter.ActualValue;
+      if(probabilities.Length != Operators.Count) {
         throw new InvalidOperationException("StochasticMultiBranch: The list of probabilities has to match the number of operators");
       }
       double sum = 0;
-      foreach(double prob in probabilities.Data) {
-        sum+=prob;
+      for (int i = 0; i < Operators.Count; i++) {
+        sum += probabilities[i];
       }
-      double r = random.NextDouble()*sum;
+      double r = random.NextDouble() * sum;
       sum = 0;
       IOperator successor = null;
-      for(int i = 0; i < SubOperators.Count; i++) {
-        sum += probabilities.Data[i];
+      for(int i = 0; i < Operators.Count; i++) {
+        sum += probabilities[i];
         if(sum > r) {
-          successor = SubOperators[i];
+          successor = Operators[i];
           break;
         }
       }
-      if(successor == null) {
-        throw new InvalidOperationException("StochasticMultiBranch: There was a problem with the list of probabilities");
+      OperationCollection next = new OperationCollection(base.Apply());
+      if (successor != null) {
+        next.Insert(0, ExecutionContext.CreateOperation(successor));
       }
-      return new AtomicOperation(successor, scope);
+      return next;
     }
   }
Index: /trunk/sources/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj	(revision 3417)
+++ /trunk/sources/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj	(revision 3418)
@@ -93,4 +93,6 @@
     <Compile Include="QualityComparator.cs" />
     <Compile Include="SolutionsCreator.cs" />
+    <Compile Include="MultiCrossover.cs" />
+    <Compile Include="TabuMaker.cs" />
     <Compile Include="UnidirectionalRingMigrator.cs" />
     <Compile Include="WeightedParentsQualityComparator.cs" />
Index: /trunk/sources/HeuristicLab.Optimization.Operators/3.3/MultiCrossover.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Operators/3.3/MultiCrossover.cs	(revision 3418)
+++ /trunk/sources/HeuristicLab.Optimization.Operators/3.3/MultiCrossover.cs	(revision 3418)
@@ -0,0 +1,159 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Collections.ObjectModel;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Operators {
+  /// <summary>
+  /// Base class for multi crossover operators.
+  /// </summary>
+  [Item("MultiCrossover", "Base class for multi crossover operators.")]
+  [StorableClass]
+  public class MultiCrossover<T> : MultiOperator<T>, IStochasticOperator where T : class, ICrossover {
+    public ValueLookupParameter<DoubleArray> ProbabilitiesParameter {
+      get { return (ValueLookupParameter<DoubleArray>)Parameters["Probabilities"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public DoubleArray Probabilities {
+      get { return ProbabilitiesParameter.Value; }
+      set { ProbabilitiesParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected MultiCrossover(bool deserializing) : base(deserializing) { }
+    /// <summary>
+    /// Initializes a new instance of <see cref="StochasticMultiBranch"/> with two parameters
+    /// (<c>Probabilities</c> and <c>Random</c>).
+    /// </summary>
+    public MultiCrossover()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<DoubleArray>("Probabilities", "The array of relative probabilities for each operator.", new DoubleArray()));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Initialize();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void Initialize() {
+      Operators.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_ItemsAdded);
+      Operators.ItemsRemoved += new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_ItemsRemoved);
+      Operators.ItemsMoved += new CollectionItemsChangedEventHandler<IndexedItem<T>>(Operators_ItemsMoved);
+      IEnumerable<Type> types = ApplicationManager.Manager.GetTypes(typeof(T), true);
+      foreach (Type type in types) {
+        if (type != this.GetType())
+          Operators.Add((T)Activator.CreateInstance(type));
+      }
+    }
+
+    void Operators_ItemsMoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<T>> e) {
+      if (Probabilities != null) {
+        DoubleArray oldProb = (DoubleArray)Probabilities.Clone();
+        foreach (IndexedItem<T> old in e.OldItems) {
+          foreach (IndexedItem<T> item in e.Items) {
+            if (old.Value == item.Value && item.Index < Probabilities.Length && old.Index < oldProb.Length)
+              Probabilities[item.Index] = oldProb[old.Index];
+          }
+        }
+      }
+    }
+
+    void Operators_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<T>> e) {
+      if (Probabilities != null && Probabilities.Length > Operators.Count) {
+        List<double> probs = new List<double>(Probabilities.Cast<double>());
+        var sorted = e.Items.OrderByDescending(x => x.Index);
+        foreach (IndexedItem<T> item in sorted)
+          if (probs.Count > item.Index) probs.RemoveAt(item.Index);
+        Probabilities = new DoubleArray(probs.ToArray());
+      }
+    }
+
+    private void Operators_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IndexedItem<T>> e) {
+      if (Probabilities != null && Probabilities.Length < Operators.Count) {
+        DoubleArray probs = new DoubleArray(Operators.Count);
+        double avg = 0;
+        if (Probabilities.Length > 0) {
+          for (int i = 0; i < Probabilities.Length; i++)
+            avg += Probabilities[i];
+          avg /= (double)Probabilities.Length;
+        } else avg = 1;
+
+        var added = e.Items.OrderBy(x => x.Index).ToList();
+        int insertCount = 0;
+        for (int i = 0; i < Operators.Count; i++) {
+          if (insertCount < added.Count && i == added[insertCount].Index) {
+            probs[i] = avg;
+            insertCount++;
+          } else if (i - insertCount < Probabilities.Length) {
+            probs[i] = Probabilities[i - insertCount];
+          } else probs[i] = avg;
+        }
+        Probabilities = probs;
+      }
+    }
+
+    /// <summary>
+    /// Applies an operator of the branches to the current scope with a 
+    /// specific probability.
+    /// </summary>
+    /// <exception cref="InvalidOperationException">Thrown when the list of probabilites does not
+    /// match the number of operators.</exception>
+    /// <returns>A new operation with the operator that was selected followed by the current operator's successor.</returns>
+    public override IOperation Apply() {
+      IRandom random = RandomParameter.ActualValue;
+      DoubleArray probabilities = ProbabilitiesParameter.ActualValue;
+      if(probabilities.Length != Operators.Count) {
+        throw new InvalidOperationException("MultiCrossover: The list of probabilities has to match the number of operators");
+      }
+      double sum = 0;
+      for (int i = 0; i < Operators.Count; i++) {
+        sum += probabilities[i];
+      }
+      double r = random.NextDouble() * sum;
+      sum = 0;
+      IOperator successor = null;
+      for(int i = 0; i < Operators.Count; i++) {
+        sum += probabilities[i];
+        if(sum > r) {
+          successor = Operators[i];
+          break;
+        }
+      }
+      OperationCollection next = new OperationCollection(base.Apply());
+      if (successor != null) {
+        next.Insert(0, ExecutionContext.CreateChildOperation(successor));
+      }
+      return next;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimization.Operators/3.3/TabuMaker.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Operators/3.3/TabuMaker.cs	(revision 3418)
+++ /trunk/sources/HeuristicLab.Optimization.Operators/3.3/TabuMaker.cs	(revision 3418)
@@ -0,0 +1,76 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  [Item("TabuMaker", "Base class for all operators that set a move tabu.")]
+  [StorableClass]
+  public abstract class TabuMaker : SingleSuccessorOperator, ITabuMaker {
+    public LookupParameter<ItemList<IItem>> TabuListParameter {
+      get { return (LookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
+    }
+    public ValueLookupParameter<IntValue> TabuTenureParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["TabuTenure"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    protected TabuMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list where move attributes are stored."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("TabuTenure", "The tenure of the tabu list."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the move."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, else if it is a minimization problem."));
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      int tabuTenure = TabuTenureParameter.ActualValue.Value;
+
+      int overlength = tabuList.Count - tabuTenure;
+      if (overlength >= 0) {
+        for (int i = 0; i < tabuTenure - 1; i++)
+          tabuList[i] = tabuList[i + overlength + 1];
+        while (tabuList.Count >= tabuTenure)
+          tabuList.RemoveAt(tabuList.Count - 1);
+      }
+
+      tabuList.Add(GetTabuAttribute(MaximizationParameter.ActualValue.Value, QualityParameter.ActualValue.Value, MoveQualityParameter.ActualValue.Value));
+      return base.Apply();
+    }
+
+    protected abstract IItem GetTabuAttribute(bool maximization, double quality, double moveQuality);
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 3417)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 3418)
@@ -131,5 +131,4 @@
     <Compile Include="Interfaces\ITabuMaker.cs" />
     <Compile Include="Result.cs" />
-    <Compile Include="TabuMaker.cs" />
     <Compile Include="UserDefinedAlgorithm.cs" />
     <Compile Include="EngineAlgorithm.cs" />
@@ -162,8 +161,4 @@
       <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
       <Name>HeuristicLab.Data-3.3</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
-      <Project>{23DA7FF4-D5B8-41B6-AA96-F0561D24F3EE}</Project>
-      <Name>HeuristicLab.Operators-3.3</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
Index: unk/sources/HeuristicLab.Optimization/3.3/TabuMaker.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/TabuMaker.cs	(revision 3417)
+++ 	(revision )
@@ -1,76 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2010 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 HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Optimization {
-  [Item("TabuMaker", "Base class for all operators that set a move tabu.")]
-  [StorableClass]
-  public abstract class TabuMaker : SingleSuccessorOperator, ITabuMaker {
-    public LookupParameter<ItemList<IItem>> TabuListParameter {
-      get { return (LookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
-    }
-    public ValueLookupParameter<IntValue> TabuTenureParameter {
-      get { return (ValueLookupParameter<IntValue>)Parameters["TabuTenure"]; }
-    }
-    public ILookupParameter<DoubleValue> MoveQualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
-    }
-    public ILookupParameter<DoubleValue> QualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
-    }
-    public IValueLookupParameter<BoolValue> MaximizationParameter {
-      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
-    }
-
-    protected TabuMaker()
-      : base() {
-      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list where move attributes are stored."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("TabuTenure", "The tenure of the tabu list."));
-      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the move."));
-      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
-      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, else if it is a minimization problem."));
-    }
-
-    public override IOperation Apply() {
-      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
-      int tabuTenure = TabuTenureParameter.ActualValue.Value;
-
-      int overlength = tabuList.Count - tabuTenure;
-      if (overlength >= 0) {
-        for (int i = 0; i < tabuTenure - 1; i++)
-          tabuList[i] = tabuList[i + overlength + 1];
-        while (tabuList.Count >= tabuTenure)
-          tabuList.RemoveAt(tabuList.Count - 1);
-      }
-
-      tabuList.Add(GetTabuAttribute(MaximizationParameter.ActualValue.Value, QualityParameter.ActualValue.Value, MoveQualityParameter.ActualValue.Value));
-      return base.Apply();
-    }
-
-    protected abstract IItem GetTabuAttribute(bool maximization, double quality, double moveQuality);
-  }
-}
