Index: trunk/sources/HeuristicLab.Optimizer/3.3/HeuristicLab.Optimizer-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Optimizer/3.3/HeuristicLab.Optimizer-3.3.csproj	(revision 8021)
+++ trunk/sources/HeuristicLab.Optimizer/3.3/HeuristicLab.Optimizer-3.3.csproj	(revision 8022)
@@ -248,8 +248,10 @@
       <Project>{72104A0B-90E7-42F3-9ABE-9BBBADD4B943}</Project>
       <Name>HeuristicLab.Data.Views-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
       <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
       <Name>HeuristicLab.Data-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.MainForm.WindowsForms\3.3\HeuristicLab.MainForm.WindowsForms-3.3.csproj">
@@ -271,4 +273,5 @@
       <Project>{56F9106A-079F-4C61-92F6-86A84C2D84B7}</Project>
       <Name>HeuristicLab.Parameters-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Persistence\3.3\HeuristicLab.Persistence-3.3.csproj">
@@ -285,4 +288,5 @@
       <Project>{3540E29E-4793-49E7-8EE2-FEA7F61C3994}</Project>
       <Name>HeuristicLab.Problems.Instances-3.3</Name>
+      <Private>False</Private>
     </ProjectReference>
   </ItemGroup>
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/HeuristicLab.Problems.LinearAssignment.Views-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/HeuristicLab.Problems.LinearAssignment.Views-3.3.csproj	(revision 8021)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/HeuristicLab.Problems.LinearAssignment.Views-3.3.csproj	(revision 8022)
@@ -102,4 +102,7 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
       <HintPath>..\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
@@ -114,9 +117,9 @@
   <ItemGroup>
     <None Include="Plugin.cs.frame" />
-    <Compile Include="LinearAssignmentProblemView.cs">
+    <Compile Include="LAPAssignmentView.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="LinearAssignmentProblemView.Designer.cs">
-      <DependentUpon>LinearAssignmentProblemView.cs</DependentUpon>
+    <Compile Include="LAPAssignmentView.Designer.cs">
+      <DependentUpon>LAPAssignmentView.cs</DependentUpon>
     </Compile>
     <Compile Include="Plugin.cs" />
@@ -148,4 +151,9 @@
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data.Views\3.3\HeuristicLab.Data.Views-3.3.csproj">
+      <Project>{72104A0B-90E7-42F3-9ABE-9BBBADD4B943}</Project>
+      <Name>HeuristicLab.Data.Views-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
       <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
@@ -153,4 +161,9 @@
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.PermutationEncoding\3.3\HeuristicLab.Encodings.PermutationEncoding-3.3.csproj">
+      <Project>{DBECB8B0-B166-4133-BAF1-ED67C3FD7FCA}</Project>
+      <Name>HeuristicLab.Encodings.PermutationEncoding-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.MainForm.WindowsForms\3.3\HeuristicLab.MainForm.WindowsForms-3.3.csproj">
       <Project>{AB687BBE-1BFE-476B-906D-44237135431D}</Project>
@@ -163,12 +176,7 @@
       <Private>False</Private>
     </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Optimization.Views\3.3\HeuristicLab.Optimization.Views-3.3.csproj">
-      <Project>{662B4B15-8F4D-4AE5-B3EB-D91C215F5AF2}</Project>
-      <Name>HeuristicLab.Optimization.Views-3.3</Name>
-      <Private>False</Private>
-    </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
-      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
-      <Name>HeuristicLab.Optimization-3.3</Name>
+    <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
+      <Project>{23DA7FF4-D5B8-41B6-AA96-F0561D24F3EE}</Project>
+      <Name>HeuristicLab.Operators-3.3</Name>
       <Private>False</Private>
     </ProjectReference>
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.Designer.cs	(revision 8022)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.Designer.cs	(revision 8022)
@@ -0,0 +1,94 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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
+
+namespace HeuristicLab.Problems.LinearAssignment.Views {
+  partial class LAPAssignmentView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.assignmentView = new HeuristicLab.Data.Views.StringConvertibleArrayView();
+      this.qualityView = new HeuristicLab.Data.Views.StringConvertibleValueView();
+      this.SuspendLayout();
+      // 
+      // assignmentView
+      // 
+      this.assignmentView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.assignmentView.Caption = "StringConvertibleArray View";
+      this.assignmentView.Content = null;
+      this.assignmentView.Location = new System.Drawing.Point(0, 30);
+      this.assignmentView.Name = "assignmentView";
+      this.assignmentView.ReadOnly = true;
+      this.assignmentView.Size = new System.Drawing.Size(422, 130);
+      this.assignmentView.TabIndex = 0;
+      // 
+      // qualityView
+      // 
+      this.qualityView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.qualityView.Caption = "StringConvertibleValue View";
+      this.qualityView.Content = null;
+      this.qualityView.LabelVisible = true;
+      this.qualityView.Location = new System.Drawing.Point(0, 3);
+      this.qualityView.Name = "qualityView";
+      this.qualityView.ReadOnly = true;
+      this.qualityView.Size = new System.Drawing.Size(422, 21);
+      this.qualityView.TabIndex = 1;
+      // 
+      // LAPAssignmentView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.qualityView);
+      this.Controls.Add(this.assignmentView);
+      this.Name = "LAPAssignmentView";
+      this.Size = new System.Drawing.Size(422, 160);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private Data.Views.StringConvertibleArrayView assignmentView;
+    private Data.Views.StringConvertibleValueView qualityView;
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.cs	(revision 8022)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.cs	(revision 8022)
@@ -0,0 +1,79 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.ComponentModel;
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.LinearAssignment.Views {
+  [View("LAPAssignmentView")]
+  [Content(typeof(LAPAssignment), IsDefaultView = true)]
+  public partial class LAPAssignmentView : ItemView {
+    public new LAPAssignment Content {
+      get { return (LAPAssignment)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public LAPAssignmentView() {
+      InitializeComponent();
+    }
+
+    #region Register Content Events
+    protected override void DeregisterContentEvents() {
+      Content.PropertyChanged -= new PropertyChangedEventHandler(Content_PropertyChanged);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.PropertyChanged += new PropertyChangedEventHandler(Content_PropertyChanged);
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        qualityView.Content = null;
+        assignmentView.Content = null;
+      } else {
+        qualityView.Content = Content.Quality;
+        assignmentView.Content = Content.Assignment;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+    }
+
+    #region Event Handlers
+    private void Content_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      switch (e.PropertyName) {
+        case "Quality": qualityView.Content = Content.Quality;
+          break;
+        case "Assignment": assignmentView.Content = Content.Assignment;
+          break;
+        default: break;
+      }
+    }
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LinearAssignmentProblemView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LinearAssignmentProblemView.Designer.cs	(revision 8021)
+++ 	(revision )
@@ -1,110 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 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
-
-namespace HeuristicLab.Problems.LinearAssignment.Views {
-  partial class LinearAssignmentProblemView {
-    /// <summary> 
-    /// Required designer variable.
-    /// </summary>
-    private System.ComponentModel.IContainer components = null;
-
-    /// <summary> 
-    /// Clean up any resources being used.
-    /// </summary>
-    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-    protected override void Dispose(bool disposing) {
-      if (disposing && (components != null)) {
-        components.Dispose();
-      }
-      base.Dispose(disposing);
-    }
-
-    #region Component Designer generated code
-
-    /// <summary> 
-    /// Required method for Designer support - do not modify 
-    /// the contents of this method with the code editor.
-    /// </summary>
-    private void InitializeComponent() {
-      this.solveButton = new System.Windows.Forms.Button();
-      this.backgroundWorker = new System.ComponentModel.BackgroundWorker();
-      ((System.ComponentModel.ISupportInitialize)(this.problemInstanceSplitContainer)).BeginInit();
-      this.problemInstanceSplitContainer.Panel1.SuspendLayout();
-      this.problemInstanceSplitContainer.Panel2.SuspendLayout();
-      this.problemInstanceSplitContainer.SuspendLayout();
-      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
-      this.SuspendLayout();
-      // 
-      // problemInstanceSplitContainer
-      // 
-      // 
-      // problemInstanceSplitContainer.Panel2
-      // 
-      this.problemInstanceSplitContainer.Panel2.Controls.Add(this.solveButton);
-      // 
-      // parameterCollectionView
-      // 
-      this.parameterCollectionView.Location = new System.Drawing.Point(6, 56);
-      this.parameterCollectionView.Size = new System.Drawing.Size(501, 274);
-      // 
-      // nameTextBox
-      // 
-      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
-      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
-      // 
-      // solveButton
-      // 
-      this.solveButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.solveButton.Location = new System.Drawing.Point(6, 27);
-      this.solveButton.Name = "solveButton";
-      this.solveButton.Size = new System.Drawing.Size(501, 23);
-      this.solveButton.TabIndex = 4;
-      this.solveButton.Text = "Solve";
-      this.solveButton.UseVisualStyleBackColor = true;
-      this.solveButton.Click += new System.EventHandler(this.solveButton_Click);
-      // 
-      // backgroundWorker
-      // 
-      this.backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker_DoWork);
-      this.backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker_RunWorkerCompleted);
-      // 
-      // LinearAssignmentProblemView
-      // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
-      this.Name = "LinearAssignmentProblemView";
-      this.problemInstanceSplitContainer.Panel1.ResumeLayout(false);
-      this.problemInstanceSplitContainer.Panel2.ResumeLayout(false);
-      this.problemInstanceSplitContainer.Panel2.PerformLayout();
-      ((System.ComponentModel.ISupportInitialize)(this.problemInstanceSplitContainer)).EndInit();
-      this.problemInstanceSplitContainer.ResumeLayout(false);
-      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
-      this.ResumeLayout(false);
-
-    }
-
-    #endregion
-
-    private System.Windows.Forms.Button solveButton;
-    private System.ComponentModel.BackgroundWorker backgroundWorker;
-  }
-}
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LinearAssignmentProblemView.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LinearAssignmentProblemView.cs	(revision 8021)
+++ 	(revision )
@@ -1,65 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 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.ComponentModel;
-using System.Windows.Forms;
-using HeuristicLab.Data;
-using HeuristicLab.MainForm;
-using HeuristicLab.MainForm.WindowsForms;
-using HeuristicLab.Optimization.Views;
-
-namespace HeuristicLab.Problems.LinearAssignment.Views {
-  [View("LinearAssignmentProblemView")]
-  [Content(typeof(LinearAssignmentProblem), IsDefaultView = true)]
-  public partial class LinearAssignmentProblemView : ProblemView {
-    public new LinearAssignmentProblem Content {
-      get { return (LinearAssignmentProblem)base.Content; }
-      set { base.Content = value; }
-    }
-
-    public LinearAssignmentProblemView() {
-      InitializeComponent();
-    }
-
-    protected override void SetEnabledStateOfControls() {
-      base.SetEnabledStateOfControls();
-      solveButton.Enabled = Content != null && !ReadOnly && !Locked;
-    }
-
-    private void solveButton_Click(object sender, System.EventArgs e) {
-      ReadOnly = true;
-      Locked = true;
-      backgroundWorker.RunWorkerAsync();
-    }
-
-    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
-      double quality;
-      var solution = LinearAssignmentProblemSolver.Solve(Content.Costs, out quality);
-      Content.Solution = new IntArray(solution);
-      Content.Quality = new DoubleValue(quality);
-    }
-
-    private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
-      Locked = false;
-      ReadOnly = false;
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/Plugin.cs.frame
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/Plugin.cs.frame	(revision 8021)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/Plugin.cs.frame	(revision 8022)
@@ -25,10 +25,11 @@
   [Plugin("HeuristicLab.Problems.LinearAssignment.Views", "3.3.6.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.LinearAssignment.Views-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
   [PluginDependency("HeuristicLab.Core.Views", "3.3")]
   [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Data.Views", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.PermutationEncoding", "3.3")]
   [PluginDependency("HeuristicLab.MainForm", "3.3")]
   [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
-  [PluginDependency("HeuristicLab.Optimization", "3.3")]
-  [PluginDependency("HeuristicLab.Optimization.Views", "3.3")]
   [PluginDependency("HeuristicLab.Problems.LinearAssignment", "3.3")]
   public class HeuristicLabProblemsLinearAssignmentViewsPlugin : PluginBase {
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Analyzers/BestLAPSolutionAnalyzer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Analyzers/BestLAPSolutionAnalyzer.cs	(revision 8022)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Analyzers/BestLAPSolutionAnalyzer.cs	(revision 8022)
@@ -0,0 +1,139 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.LinearAssignment {
+  [Item("BestLAPSolutionAnalyzer", "Analyzes the best solution found.")]
+  [StorableClass]
+  public class BestLAPSolutionAnalyzer : SingleSuccessorOperator, IAnalyzer {
+    public bool EnabledByDefault { get { return true; } }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleMatrix> CostsParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Costs"]; }
+    }
+    public IScopeTreeLookupParameter<Permutation> AssignmentParameter {
+      get { return (IScopeTreeLookupParameter<Permutation>)Parameters["Assignment"]; }
+    }
+    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<LAPAssignment> BestSolutionParameter {
+      get { return (ILookupParameter<LAPAssignment>)Parameters["BestSolution"]; }
+    }
+    public ILookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public ILookupParameter<ItemSet<Permutation>> BestKnownSolutionsParameter {
+      get { return (ILookupParameter<ItemSet<Permutation>>)Parameters["BestKnownSolutions"]; }
+    }
+    public ILookupParameter<Permutation> BestKnownSolutionParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["BestKnownSolution"]; }
+    }
+    public IValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (IValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    [StorableConstructor]
+    protected BestLAPSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    protected BestLAPSolutionAnalyzer(BestLAPSolutionAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public BestLAPSolutionAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Costs", LinearAssignmentProblem.CostsDescription));
+      Parameters.Add(new ScopeTreeLookupParameter<Permutation>("Assignment", "The LAP solutions from which the best solution should be analyzed."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the LAP solutions which should be analyzed."));
+      Parameters.Add(new LookupParameter<LAPAssignment>("BestSolution", "The best LAP solution."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the best LAP solution should be stored."));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution of this LAP instance."));
+      Parameters.Add(new LookupParameter<ItemSet<Permutation>>("BestKnownSolutions", "The best known solutions (there may be multiple) of this LAP instance."));
+      Parameters.Add(new LookupParameter<Permutation>("BestKnownSolution", "The best known solution of this LAP instance."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestLAPSolutionAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var costs = CostsParameter.ActualValue;
+      var permutations = AssignmentParameter.ActualValue;
+      var qualities = QualityParameter.ActualValue;
+      var results = ResultsParameter.ActualValue;
+      bool max = MaximizationParameter.ActualValue.Value;
+      DoubleValue bestKnownQuality = BestKnownQualityParameter.ActualValue;
+      
+      var sorted = qualities.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).ToArray();
+      if (max) sorted = sorted.Reverse().ToArray();
+      int i = sorted.First().index;
+
+      if (bestKnownQuality == null
+          || max && qualities[i].Value > bestKnownQuality.Value
+          || !max && qualities[i].Value < bestKnownQuality.Value) {
+        // if there isn't a best-known quality or we improved the best-known quality we'll add the current solution as best-known
+        BestKnownQualityParameter.ActualValue = new DoubleValue(qualities[i].Value);
+        BestKnownSolutionParameter.ActualValue = (Permutation)permutations[i].Clone();
+        BestKnownSolutionsParameter.ActualValue = new ItemSet<Permutation>(new PermutationEqualityComparer());
+        BestKnownSolutionsParameter.ActualValue.Add((Permutation)permutations[i].Clone());
+      } else if (bestKnownQuality.Value == qualities[i].Value) {
+        // if we matched the best-known quality we'll try to set the best-known solution if it isn't null
+        // and try to add it to the pool of best solutions if it is different
+        if (BestKnownSolutionParameter.ActualValue == null)
+          BestKnownSolutionParameter.ActualValue = (Permutation)permutations[i].Clone();
+        if (BestKnownSolutionsParameter.ActualValue == null)
+          BestKnownSolutionsParameter.ActualValue = new ItemSet<Permutation>(new PermutationEqualityComparer());
+        foreach (var k in sorted) { // for each solution that we found check if it is in the pool of best-knowns
+          if (!max && k.Value > qualities[i].Value
+            || max && k.Value < qualities[i].Value) break; // stop when we reached a solution worse than the best-known quality
+          Permutation p = permutations[k.index];
+          if (!BestKnownSolutionsParameter.ActualValue.Contains(p))
+            BestKnownSolutionsParameter.ActualValue.Add((Permutation)permutations[k.index].Clone());
+        }
+      }
+
+      LAPAssignment assignment = BestSolutionParameter.ActualValue;
+      if (assignment == null) {
+        assignment = new LAPAssignment(costs, (Permutation)permutations[i].Clone(), new DoubleValue(qualities[i].Value));
+        BestSolutionParameter.ActualValue = assignment;
+        results.Add(new Result("Best LAP Solution", assignment));
+      } else {
+        if (max && assignment.Quality.Value < qualities[i].Value ||
+          !max && assignment.Quality.Value > qualities[i].Value) {
+          assignment.Costs = costs;
+          assignment.Assignment = (Permutation)permutations[i].Clone();
+          assignment.Quality.Value = qualities[i].Value;
+        }
+      }
+
+      return base.Apply();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/HeuristicLab.Problems.LinearAssignment-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/HeuristicLab.Problems.LinearAssignment-3.3.csproj	(revision 8021)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/HeuristicLab.Problems.LinearAssignment-3.3.csproj	(revision 8022)
@@ -112,5 +112,10 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="HungarianAlgorithm.cs" />
+    <Compile Include="LAPAssignment.cs" />
     <None Include="Plugin.cs.frame" />
+    <Compile Include="Analyzers\BestLAPSolutionAnalyzer.cs" />
+    <Compile Include="Interfaces\ILAPEvaluator.cs" />
+    <Compile Include="LAPEvaluator.cs" />
     <Compile Include="LinearAssignmentProblem.cs" />
     <Compile Include="LinearAssignmentProblemSolver.cs" />
@@ -123,4 +128,9 @@
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
       <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
@@ -146,4 +156,9 @@
       <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
       <Name>HeuristicLab.Data-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.PermutationEncoding\3.3\HeuristicLab.Encodings.PermutationEncoding-3.3.csproj">
+      <Project>{DBECB8B0-B166-4133-BAF1-ED67C3FD7FCA}</Project>
+      <Name>HeuristicLab.Encodings.PermutationEncoding-3.3</Name>
       <Private>False</Private>
     </ProjectReference>
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/HungarianAlgorithm.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/HungarianAlgorithm.cs	(revision 8022)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/HungarianAlgorithm.cs	(revision 8022)
@@ -0,0 +1,148 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.LinearAssignment {
+  /// <summary>
+  /// A genetic algorithm.
+  /// </summary>
+  [Item("HungarianAlgorithm", "The Hungarian algorithm can be used to solve the linear assignment problem in O(n^3). It is also known as the Kuhn–Munkres algorithm or Munkres assignment algorithm.")]
+  [Creatable("Algorithms")]
+  [StorableClass]
+  public sealed class HungarianAlgorithm : EngineAlgorithm {
+    #region Problem Properties
+    public override Type ProblemType {
+      get { return typeof(LinearAssignmentProblem); }
+    }
+    public new LinearAssignmentProblem Problem {
+      get { return (LinearAssignmentProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+    #endregion
+
+    #region Parameter Properties
+    private ValueParameter<MultiAnalyzer> AnalyzerParameter {
+      get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
+    }
+
+    #endregion
+
+    #region Properties
+    public MultiAnalyzer Analyzer {
+      get { return AnalyzerParameter.Value; }
+      set { AnalyzerParameter.Value = value; }
+    }
+    private LinearAssignmentProblemSolver Solver {
+      get { return (LinearAssignmentProblemSolver)OperatorGraph.InitialOperator; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private HungarianAlgorithm(bool deserializing) : base(deserializing) { }
+    private HungarianAlgorithm(HungarianAlgorithm original, Cloner cloner)
+      : base(original, cloner) {
+      // TODO: clone your private fields here
+      AttachEventHandlers();
+    }
+    public HungarianAlgorithm()
+      : base() {
+      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the result.", new MultiAnalyzer()));
+
+      var solver = new LinearAssignmentProblemSolver();
+      OperatorGraph.InitialOperator = solver;
+
+      var placeholder = new Placeholder();
+      placeholder.Name = "(Analyzer)";
+      placeholder.OperatorParameter.ActualName = AnalyzerParameter.Name;
+      solver.Successor = placeholder;
+
+      UpdateAnalyzers();
+      AttachEventHandlers();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new HungarianAlgorithm(this, cloner);
+    }
+
+    public override void Prepare() {
+      if (Problem != null) base.Prepare();
+    }
+
+    #region Events
+    protected override void OnProblemChanged() {
+      Problem.SolutionCreatorChanged += new EventHandler(Problem_SolutionCreatorChanged);
+      Problem.EvaluatorChanged += new EventHandler(Problem_EvaluatorChanged);
+      UpdateAnalyzers();
+      Parameterize();
+      base.OnProblemChanged();
+    }
+
+    private void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
+      Parameterize();
+    }
+
+    private void Problem_EvaluatorChanged(object sender, EventArgs e) {
+      Parameterize();
+    }
+
+    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
+      UpdateAnalyzers();
+      base.Problem_OperatorsChanged(sender, e);
+    }
+    #endregion
+
+    #region Helpers
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AttachEventHandlers() {
+      if (Problem != null) {
+        Problem.SolutionCreatorChanged += new EventHandler(Problem_SolutionCreatorChanged);
+        Problem.EvaluatorChanged += new EventHandler(Problem_EvaluatorChanged);
+      }
+    }
+    private void UpdateAnalyzers() {
+      Analyzer.Operators.Clear();
+      if (Problem != null) {
+        foreach (var analyzer in Problem.OperatorsParameter.Value.OfType<IAnalyzer>()) {
+          foreach (IScopeTreeLookupParameter param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
+            param.Depth = 0;
+          Analyzer.Operators.Add(analyzer);
+        }
+      }
+    }
+    private void Parameterize() {
+      if (Problem != null) {
+        Solver.AssignmentParameter.ActualName = Problem.SolutionCreator.PermutationParameter.ActualName;
+        Solver.CostsParameter.ActualName = Problem.CostsParameter.Name;
+        Solver.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+      }
+    }
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Interfaces/ILAPEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Interfaces/ILAPEvaluator.cs	(revision 8022)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Interfaces/ILAPEvaluator.cs	(revision 8022)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.LinearAssignment {
+  public interface ILAPEvaluator : ISingleObjectiveEvaluator {
+    ILookupParameter<DoubleMatrix> CostsParameter { get; }
+    ILookupParameter<Permutation> AssignmentParameter { get; }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LAPAssignment.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LAPAssignment.cs	(revision 8022)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LAPAssignment.cs	(revision 8022)
@@ -0,0 +1,95 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.ComponentModel;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.LinearAssignment {
+  [Item("LAP Assignment", "Represents a solution to the LAP.")]
+  [StorableClass]
+  public sealed class LAPAssignment : Item, INotifyPropertyChanged {
+
+    [Storable]
+    private DoubleMatrix costs;
+    public DoubleMatrix Costs {
+      get { return costs; }
+      set {
+        bool changed = (costs != value);
+        costs = value;
+        if (changed) OnPropertyChanged("Costs");
+      }
+    }
+
+    [Storable]
+    private Permutation assignment;
+    public Permutation Assignment {
+      get { return assignment; }
+      set {
+        bool changed = (assignment != value);
+        assignment = value;
+        if (changed) OnPropertyChanged("Assignment");
+      }
+    }
+
+    [Storable]
+    private DoubleValue quality;
+    public DoubleValue Quality {
+      get { return quality; }
+      set {
+        bool changed = (quality != value);
+        quality = value;
+        if (changed) OnPropertyChanged("Quality");
+      }
+    }
+
+    [StorableConstructor]
+    private LAPAssignment(bool deserializing) : base(deserializing) { }
+    private LAPAssignment(LAPAssignment original, Cloner cloner)
+      : base(original, cloner) {
+      costs = cloner.Clone(original.costs);
+      assignment = cloner.Clone(original.assignment);
+      quality = cloner.Clone(original.quality);
+    }
+    public LAPAssignment(DoubleMatrix costs, Permutation assignment) {
+      this.costs = costs;
+      this.assignment = assignment;
+    }
+    public LAPAssignment(DoubleMatrix costs, Permutation assignment, DoubleValue quality)
+      : this(costs, assignment) {
+      this.quality = quality;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LAPAssignment(this, cloner);
+    }
+
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    private void OnPropertyChanged(string propertyName) {
+      var handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LAPEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LAPEvaluator.cs	(revision 8022)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LAPEvaluator.cs	(revision 8022)
@@ -0,0 +1,74 @@
+﻿using System;
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Encodings.PermutationEncoding;
+
+namespace HeuristicLab.Problems.LinearAssignment {
+  [Item("LAPEvaluator", "Evaluates a solution to the linear assignment problem.")]
+  [StorableClass]
+  public class LAPEvaluator : SingleSuccessorOperator, ILAPEvaluator {
+
+    public ILookupParameter<DoubleMatrix> CostsParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Costs"]; }
+    }
+    public ILookupParameter<Permutation> AssignmentParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    [StorableConstructor]
+    protected LAPEvaluator(bool deserializing) : base(deserializing) { }
+    protected LAPEvaluator(LAPEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public LAPEvaluator() : base() {
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Costs", LinearAssignmentProblem.CostsDescription));
+      Parameters.Add(new LookupParameter<Permutation>("Assignment", "The assignment solution to evaluate."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the solution."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LAPEvaluator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var costs = CostsParameter.ActualValue;
+      var assignment = AssignmentParameter.ActualValue;
+      if (costs == null || assignment == null) throw new InvalidOperationException(Name + ": Cannot find Costs or Assignment.");
+
+      int len = assignment.Length;
+      double quality = 0;
+      for (int i = 0; i < len; i++) {
+        quality += costs[i, assignment[i]];
+      }
+
+      QualityParameter.ActualValue = new DoubleValue(quality);
+      return base.Apply();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblem.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblem.cs	(revision 8021)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblem.cs	(revision 8022)
@@ -22,10 +22,13 @@
 using System;
 using System.Drawing;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Problems.LinearAssignment {
@@ -33,5 +36,7 @@
   [Creatable("Problems")]
   [StorableClass]
-  public sealed class LinearAssignmentProblem : Problem {
+  public sealed class LinearAssignmentProblem : SingleObjectiveHeuristicOptimizationProblem<ILAPEvaluator, IPermutationCreator> {
+    public static readonly string CostsDescription = "The cost matrix that describes the assignment of rows to columns.";
+
     public override Image ItemImage {
       get { return HeuristicLab.Common.Resources.VSImageLibrary.Type; }
@@ -42,9 +47,9 @@
       get { return (IValueParameter<DoubleMatrix>)Parameters["Costs"]; }
     }
-    public IValueParameter<IntArray> SolutionParameter {
-      get { return (IValueParameter<IntArray>)Parameters["Solution"]; }
+    public IValueParameter<ItemSet<Permutation>> BestKnownSolutionsParameter {
+      get { return (IValueParameter<ItemSet<Permutation>>)Parameters["BestKnownSolutions"]; }
     }
-    public IValueParameter<DoubleValue> QualityParameter {
-      get { return (IValueParameter<DoubleValue>)Parameters["Quality"]; }
+    public IValueParameter<Permutation> BestKnownSolutionParameter {
+      get { return (IValueParameter<Permutation>)Parameters["BestKnownSolution"]; }
     }
     #endregion
@@ -55,14 +60,16 @@
       set { CostsParameter.Value = value; }
     }
-    public IntArray Solution {
-      get { return SolutionParameter.Value; }
-      set { SolutionParameter.Value = value; }
+    public ItemSet<Permutation> BestKnownSolutions {
+      get { return BestKnownSolutionsParameter.Value; }
+      set { BestKnownSolutionsParameter.Value = value; }
     }
-    public DoubleValue Quality {
-      get { return QualityParameter.Value; }
-      set { QualityParameter.Value = value; }
+    public Permutation BestKnownSolution {
+      get { return BestKnownSolutionParameter.Value; }
+      set { BestKnownSolutionParameter.Value = value; }
     }
+    #endregion
 
-    #endregion
+    [Storable]
+    private BestLAPSolutionAnalyzer bestLAPSolutionAnalyzer;
 
     [StorableConstructor]
@@ -70,14 +77,19 @@
     private LinearAssignmentProblem(LinearAssignmentProblem original, Cloner cloner)
       : base(original, cloner) {
+      this.bestLAPSolutionAnalyzer = cloner.Clone(original.bestLAPSolutionAnalyzer);
       AttachEventHandlers();
     }
     public LinearAssignmentProblem()
-      : base() {
-      Parameters.Add(new ValueParameter<DoubleMatrix>("Costs", "The cost matrix that describes the assignment of rows to columns.", new DoubleMatrix(3, 3)));
-      Parameters.Add(new OptionalValueParameter<IntArray>("Solution", "An optimal solution.", null));
-      Parameters.Add(new OptionalValueParameter<DoubleValue>("Quality", "The solution quality.", null));
-
+      : base(new LAPEvaluator(), new RandomPermutationCreator()) {
+      Parameters.Add(new ValueParameter<DoubleMatrix>("Costs", CostsDescription, new DoubleMatrix(3, 3)));
+      Parameters.Add(new OptionalValueParameter<ItemSet<Permutation>>("BestKnownSolutions", "The list of best known solutions which is updated whenever a new better solution is found or may be the optimal solution if it is known beforehand.", null));
+      Parameters.Add(new OptionalValueParameter<Permutation>("BestKnownSolution", "The best known solution which is updated whenever a new better solution is found or may be the optimal solution if it is known beforehand.", null));
+      
       ((ValueParameter<DoubleMatrix>)CostsParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
 
+      bestLAPSolutionAnalyzer = new BestLAPSolutionAnalyzer();
+      SolutionCreator.PermutationParameter.ActualName = "Assignment";
+      InitializeOperators();
+      Parameterize();
       AttachEventHandlers();
     }
@@ -88,11 +100,31 @@
 
     #region Events
+    protected override void OnEvaluatorChanged() {
+      base.OnEvaluatorChanged();
+      Parameterize();
+    }
+    protected override void OnOperatorsChanged() {
+      base.OnOperatorsChanged();
+      Parameterize();
+    }
+    protected override void OnSolutionCreatorChanged() {
+      base.OnSolutionCreatorChanged();
+      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
+      Parameterize();
+    }
     private void Costs_RowsChanged(object sender, EventArgs e) {
-      if (Costs.Rows != Costs.Columns)
+      if (Costs.Rows != Costs.Columns) {
         ((IStringConvertibleMatrix)Costs).Columns = Costs.Rows;
+        Parameterize();
+      }
     }
     private void Costs_ColumnsChanged(object sender, EventArgs e) {
-      if (Costs.Rows != Costs.Columns)
+      if (Costs.Rows != Costs.Columns) {
         ((IStringConvertibleMatrix)Costs).Rows = Costs.Columns;
+        Parameterize();
+      }
+    }
+    private void SolutionCreator_PermutationParameter_ActualNameChanged(object sender, EventArgs e) {
+      Parameterize();
     }
     #endregion
@@ -107,4 +139,45 @@
       Costs.RowsChanged += new EventHandler(Costs_RowsChanged);
       Costs.ColumnsChanged += new EventHandler(Costs_ColumnsChanged);
+      SolutionCreator.PermutationParameter.ActualNameChanged += new EventHandler(SolutionCreator_PermutationParameter_ActualNameChanged);
+    }
+
+    private void InitializeOperators() {
+      Operators.AddRange(ApplicationManager.Manager.GetInstances<IPermutationOperator>());
+      Operators.RemoveAll(x => x is IMoveOperator);
+      Operators.Add(bestLAPSolutionAnalyzer);
+    }
+
+    private void Parameterize() {
+      SolutionCreator.LengthParameter.Value = new IntValue(Costs.Rows);
+      SolutionCreator.LengthParameter.Hidden = false;
+      Evaluator.CostsParameter.ActualName = CostsParameter.Name;
+      Evaluator.CostsParameter.Hidden = true;
+      Evaluator.AssignmentParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+      Evaluator.AssignmentParameter.Hidden = true;
+
+      foreach (var op in Operators.OfType<IPermutationCrossover>()) {
+        op.ParentsParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+        op.ParentsParameter.Hidden = true;
+        op.ChildParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+        op.ChildParameter.Hidden = true;
+      }
+
+      foreach (var op in Operators.OfType<IPermutationManipulator>()) {
+        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+        op.PermutationParameter.Hidden = true;
+      }
+
+      foreach (var op in Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>()) {
+        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+        op.PermutationParameter.Hidden = true;
+      }
+
+      bestLAPSolutionAnalyzer.AssignmentParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
+      bestLAPSolutionAnalyzer.BestKnownQualityParameter.ActualName = BestKnownQualityParameter.Name;
+      bestLAPSolutionAnalyzer.BestKnownSolutionParameter.ActualName = BestKnownSolutionParameter.Name;
+      bestLAPSolutionAnalyzer.BestKnownSolutionsParameter.ActualName = BestKnownSolutionsParameter.Name;
+      bestLAPSolutionAnalyzer.CostsParameter.ActualName = CostsParameter.Name;
+      bestLAPSolutionAnalyzer.MaximizationParameter.ActualName = MaximizationParameter.Name;
+      bestLAPSolutionAnalyzer.QualityParameter.ActualName = Evaluator.QualityParameter.ActualName;
     }
     #endregion
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblemSolver.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblemSolver.cs	(revision 8021)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblemSolver.cs	(revision 8022)
@@ -21,9 +21,51 @@
 
 using HeuristicLab.Common;
+using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Problems.LinearAssignment {
-  public static class LinearAssignmentProblemSolver {
+  [Item("LinearAssignmentProblemSolver", "Uses the hungarian algorithm to solve linear assignment problems.")]
+  [StorableClass]
+  public sealed class LinearAssignmentProblemSolver : SingleSuccessorOperator {
     private const int UNASSIGNED = -1;
+
+    public ILookupParameter<DoubleMatrix> CostsParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Costs"]; }
+    }
+    public ILookupParameter<Permutation> AssignmentParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Assignment"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    [StorableConstructor]
+    private LinearAssignmentProblemSolver(bool deserializing) : base(deserializing) { }
+    private LinearAssignmentProblemSolver(LinearAssignmentProblemSolver original, Cloner cloner) : base(original, cloner) { }
+    public LinearAssignmentProblemSolver()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Costs", LinearAssignmentProblem.CostsDescription));
+      Parameters.Add(new LookupParameter<Permutation>("Assignment", "The assignment solution to create."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality value of the solution."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LinearAssignmentProblemSolver(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var costs = CostsParameter.ActualValue;
+      double quality;
+      var solution = Solve(costs, out quality);
+
+      AssignmentParameter.ActualValue = new Permutation(PermutationTypes.Absolute, solution);
+      QualityParameter.ActualValue = new DoubleValue(quality);
+
+      return base.Apply();
+    }
 
     /// <summary>
Index: trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Plugin.cs.frame
===================================================================
--- trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Plugin.cs.frame	(revision 8021)
+++ trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Plugin.cs.frame	(revision 8022)
@@ -25,4 +25,5 @@
   [Plugin("HeuristicLab.Problems.LinearAssignment", "3.3.6.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.LinearAssignment-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
   [PluginDependency("HeuristicLab.Collections", "3.3")]
   [PluginDependency("HeuristicLab.Common", "3.3")]
@@ -30,4 +31,6 @@
   [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")]
