Index: /branches/QAP/HeuristicLab.Analysis.Views/3.3/DataTableView.Designer.cs
===================================================================
--- /branches/QAP/HeuristicLab.Analysis.Views/3.3/DataTableView.Designer.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Analysis.Views/3.3/DataTableView.Designer.cs	(revision 5838)
@@ -45,8 +45,8 @@
     /// </summary>
     private void InitializeComponent() {
-      System.Windows.Forms.DataVisualization.Charting.ChartArea defaultChartArea = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
-      System.Windows.Forms.DataVisualization.Charting.Legend defaultLegend = new System.Windows.Forms.DataVisualization.Charting.Legend();
-      System.Windows.Forms.DataVisualization.Charting.Series defaultSeries = new System.Windows.Forms.DataVisualization.Charting.Series();
-      System.Windows.Forms.DataVisualization.Charting.Title defaultTitle = new System.Windows.Forms.DataVisualization.Charting.Title();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
       this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
@@ -58,9 +58,10 @@
       this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
       this.errorProvider.SetIconPadding(this.nameTextBox, 2);
-      this.nameTextBox.Size = new System.Drawing.Size(287, 20);
+      this.nameTextBox.Location = new System.Drawing.Point(55, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(279, 20);
       // 
-      // descriptionTextBox
+      // infoLabel
       // 
-      this.descriptionTextBox.Size = new System.Drawing.Size(287, 20);
+      this.infoLabel.Location = new System.Drawing.Point(340, 3);
       // 
       // chart
@@ -71,28 +72,28 @@
       this.chart.BorderlineColor = System.Drawing.Color.Black;
       this.chart.BorderlineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Solid;
-      defaultChartArea.AxisX.Minimum = 0;
-      defaultChartArea.CursorX.IsUserEnabled = true;
-      defaultChartArea.CursorX.IsUserSelectionEnabled = true;
-      defaultChartArea.CursorY.IsUserEnabled = true;
-      defaultChartArea.CursorY.IsUserSelectionEnabled = true;
-      defaultChartArea.Name = "Default";
-      this.chart.ChartAreas.Add(defaultChartArea);
-      defaultLegend.Alignment = System.Drawing.StringAlignment.Center;
-      defaultLegend.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
-      defaultLegend.Name = "Default";
-      this.chart.Legends.Add(defaultLegend);
-      this.chart.Location = new System.Drawing.Point(0, 52);
+      chartArea1.AxisX.Minimum = 0D;
+      chartArea1.CursorX.IsUserEnabled = true;
+      chartArea1.CursorX.IsUserSelectionEnabled = true;
+      chartArea1.CursorY.IsUserEnabled = true;
+      chartArea1.CursorY.IsUserSelectionEnabled = true;
+      chartArea1.Name = "Default";
+      this.chart.ChartAreas.Add(chartArea1);
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 26);
       this.chart.Name = "chart";
-      defaultSeries.ChartArea = "Default";
-      defaultSeries.Legend = "Default";
-      defaultSeries.Name = "Default";
-      this.chart.Series.Add(defaultSeries);
-      this.chart.Size = new System.Drawing.Size(359, 222);
-      this.chart.TabIndex = 4;
+      series1.ChartArea = "Default";
+      series1.Legend = "Default";
+      series1.Name = "Default";
+      this.chart.Series.Add(series1);
+      this.chart.Size = new System.Drawing.Size(359, 248);
+      this.chart.TabIndex = 3;
       this.chart.Text = "chart";
-      defaultTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-      defaultTitle.Name = "Default";
-      defaultTitle.Text = "Title";
-      this.chart.Titles.Add(defaultTitle);
+      title1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      title1.Name = "Default";
+      title1.Text = "Title";
+      this.chart.Titles.Add(title1);
       this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
       this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
@@ -106,9 +107,8 @@
       this.Name = "DataTableView";
       this.Size = new System.Drawing.Size(359, 274);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
       this.Controls.SetChildIndex(this.chart, 0);
       this.Controls.SetChildIndex(this.nameLabel, 0);
-      this.Controls.SetChildIndex(this.descriptionLabel, 0);
       this.Controls.SetChildIndex(this.nameTextBox, 0);
-      this.Controls.SetChildIndex(this.descriptionTextBox, 0);
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
       ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 5837)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 5838)
@@ -168,15 +168,15 @@
     <Compile Include="Moves\PermutationMoveAttribute.cs" />
     <Compile Include="Moves\StandardEdgeEqualityComparer.cs" />
-    <Compile Include="Moves\Swap\SwapMoveSoftTabuCriterion.cs" />
-    <Compile Include="Moves\Swap\ExhaustiveSwapMoveGenerator.cs" />
-    <Compile Include="Moves\Swap\StochasticSwapSingleMoveGenerator.cs" />
-    <Compile Include="Moves\Swap\SwapMoveAbsoluteAttribute.cs" />
-    <Compile Include="Moves\Swap\SwapMoveHardTabuCriterion.cs" />
-    <Compile Include="Moves\Swap\SwapMoveMaker.cs" />
-    <Compile Include="Moves\Swap\SwapMoveRelativeAttribute.cs" />
-    <Compile Include="Moves\Swap\SwapMoveTabuMaker.cs" />
-    <Compile Include="Moves\Swap\StochasticSwapMultiMoveGenerator.cs" />
-    <Compile Include="Moves\Swap\SwapMoveGenerator.cs" />
-    <Compile Include="Moves\Swap\SwapMove.cs" />
+    <Compile Include="Moves\Swap2\ExhaustiveSwap2MoveGenerator.cs" />
+    <Compile Include="Moves\Swap2\StochasticSwap2MultiMoveGenerator.cs" />
+    <Compile Include="Moves\Swap2\StochasticSwap2SingleMoveGenerator.cs" />
+    <Compile Include="Moves\Swap2\Swap2Move.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveAbsoluteAttribute.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveGenerator.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveHardTabuCriterion.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveMaker.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveRelativeAttribute.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveSoftTabuCriterion.cs" />
+    <Compile Include="Moves\Swap2\Swap2MoveTabuMaker.cs" />
     <Compile Include="Moves\ThreeIndexMove.cs" />
     <Compile Include="Moves\ThreeOpt\StochasticSingleInsertionMoveGenerator.cs" />
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationSwapMoveOperator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationSwapMoveOperator.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationSwapMoveOperator.cs	(revision 5838)
@@ -23,6 +23,6 @@
 
 namespace HeuristicLab.Encodings.PermutationEncoding {
-  public interface IPermutationSwapMoveOperator : IPermutationMoveOperator {
-    ILookupParameter<SwapMove> SwapMoveParameter { get; }
+  public interface IPermutationSwap2MoveOperator : IPermutationMoveOperator {
+    ILookupParameter<Swap2Move> Swap2MoveParameter { get; }
   }
 }
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/ExhaustiveSwap2MoveGenerator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/ExhaustiveSwap2MoveGenerator.cs	(revision 5838)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/ExhaustiveSwap2MoveGenerator.cs	(revision 5838)
@@ -0,0 +1,75 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("ExhaustiveSwap2MoveGenerator", "Generates all possible swap-2 moves from a given permutation.")]
+  [StorableClass]
+  public class ExhaustiveSwap2MoveGenerator : Swap2MoveGenerator, IExhaustiveMoveGenerator {
+    [StorableConstructor]
+    protected ExhaustiveSwap2MoveGenerator(bool deserializing) : base(deserializing) { }
+    protected ExhaustiveSwap2MoveGenerator(ExhaustiveSwap2MoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public ExhaustiveSwap2MoveGenerator() : base() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExhaustiveSwap2MoveGenerator(this, cloner);
+    }
+
+    public static Swap2Move[] Apply(Permutation permutation) {
+      int length = permutation.Length;
+      if (length == 1) throw new ArgumentException("ExhaustiveSwap2MoveGenerator: There cannot be an Swap move given a permutation of length 1.", "permutation");
+      int totalMoves = (length) * (length - 1) / 2;
+      Swap2Move[] moves = null;
+      int count = 0;
+
+      if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
+        if (totalMoves - 3 > 0) {
+          moves = new Swap2Move[totalMoves - 3];
+          for (int i = 0; i < length - 1; i++) {
+            for (int j = i + 1; j < length; j++) {
+              if (j - i >= length - 2) continue;
+              moves[count++] = new Swap2Move(i, j);
+            }
+          }
+        } else { // when length is 3 or less, there's actually no difference, but for the sake of not crashing the algorithm create a dummy move
+          moves = new Swap2Move[1];
+          moves[0] = new Swap2Move(0, 1);
+        }
+      } else {
+        moves = new Swap2Move[totalMoves];
+        for (int i = 0; i < length - 1; i++)
+          for (int j = i + 1; j < length; j++) {
+            moves[count++] = new Swap2Move(i, j);
+          }
+      }
+      return moves;
+    }
+
+    protected override Swap2Move[] GenerateMoves(Permutation permutation) {
+      return Apply(permutation);
+    }
+  }
+}
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2MultiMoveGenerator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2MultiMoveGenerator.cs	(revision 5838)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2MultiMoveGenerator.cs	(revision 5838)
@@ -0,0 +1,72 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("StochasticSwap2MultiMoveGenerator", "Randomly samples n from all possible swap-2 moves from a given permutation.")]
+  [StorableClass]
+  public class StochasticSwap2MultiMoveGenerator : Swap2MoveGenerator, IMultiMoveGenerator, IStochasticOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public IValueLookupParameter<IntValue> SampleSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+
+    public IntValue SampleSize {
+      get { return SampleSizeParameter.Value; }
+      set { SampleSizeParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected StochasticSwap2MultiMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticSwap2MultiMoveGenerator(StochasticSwap2MultiMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticSwap2MultiMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticSwap2MultiMoveGenerator(this, cloner);
+    }
+
+    public static Swap2Move[] Apply(Permutation permutation, IRandom random, int sampleSize) {
+      int length = permutation.Length;
+      Swap2Move[] moves = new Swap2Move[sampleSize];
+      for (int i = 0; i < sampleSize; i++) {
+        moves[i] = StochasticSwap2SingleMoveGenerator.Apply(permutation, random);
+      }
+      return moves;
+    }
+
+    protected override Swap2Move[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      return Apply(permutation, random, SampleSizeParameter.ActualValue.Value);
+    }
+  }
+}
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2SingleMoveGenerator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2SingleMoveGenerator.cs	(revision 5838)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/StochasticSwap2SingleMoveGenerator.cs	(revision 5838)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("StochasticSwap2SingleMoveGenerator", "Randomly samples a single from all possible swap-2 moves from a given permutation.")]
+  [StorableClass]
+  public class StochasticSwap2SingleMoveGenerator : Swap2MoveGenerator, IStochasticOperator, ISingleMoveGenerator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected StochasticSwap2SingleMoveGenerator(bool deserializing) : base(deserializing) { }
+    protected StochasticSwap2SingleMoveGenerator(StochasticSwap2SingleMoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public StochasticSwap2SingleMoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticSwap2SingleMoveGenerator(this, cloner);
+    }
+
+    public static Swap2Move Apply(Permutation permutation, IRandom random) {
+      int length = permutation.Length;
+      if (length == 1) throw new ArgumentException("StochasticSwap2SingleMoveGenerator: There cannot be an Swap move given a permutation of length 1.", "permutation");
+      int index1 = random.Next(length - 1);
+      int index2 = random.Next(index1 + 1, length);
+      return new Swap2Move(index1, index2);
+    }
+
+    protected override Swap2Move[] GenerateMoves(Permutation permutation) {
+      IRandom random = RandomParameter.ActualValue;
+      return new Swap2Move[] { Apply(permutation, random) };
+    }
+  }
+}
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2Move.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2Move.cs	(revision 5838)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2Move.cs	(revision 5838)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("Swap2Move", "Item that describes a swap-2 move.")]
+  [StorableClass]
+  public class Swap2Move : TwoIndexMove {
+    [StorableConstructor]
+    protected Swap2Move(bool deserializing) : base(deserializing) { }
+    protected Swap2Move(Swap2Move original, Cloner cloner) : base(original, cloner) { }
+    public Swap2Move() : base() { }
+    public Swap2Move(int index1, int index2) : base(index1, index2, null) { }
+    public Swap2Move(int index1, int index2, Permutation permutation) : base(index1, index2, permutation) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2Move(this, cloner);
+    }
+  }
+}
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveAbsoluteAttribute.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveAbsoluteAttribute.cs	(revision 5838)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveAbsoluteAttribute.cs	(revision 5838)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("Swap2MoveAbsoluteAttribute", "Specifies the tabu attributes for a swap-2 move on an absolute position permutation.")]
+  [StorableClass]
+  public class Swap2MoveAbsoluteAttribute : PermutationMoveAttribute {
+    [Storable]
+    public int Index1 { get; private set; }
+    [Storable]
+    public int Number1 { get; private set; }
+    [Storable]
+    public int Index2 { get; private set; }
+    [Storable]
+    public int Number2 { get; private set; }
+
+    [StorableConstructor]
+    protected Swap2MoveAbsoluteAttribute(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveAbsoluteAttribute(Swap2MoveAbsoluteAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.Index1 = original.Index1;
+      this.Number1 = original.Number1;
+      this.Index2 = original.Index2;
+      this.Number2 = original.Number2;
+    }
+    public Swap2MoveAbsoluteAttribute() : this(-1, -1, -1, -1, -1) { }
+    public Swap2MoveAbsoluteAttribute(int index1, int number1, int index2, int number2, double moveQuality)
+      : base(moveQuality) {
+      Index1 = index1;
+      Number1 = number1;
+      Index2 = index2;
+      Number2 = number2;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2MoveAbsoluteAttribute(this, cloner);
+    }
+  }
+}
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveGenerator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveGenerator.cs	(revision 5838)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveGenerator.cs	(revision 5838)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("Swap2MoveGenerator", "Base class for all swap-2 move generators.")]
+  [StorableClass]
+  public abstract class Swap2MoveGenerator : SingleSuccessorOperator, IPermutationSwap2MoveOperator, IMoveGenerator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (LookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
+    }
+    protected ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+
+    [StorableConstructor]
+    protected Swap2MoveGenerator(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveGenerator(Swap2MoveGenerator original, Cloner cloner) : base(original, cloner) { }
+    public Swap2MoveGenerator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation for which moves should be generated."));
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "The moves that should be generated in subscopes."));
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope where the moves should be added as subscopes."));
+    }
+
+    public override IOperation Apply() {
+      Permutation p = PermutationParameter.ActualValue;
+      Swap2Move[] moves = GenerateMoves(p);
+      Scope[] moveScopes = new Scope[moves.Length];
+      for (int i = 0; i < moveScopes.Length; i++) {
+        moveScopes[i] = new Scope(i.ToString());
+        moveScopes[i].Variables.Add(new Variable(Swap2MoveParameter.ActualName, moves[i]));
+      }
+      CurrentScopeParameter.ActualValue.SubScopes.AddRange(moveScopes);
+      return base.Apply();
+    }
+
+    protected abstract Swap2Move[] GenerateMoves(Permutation permutation);
+  }
+}
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveHardTabuCriterion.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveHardTabuCriterion.cs	(revision 5838)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveHardTabuCriterion.cs	(revision 5838)
@@ -0,0 +1,169 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Collections.Generic;
+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.PermutationEncoding {
+  [Item("Swap2MoveHardTabuCriterion", @"For relative postion encoded permutations it prevents readding of previously deleted edges as well as deleting previously added edges.
+  For absolute position encoded permutations it prevents moving a number if it was previously moved.
+
+If the aspiration condition is activated, a move will not be considered tabu against a move in the tabu list if it leads to a better solution than the quality recorded with the move in the tabu list.")]
+  [StorableClass]
+  public class Swap2MoveHardTabuCriterion : SingleSuccessorOperator, IPermutationSwap2MoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (LookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<ItemList<IItem>> TabuListParameter {
+      get { return (ILookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
+    }
+    public ILookupParameter<BoolValue> MoveTabuParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["MoveTabu"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ValueParameter<BoolValue> UseAspirationCriterionParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["UseAspirationCriterion"]; }
+    }
+
+    public BoolValue UseAspirationCriterion {
+      get { return UseAspirationCriterionParameter.Value; }
+      set { UseAspirationCriterionParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected Swap2MoveHardTabuCriterion(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveHardTabuCriterion(Swap2MoveHardTabuCriterion original, Cloner cloner) : base(original, cloner) { }
+    public Swap2MoveHardTabuCriterion()
+      : base() {
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list."));
+      Parameters.Add(new ValueParameter<BoolValue>("UseAspirationCriterion", "Whether to use the aspiration criterion or not.", new BoolValue(true)));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, else if it is a minimization problem."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the current move."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2MoveHardTabuCriterion(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      Swap2Move move = Swap2MoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      int length = permutation.Length;
+      double moveQuality = MoveQualityParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      bool useAspiration = UseAspirationCriterion.Value;
+      bool isTabu = false;
+
+      if (permutation.PermutationType != PermutationTypes.Absolute)
+        isTabu = EvaluateRelativeTabuState(tabuList, move, permutation, moveQuality, maximization, useAspiration);
+      else isTabu = EvaluateAbsoluteTabuState(tabuList, move, permutation, moveQuality, maximization, useAspiration);
+
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+
+    private static bool EvaluateRelativeTabuState(ItemList<IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration) {
+      bool isTabu = false;
+      StandardEdgeEqualityComparer eq = new StandardEdgeEqualityComparer();
+      bool bidirectional = permutation.PermutationType == PermutationTypes.RelativeUndirected;
+      List<Edge> deleted = new List<Edge>();
+      deleted.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index1], bidirectional));
+      deleted.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index1 + 1), bidirectional));
+      deleted.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index2], bidirectional));
+      deleted.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index2 + 1), bidirectional));
+      List<Edge> added = new List<Edge>();
+      added.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index2], bidirectional));
+      added.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index1 + 1), bidirectional));
+      added.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index1], bidirectional));
+      added.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index2 + 1), bidirectional));
+
+      foreach (IItem tabuMove in tabuList) {
+        Swap2MoveRelativeAttribute relAttrib = (tabuMove as Swap2MoveRelativeAttribute);
+        if (relAttrib != null
+          && (!useAspiration
+              || maximization && moveQuality <= relAttrib.MoveQuality
+              || !maximization && moveQuality >= relAttrib.MoveQuality)) {
+          for (int i = 0; i < relAttrib.AddedEdges.Count; i++) {
+            isTabu = eq.Equals(relAttrib.AddedEdges[i], deleted[0])
+                  || eq.Equals(relAttrib.AddedEdges[i], deleted[1])
+                  || eq.Equals(relAttrib.AddedEdges[i], deleted[2])
+                  || eq.Equals(relAttrib.AddedEdges[i], deleted[3]);
+            if (isTabu) break;
+          }
+          if (isTabu) break;
+          for (int i = 0; i < relAttrib.DeletedEdges.Count; i++) {
+            isTabu = eq.Equals(relAttrib.DeletedEdges[i], added[0])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[1])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[2])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[3]);
+            if (isTabu) break;
+          }
+        }
+        if (isTabu) break;
+      }
+      return isTabu;
+    }
+
+    private bool EvaluateAbsoluteTabuState(ItemList<IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration) {
+      bool isTabu = false;
+      foreach (IItem tabuMove in tabuList) {
+        Swap2MoveAbsoluteAttribute attrib = (tabuMove as Swap2MoveAbsoluteAttribute);
+        if (attrib != null
+          && (!useAspiration
+              || maximization && moveQuality <= attrib.MoveQuality
+              || !maximization && moveQuality >= attrib.MoveQuality)) {
+          int i1 = move.Index1;
+          int n1 = permutation[move.Index1];
+          int i2 = move.Index2;
+          int n2 = permutation[move.Index2];
+          if (attrib != null) {
+            if (attrib.Number1 == n1 || attrib.Number1 == n2
+              || attrib.Number2 == n2 || attrib.Number2 == n1)
+              isTabu = true;
+          }
+        }
+        if (isTabu) break;
+      }
+      return isTabu;
+    }
+  }
+}
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveMaker.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveMaker.cs	(revision 5838)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveMaker.cs	(revision 5838)
@@ -0,0 +1,77 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("Swap2MoveMaker", "Peforms a swap-2 move on a given permutation and updates the quality.")]
+  [StorableClass]
+  public class Swap2MoveMaker : SingleSuccessorOperator, IPermutationSwap2MoveOperator, IMoveMaker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (ILookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    [StorableConstructor]
+    protected Swap2MoveMaker(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveMaker(Swap2MoveMaker original, Cloner cloner) : base(original, cloner) { }
+    public Swap2MoveMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The relative quality of the move."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2MoveMaker(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      Swap2Move move = Swap2MoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      DoubleValue moveQuality = MoveQualityParameter.ActualValue;
+      DoubleValue quality = QualityParameter.ActualValue;
+
+      Swap2Manipulator.Apply(permutation, move.Index1, move.Index2);
+      quality.Value = moveQuality.Value;
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveRelativeAttribute.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveRelativeAttribute.cs	(revision 5838)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveRelativeAttribute.cs	(revision 5838)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("Swap2MoveRelativeAttribute", "Specifies the tabu attributes for a swap-2 move on a relative position permutation.")]
+  [StorableClass]
+  public class Swap2MoveRelativeAttribute : PermutationMoveAttribute {
+    [Storable]
+    public ItemList<Edge> DeletedEdges { get; private set; }
+    [Storable]
+    public ItemList<Edge> AddedEdges { get; private set; }
+
+    [StorableConstructor]
+    protected Swap2MoveRelativeAttribute(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveRelativeAttribute(Swap2MoveRelativeAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.DeletedEdges = cloner.Clone(original.DeletedEdges);
+      this.AddedEdges = cloner.Clone(original.AddedEdges);
+    }
+    public Swap2MoveRelativeAttribute(double moveQuality)
+      : base(moveQuality) {
+      DeletedEdges = new ItemList<Edge>();
+      AddedEdges = new ItemList<Edge>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2MoveRelativeAttribute(this, cloner);
+    }
+  }
+}
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveSoftTabuCriterion.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveSoftTabuCriterion.cs	(revision 5838)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveSoftTabuCriterion.cs	(revision 5838)
@@ -0,0 +1,154 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Collections.Generic;
+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.PermutationEncoding {
+  [Item("Swap2MoveSoftTabuCriterion", @"For relative postion encoded permutations it just prevents readding of previously deleted edges, but allows deleting previously added edges.
+  For absolute position encoded permutations it prevents moving a number to a position it has previously occupied.
+
+If the aspiration condition is activated, a move will not be considered tabu against a move in the tabu list if it leads to a better solution than the quality recorded with the move in the tabu list.")]
+  [StorableClass]
+  public class Swap2MoveSoftTabuCriterion : SingleSuccessorOperator, IPermutationSwap2MoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (LookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
+    }
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (LookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<ItemList<IItem>> TabuListParameter {
+      get { return (ILookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
+    }
+    public ILookupParameter<BoolValue> MoveTabuParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["MoveTabu"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ValueParameter<BoolValue> UseAspirationCriterionParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["UseAspirationCriterion"]; }
+    }
+
+    public BoolValue UseAspirationCriterion {
+      get { return UseAspirationCriterionParameter.Value; }
+      set { UseAspirationCriterionParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected Swap2MoveSoftTabuCriterion(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveSoftTabuCriterion(Swap2MoveSoftTabuCriterion original, Cloner cloner) : base(original, cloner) { }
+    public Swap2MoveSoftTabuCriterion()
+      : base() {
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list."));
+      Parameters.Add(new ValueParameter<BoolValue>("UseAspirationCriterion", "Whether to use the aspiration criterion or not.", new BoolValue(true)));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, else if it is a minimization problem."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the current move."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2MoveSoftTabuCriterion(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      Swap2Move move = Swap2MoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      int length = permutation.Length;
+      double moveQuality = MoveQualityParameter.ActualValue.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      bool useAspiration = UseAspirationCriterion.Value;
+      bool isTabu = false;
+
+      if (permutation.PermutationType != PermutationTypes.Absolute)
+        isTabu = EvaluateRelativeTabuState(tabuList, move, permutation, moveQuality, maximization, useAspiration);
+      else isTabu = EvaluateAbsoluteTabuState(tabuList, move, permutation, moveQuality, maximization, useAspiration);
+
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+
+    private static bool EvaluateRelativeTabuState(ItemList<IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration) {
+      bool isTabu = false;
+      StandardEdgeEqualityComparer eq = new StandardEdgeEqualityComparer();
+      bool bidirectional = permutation.PermutationType == PermutationTypes.RelativeUndirected;
+      List<Edge> added = new List<Edge>();
+      added.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index2], bidirectional));
+      added.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index1 + 1), bidirectional));
+      added.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index1], bidirectional));
+      added.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index2 + 1), bidirectional));
+
+      foreach (IItem tabuMove in tabuList) {
+        Swap2MoveRelativeAttribute relAttrib = (tabuMove as Swap2MoveRelativeAttribute);
+        if (relAttrib != null
+          && (!useAspiration
+              || maximization && moveQuality <= relAttrib.MoveQuality
+              || !maximization && moveQuality >= relAttrib.MoveQuality)) {
+          for (int i = 0; i < relAttrib.DeletedEdges.Count; i++) {
+            isTabu = eq.Equals(relAttrib.DeletedEdges[i], added[0])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[1])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[2])
+                  || eq.Equals(relAttrib.DeletedEdges[i], added[3]);
+            if (isTabu) break;
+          }
+        }
+        if (isTabu) break;
+      }
+      return isTabu;
+    }
+
+    private bool EvaluateAbsoluteTabuState(ItemList<IItem> tabuList, Swap2Move move, Permutation permutation, double moveQuality, bool maximization, bool useAspiration) {
+      bool isTabu = false;
+      foreach (IItem tabuMove in tabuList) {
+        Swap2MoveAbsoluteAttribute attrib = (tabuMove as Swap2MoveAbsoluteAttribute);
+        if (attrib != null
+          && (!useAspiration
+              || maximization && moveQuality <= attrib.MoveQuality
+              || !maximization && moveQuality >= attrib.MoveQuality)) {
+          int i1 = move.Index1;
+          int n1 = permutation[move.Index1];
+          int i2 = move.Index2;
+          int n2 = permutation[move.Index2];
+          if ((attrib.Index1 == i1 || attrib.Index1 == i2) && (attrib.Number1 == n1 || attrib.Number1 == n2)
+            || (attrib.Index2 == i2 || attrib.Index2 == i1) && (attrib.Number2 == n2 || attrib.Number2 == n1))
+            isTabu = true;
+        }
+        if (isTabu) break;
+      }
+      return isTabu;
+    }
+  }
+}
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveTabuMaker.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveTabuMaker.cs	(revision 5838)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/Swap2/Swap2MoveTabuMaker.cs	(revision 5838)
@@ -0,0 +1,74 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  [Item("Swap2MoveTabuMaker", "Declares a given swap-2 move as tabu, by adding its attributes to the tabu list and also store the solution quality or the move quality (whichever is better).")]
+  [StorableClass]
+  public class Swap2MoveTabuMaker : TabuMaker, IPermutationSwap2MoveOperator {
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (LookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
+    }
+
+    [StorableConstructor]
+    protected Swap2MoveTabuMaker(bool deserializing) : base(deserializing) { }
+    protected Swap2MoveTabuMaker(Swap2MoveTabuMaker original, Cloner cloner) : base(original, cloner) { }
+    public Swap2MoveTabuMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "The move that was made."));
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Swap2MoveTabuMaker(this, cloner);
+    }
+
+    protected override IItem GetTabuAttribute(bool maximization, double quality, double moveQuality) {
+      Swap2Move move = Swap2MoveParameter.ActualValue;
+      Permutation permutation = PermutationParameter.ActualValue;
+      double baseQuality = moveQuality;
+      if (maximization && quality > moveQuality || !maximization && quality < moveQuality) baseQuality = quality; // we make an uphill move, the lower bound is the solution quality
+      if (permutation.PermutationType == PermutationTypes.Absolute)
+        return new Swap2MoveAbsoluteAttribute(move.Index1, permutation[move.Index1], move.Index2, permutation[move.Index2], baseQuality);
+      else {
+        Swap2MoveRelativeAttribute attrib = new Swap2MoveRelativeAttribute(baseQuality);
+        bool bidirectional = permutation.PermutationType == PermutationTypes.RelativeUndirected;
+        attrib.DeletedEdges.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index1], bidirectional));
+        attrib.DeletedEdges.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index1 + 1), bidirectional));
+        attrib.DeletedEdges.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index2], bidirectional));
+        attrib.DeletedEdges.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index2 + 1), bidirectional));
+        attrib.AddedEdges.Add(new Edge(permutation.GetCircular(move.Index1 - 1), permutation[move.Index2], bidirectional));
+        attrib.AddedEdges.Add(new Edge(permutation[move.Index2], permutation.GetCircular(move.Index1 + 1), bidirectional));
+        attrib.AddedEdges.Add(new Edge(permutation.GetCircular(move.Index2 - 1), permutation[move.Index1], bidirectional));
+        attrib.AddedEdges.Add(new Edge(permutation[move.Index1], permutation.GetCircular(move.Index2 + 1), bidirectional));
+        return attrib;
+      }
+    }
+  }
+}
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeIndexMove.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeIndexMove.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeIndexMove.cs	(revision 5838)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Encodings.PermutationEncoding {
-  [Item("ThreeIndexMove", "A move on a permutation that is specified by 3 indices")]
+  [Item("ThreeIndexMove", "A move on a permutation that is specified by 3 indices.")]
   [StorableClass]
   public class ThreeIndexMove : Item {
Index: /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoIndexMove.cs
===================================================================
--- /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoIndexMove.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/TwoIndexMove.cs	(revision 5838)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Encodings.PermutationEncoding {
-  [Item("TwoIndexMove", "A move on a permutation that is specified by 2 indices")]
+  [Item("TwoIndexMove", "A move on a permutation that is specified by 2 indices.")]
   [StorableClass]
   public class TwoIndexMove : Item {
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QuadraticAssignmentProblemView.Designer.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QuadraticAssignmentProblemView.Designer.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QuadraticAssignmentProblemView.Designer.cs	(revision 5838)
@@ -75,13 +75,4 @@
       this.nameLabel.Location = new System.Drawing.Point(3, 32);
       // 
-      // descriptionLabel
-      // 
-      this.descriptionLabel.Location = new System.Drawing.Point(3, 58);
-      // 
-      // descriptionTextBox
-      // 
-      this.descriptionTextBox.Location = new System.Drawing.Point(86, 55);
-      this.descriptionTextBox.Size = new System.Drawing.Size(561, 20);
-      // 
       // importInstanceButton
       // 
@@ -147,8 +138,8 @@
       this.tabControl.Controls.Add(this.problemTabPage);
       this.tabControl.Controls.Add(this.visualizationTabPage);
-      this.tabControl.Location = new System.Drawing.Point(0, 81);
+      this.tabControl.Location = new System.Drawing.Point(0, 55);
       this.tabControl.Name = "tabControl";
       this.tabControl.SelectedIndex = 0;
-      this.tabControl.Size = new System.Drawing.Size(647, 411);
+      this.tabControl.Size = new System.Drawing.Size(647, 437);
       this.tabControl.TabIndex = 8;
       // 
@@ -158,5 +149,5 @@
       this.problemTabPage.Name = "problemTabPage";
       this.problemTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.problemTabPage.Size = new System.Drawing.Size(639, 385);
+      this.problemTabPage.Size = new System.Drawing.Size(639, 411);
       this.problemTabPage.TabIndex = 0;
       this.problemTabPage.Text = "Problem";
@@ -196,10 +187,9 @@
       this.Name = "QuadraticAssignmentProblemView";
       this.Size = new System.Drawing.Size(647, 492);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
       this.Controls.SetChildIndex(this.parameterCollectionView, 0);
-      this.Controls.SetChildIndex(this.descriptionLabel, 0);
       this.Controls.SetChildIndex(this.nameLabel, 0);
       this.Controls.SetChildIndex(this.nameTextBox, 0);
       this.Controls.SetChildIndex(this.QAPLIBInstancesLabel, 0);
-      this.Controls.SetChildIndex(this.descriptionTextBox, 0);
       this.Controls.SetChildIndex(this.loadInstanceButton, 0);
       this.Controls.SetChildIndex(this.importInstanceButton, 0);
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QuadraticAssignmentProblemView.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QuadraticAssignmentProblemView.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QuadraticAssignmentProblemView.cs	(revision 5838)
@@ -46,5 +46,5 @@
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
-      Content.DistanceMatrixParameter.ValueChanged += new EventHandler(DistanceMatrixParameter_ValueChanged);
+      Content.DistancesParameter.ValueChanged += new EventHandler(DistanceMatrixParameter_ValueChanged);
       Content.WeightsParameter.ValueChanged += new EventHandler(WeightsParameter_ValueChanged);
       Content.BestKnownSolutionParameter.ValueChanged += new EventHandler(BestKnownSolutionParameter_ValueChanged);
@@ -52,5 +52,5 @@
 
     protected override void DeregisterContentEvents() {
-      Content.DistanceMatrixParameter.ValueChanged -= new EventHandler(DistanceMatrixParameter_ValueChanged);
+      Content.DistancesParameter.ValueChanged -= new EventHandler(DistanceMatrixParameter_ValueChanged);
       Content.WeightsParameter.ValueChanged -= new EventHandler(WeightsParameter_ValueChanged);
       Content.BestKnownSolutionParameter.ValueChanged -= new EventHandler(BestKnownSolutionParameter_ValueChanged);
@@ -59,5 +59,5 @@
 
     private void DistanceMatrixParameter_ValueChanged(object sender, System.EventArgs e) {
-      qapView.Distances = Content.DistanceMatrix;
+      qapView.Distances = Content.Distances;
     }
 
@@ -77,5 +77,5 @@
           instancesComboBox.Items.Add(instance);
         }
-        qapView.Distances = Content.DistanceMatrix;
+        qapView.Distances = Content.Distances;
         qapView.Weights = Content.Weights;
         qapView.Assignment = Content.BestKnownSolution;
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Analyzers/BestQAPSolutionAnalyzer.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Analyzers/BestQAPSolutionAnalyzer.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Analyzers/BestQAPSolutionAnalyzer.cs	(revision 5838)
@@ -89,5 +89,4 @@
 
     public override IOperation Apply() {
-      DoubleMatrix coordinates = CoordinatesParameter.ActualValue;
       DoubleMatrix distances = DistancesParameter.ActualValue;
       DoubleMatrix weights = WeightsParameter.ActualValue;
@@ -113,5 +112,4 @@
       if (assignment == null) {
         assignment = new QAPAssignment(weights, (Permutation)permutations[i].Clone(), new DoubleValue(qualities[i].Value));
-        assignment.Coordinates = coordinates;
         assignment.Distances = distances;
         BestSolutionParameter.ActualValue = assignment;
@@ -120,5 +118,4 @@
         if (max && assignment.Quality.Value < qualities[i].Value ||
           !max && assignment.Quality.Value > qualities[i].Value) {
-          assignment.Coordinates = coordinates;
           assignment.Distances = distances;
           assignment.Weights = weights;
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPEvaluator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPEvaluator.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPEvaluator.cs	(revision 5838)
@@ -35,9 +35,6 @@
       get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
     }
-    public ILookupParameter<DoubleMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
-    }
-    public ILookupParameter<DoubleMatrix> CoordinatesParameter {
-      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
+    public ILookupParameter<DoubleMatrix> DistancesParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Distances"]; }
     }
     public ILookupParameter<DoubleMatrix> WeightsParameter {
@@ -53,6 +50,5 @@
     public QAPEvaluator() {
       Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation that represents the current solution."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("DistanceMatrix", "The distance matrix that contains the distances between the locations."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The coordinates in case the distance matrix should not be used."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", "The distance matrix that contains the distances between the locations."));
       Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", "The matrix with the weights between the facilities, that is how strongly they're connected to each other."));
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value aka fitness value of the solution."));
@@ -76,5 +72,5 @@
       Permutation assignment = PermutationParameter.ActualValue;
       DoubleMatrix weights = WeightsParameter.ActualValue;
-      DoubleMatrix distanceMatrix = DistanceMatrixParameter.ActualValue;
+      DoubleMatrix distanceMatrix = DistancesParameter.ActualValue;
 
       double quality = Apply(assignment, weights, distanceMatrix);
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPInversionMoveEvaluator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPInversionMoveEvaluator.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPInversionMoveEvaluator.cs	(revision 5838)
@@ -73,5 +73,5 @@
       if (move == null) throw new InvalidOperationException("Inversion move is not found.");
       Permutation assignment = PermutationParameter.ActualValue;
-      DoubleMatrix distances = DistanceMatrixParameter.ActualValue;
+      DoubleMatrix distances = DistancesParameter.ActualValue;
       DoubleMatrix weights = WeightsParameter.ActualValue;
 
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPMoveEvaluator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPMoveEvaluator.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPMoveEvaluator.cs	(revision 5838)
@@ -49,6 +49,6 @@
       get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
     }
-    public ILookupParameter<DoubleMatrix> DistanceMatrixParameter {
-      get { return (ILookupParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
+    public ILookupParameter<DoubleMatrix> DistancesParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Distances"]; }
     }
     public ILookupParameter<DoubleMatrix> WeightsParameter {
@@ -64,5 +64,5 @@
       Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The evaluated quality of a move on a QAP solution."));
       Parameters.Add(new LookupParameter<Permutation>("Permutation", "The solution as permutation."));
-      Parameters.Add(new LookupParameter<DoubleMatrix>("DistanceMatrix", "The matrix which contains the distances between the facilities."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Distances", "The matrix which contains the distances between the facilities."));
       Parameters.Add(new LookupParameter<DoubleMatrix>("Weights", "The matrix with the weights between the facilities, that is how strongly they're connected to each other."));
     }
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPSwapMoveEvaluator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPSwapMoveEvaluator.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPSwapMoveEvaluator.cs	(revision 5838)
@@ -29,25 +29,25 @@
 
 namespace HeuristicLab.Problems.QuadraticAssignment {
-  [Item("QAPSwapMoveEvaluator", "Evaluated a swap move on a QAP solution.")]
+  [Item("QAPSwap2MoveEvaluator", "Evaluated a swap-2 move on a QAP solution.")]
   [StorableClass]
-  public class QAPSwapMoveEvaluator : QAPMoveEvaluator, IPermutationSwapMoveOperator {
-    public ILookupParameter<SwapMove> SwapMoveParameter {
-      get { return (ILookupParameter<SwapMove>)Parameters["SwapMove"]; }
+  public class QAPSwap2MoveEvaluator : QAPMoveEvaluator, IPermutationSwap2MoveOperator {
+    public ILookupParameter<Swap2Move> Swap2MoveParameter {
+      get { return (ILookupParameter<Swap2Move>)Parameters["Swap2Move"]; }
     }
 
     [StorableConstructor]
-    protected QAPSwapMoveEvaluator(bool deserializing) : base(deserializing) { }
-    protected QAPSwapMoveEvaluator(QAPSwapMoveEvaluator original, Cloner cloner)
+    protected QAPSwap2MoveEvaluator(bool deserializing) : base(deserializing) { }
+    protected QAPSwap2MoveEvaluator(QAPSwap2MoveEvaluator original, Cloner cloner)
       : base(original, cloner) {
     }
-    public QAPSwapMoveEvaluator() {
-      Parameters.Add(new LookupParameter<SwapMove>("SwapMove", "The move to evaluate."));
+    public QAPSwap2MoveEvaluator() {
+      Parameters.Add(new LookupParameter<Swap2Move>("Swap2Move", "The move to evaluate."));
     }
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      return new QAPSwapMoveEvaluator(this, cloner);
+      return new QAPSwap2MoveEvaluator(this, cloner);
     }
 
-    public static double Apply(Permutation assignment, SwapMove move, DoubleMatrix weights, DoubleMatrix distances) {
+    public static double Apply(Permutation assignment, Swap2Move move, DoubleMatrix weights, DoubleMatrix distances) {
       if (move.Index1 == move.Index2) return 0;
       double moveQuality = 0;
@@ -70,8 +70,8 @@
 
     public override IOperation Apply() {
-      SwapMove move = SwapMoveParameter.ActualValue;
-      if (move == null) throw new InvalidOperationException("Swap move is not found.");
+      Swap2Move move = Swap2MoveParameter.ActualValue;
+      if (move == null) throw new InvalidOperationException("Swap-2 move is not found.");
       Permutation assignment = PermutationParameter.ActualValue;
-      DoubleMatrix distances = DistanceMatrixParameter.ActualValue;
+      DoubleMatrix distances = DistancesParameter.ActualValue;
       DoubleMatrix weights = WeightsParameter.ActualValue;
 
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPTranslocationMoveEvaluator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPTranslocationMoveEvaluator.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Evaluators/QAPTranslocationMoveEvaluator.cs	(revision 5838)
@@ -85,5 +85,5 @@
       if (move == null) throw new InvalidOperationException("Translocation move is not found.");
       Permutation assignment = PermutationParameter.ActualValue;
-      DoubleMatrix distances = DistanceMatrixParameter.ActualValue;
+      DoubleMatrix distances = DistancesParameter.ActualValue;
       DoubleMatrix weights = WeightsParameter.ActualValue;
 
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Interfaces/IQAPEvaluator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Interfaces/IQAPEvaluator.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Interfaces/IQAPEvaluator.cs	(revision 5838)
@@ -28,6 +28,5 @@
   public interface IQAPEvaluator : ISingleObjectiveEvaluator {
     ILookupParameter<Permutation> PermutationParameter { get; }
-    ILookupParameter<DoubleMatrix> DistanceMatrixParameter { get; }
-    ILookupParameter<DoubleMatrix> CoordinatesParameter { get; }
+    ILookupParameter<DoubleMatrix> DistancesParameter { get; }
     ILookupParameter<DoubleMatrix> WeightsParameter { get; }
   }
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Interfaces/IQAPMoveEvaluator.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Interfaces/IQAPMoveEvaluator.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Interfaces/IQAPMoveEvaluator.cs	(revision 5838)
@@ -28,5 +28,5 @@
   public interface IQAPMoveEvaluator : ISingleObjectiveMoveEvaluator, IMoveOperator {
     ILookupParameter<Permutation> PermutationParameter { get; }
-    ILookupParameter<DoubleMatrix> DistanceMatrixParameter { get; }
+    ILookupParameter<DoubleMatrix> DistancesParameter { get; }
     ILookupParameter<DoubleMatrix> WeightsParameter { get; }
   }
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Parsers/QAPLIBParser.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Parsers/QAPLIBParser.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Parsers/QAPLIBParser.cs	(revision 5838)
@@ -1,3 +1,24 @@
-﻿using System;
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.IO;
 
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Parsers/QAPLIBSolutionParser.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Parsers/QAPLIBSolutionParser.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Parsers/QAPLIBSolutionParser.cs	(revision 5838)
@@ -1,3 +1,24 @@
-﻿using System;
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Globalization;
 using System.IO;
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Plugin.cs.frame
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Plugin.cs.frame	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Plugin.cs.frame	(revision 5838)
@@ -25,14 +25,14 @@
   [Plugin("HeuristicLab.Problems.QuadraticAssignment", "3.3.3.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.QuadraticAssignment-3.3.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.Collections", "3.3.3")]
-  [PluginDependency("HeuristicLab.Common", "3.3.3")]
-  [PluginDependency("HeuristicLab.Common.Resources", "3.3.3")]
-  [PluginDependency("HeuristicLab.Core", "3.3.3")]
-  [PluginDependency("HeuristicLab.Data", "3.3.3")]
-  [PluginDependency("HeuristicLab.Encodings.PermutationEncoding", "3.3.3")]
-  [PluginDependency("HeuristicLab.Operators", "3.3.3")]
-  [PluginDependency("HeuristicLab.Optimization", "3.3.3")]
-  [PluginDependency("HeuristicLab.Parameters", "3.3.3")]
-  [PluginDependency("HeuristicLab.Persistence", "3.3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.PermutationEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
   public class HeuristicLabProblemsQuadraticAssignmentPlugin : PluginBase { }
 }
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/QAPAssignment.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/QAPAssignment.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/QAPAssignment.cs	(revision 5838)
@@ -10,14 +10,4 @@
   [StorableClass]
   public sealed class QAPAssignment : Item, INotifyPropertyChanged {
-    [Storable]
-    private DoubleMatrix coordinates;
-    public DoubleMatrix Coordinates {
-      get { return coordinates; }
-      set {
-        bool changed = (coordinates != value);
-        coordinates = value;
-        if (changed) OnPropertyChanged("Coordinates");
-      }
-    }
 
     [Storable]
@@ -69,5 +59,4 @@
     private QAPAssignment(QAPAssignment original, Cloner cloner)
       : base(original, cloner) {
-      coordinates = cloner.Clone(original.coordinates);
       distances = cloner.Clone(original.distances);
       weights = cloner.Clone(original.weights);
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs	(revision 5838)
@@ -36,5 +36,5 @@
 
 namespace HeuristicLab.Problems.QuadraticAssignment {
-  [Item("Quadratic Assignment Problem", "The Quadratic Assignment Problem (QAP) is the problem of assigning N facilities to N fixed locations such that there is exactly one facility in each location and that the distances multiplied by the connection strength between the facilities becomes minimal.")]
+  [Item("Quadratic Assignment Problem", "The Quadratic Assignment Problem (QAP) can be described as the problem of assigning N facilities to N fixed locations such that there is exactly one facility in each location and that the sum of the distances multiplied by the connection strength between the facilities becomes minimal.")]
   [Creatable("Problems")]
   [StorableClass]
@@ -56,6 +56,6 @@
       get { return (IValueParameter<DoubleMatrix>)Parameters["Weights"]; }
     }
-    public IValueParameter<DoubleMatrix> DistanceMatrixParameter {
-      get { return (IValueParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
+    public IValueParameter<DoubleMatrix> DistancesParameter {
+      get { return (IValueParameter<DoubleMatrix>)Parameters["Distances"]; }
     }
     #endregion
@@ -74,7 +74,7 @@
       set { WeightsParameter.Value = value; }
     }
-    public DoubleMatrix DistanceMatrix {
-      get { return DistanceMatrixParameter.Value; }
-      set { DistanceMatrixParameter.Value = value; }
+    public DoubleMatrix Distances {
+      get { return DistancesParameter.Value; }
+      set { DistancesParameter.Value = value; }
     }
 
@@ -106,5 +106,5 @@
       Parameters.Add(new ValueParameter<DoubleMatrix>("Coordinates", "The coordinates of the locations. If this is changed the distance matrix is calculated automatically using the euclidean distance."));
       Parameters.Add(new ValueParameter<DoubleMatrix>("Weights", "The strength of the connection between the facilities.", new DoubleMatrix(5, 5)));
-      Parameters.Add(new ValueParameter<DoubleMatrix>("DistanceMatrix", "The distance matrix which can either be specified directly without the coordinates, or can be calculated automatically from the coordinates.", new DoubleMatrix(5, 5)));
+      Parameters.Add(new ValueParameter<DoubleMatrix>("Distances", "The distance matrix which can either be specified directly without the coordinates, or can be calculated automatically from the coordinates.", new DoubleMatrix(5, 5)));
 
       Maximization = new BoolValue(false);
@@ -126,5 +126,5 @@
       });
 
-      DistanceMatrix = new DoubleMatrix(new double[,] {
+      Distances = new DoubleMatrix(new double[,] {
         {   0, 360, 582, 582, 360 },
         { 360,   0, 360, 582, 582 },
@@ -231,6 +231,5 @@
       if (Evaluator != null) {
         Evaluator.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
-        Evaluator.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
-        Evaluator.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
+        Evaluator.DistancesParameter.ActualName = DistancesParameter.Name;
         Evaluator.WeightsParameter.ActualName = WeightsParameter.Name;
       }
@@ -240,5 +239,5 @@
         BestQAPSolutionAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
         BestQAPSolutionAnalyzer.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
-        BestQAPSolutionAnalyzer.DistancesParameter.ActualName = DistanceMatrixParameter.Name;
+        BestQAPSolutionAnalyzer.DistancesParameter.ActualName = DistancesParameter.Name;
         BestQAPSolutionAnalyzer.WeightsParameter.ActualName = WeightsParameter.Name;
         BestQAPSolutionAnalyzer.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
@@ -267,7 +266,7 @@
         foreach (IPermutationTranslocationMoveOperator op in Operators.OfType<IPermutationTranslocationMoveOperator>())
           op.TranslocationMoveParameter.ActualName = translocationMove;
-        string swapMove = Operators.OfType<IMoveGenerator>().OfType<IPermutationSwapMoveOperator>().First().SwapMoveParameter.ActualName;
-        foreach (IPermutationSwapMoveOperator op in Operators.OfType<IPermutationSwapMoveOperator>()) {
-          op.SwapMoveParameter.ActualName = swapMove;
+        string swapMove = Operators.OfType<IMoveGenerator>().OfType<IPermutationSwap2MoveOperator>().First().Swap2MoveParameter.ActualName;
+        foreach (IPermutationSwap2MoveOperator op in Operators.OfType<IPermutationSwap2MoveOperator>()) {
+          op.Swap2MoveParameter.ActualName = swapMove;
         }
       }
@@ -282,8 +281,8 @@
             double dy = Coordinates[i, 1] - Coordinates[j, 1];
             distance[i, j] = Math.Sqrt(dx * dx + dy * dy);
-            distance[j, i] = DistanceMatrix[i, j];
+            distance[j, i] = Distances[i, j];
           }
         }
-        DistanceMatrix = distance;
+        Distances = distance;
       }
     }
@@ -295,5 +294,5 @@
       if (parser.Error != null) throw parser.Error;
       Coordinates = new DoubleMatrix();
-      DistanceMatrix = new DoubleMatrix(parser.Distances);
+      Distances = new DoubleMatrix(parser.Distances);
       Weights = new DoubleMatrix(parser.Weights);
       Name = "Quadratic Assignment Problem (imported from " + Path.GetFileNameWithoutExtension(filename) + ")";
@@ -311,5 +310,5 @@
         if (parser.Error != null) throw parser.Error;
         Coordinates = new DoubleMatrix();
-        DistanceMatrix = new DoubleMatrix(parser.Distances);
+        Distances = new DoubleMatrix(parser.Distances);
         Weights = new DoubleMatrix(parser.Weights);
         Name = "Quadratic Assignment Problem (loaded instance " + instance + ")";
@@ -327,9 +326,9 @@
           solParser.Parse(solStream, false); // most sln's seem to be of the type index = location => value = facility
           if (solParser.Error != null) throw solParser.Error;
-          if (!solParser.Quality.IsAlmost(QAPEvaluator.Apply(new Permutation(PermutationTypes.Absolute, solParser.Assignment), Weights, DistanceMatrix))) {
+          if (!solParser.Quality.IsAlmost(QAPEvaluator.Apply(new Permutation(PermutationTypes.Absolute, solParser.Assignment), Weights, Distances))) {
             solStream.Seek(0, SeekOrigin.Begin);
             solParser.Parse(solStream, true); // some sln's seem to be of the type index = facility => value = location
             if (solParser.Error != null) throw solParser.Error;
-            if (solParser.Quality.IsAlmost(QAPEvaluator.Apply(new Permutation(PermutationTypes.Absolute, solParser.Assignment), Weights, DistanceMatrix))) {
+            if (solParser.Quality.IsAlmost(QAPEvaluator.Apply(new Permutation(PermutationTypes.Absolute, solParser.Assignment), Weights, Distances))) {
               BestKnownQuality = new DoubleValue(solParser.Quality);
               BestKnownSolution = new Permutation(PermutationTypes.Absolute, solParser.Assignment);
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPLIBInstancesTest.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPLIBInstancesTest.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPLIBInstancesTest.cs	(revision 5838)
@@ -35,5 +35,5 @@
           double quality = double.NaN;
           try {
-            quality = QAPEvaluator.Apply(qap.BestKnownSolution, qap.Weights, qap.DistanceMatrix);
+            quality = QAPEvaluator.Apply(qap.BestKnownSolution, qap.Weights, qap.Distances);
           } catch (Exception ex) {
             failedInstances.AppendLine("An unknown problem occurred evaluating solution of instance " + instance + ": " + ex.Message);
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPMoveEvaluatorTest.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPMoveEvaluatorTest.cs	(revision 5837)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPMoveEvaluatorTest.cs	(revision 5838)
@@ -97,5 +97,5 @@
         double after = QAPEvaluator.Apply(assignment, weights, distances);
         // evaluate swap back
-        double move = QAPSwapMoveEvaluator.Apply(assignment, new SwapMove(index1, index2, assignment), weights, distances);
+        double move = QAPSwap2MoveEvaluator.Apply(assignment, new Swap2Move(index1, index2, assignment), weights, distances);
         Assert.IsTrue(move.IsAlmost(before - after));
       }
