Index: /trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.Designer.cs	(revision 8092)
+++ /trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.Designer.cs	(revision 8093)
@@ -45,20 +45,14 @@
     /// </summary>
     private void InitializeComponent() {
-      this.assignmentView = new HeuristicLab.Data.Views.StringConvertibleArrayView();
       this.qualityView = new HeuristicLab.Data.Views.StringConvertibleValueView();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.assignmentDataGridView = new System.Windows.Forms.DataGridView();
+      this.RowsColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
+      this.Columns = new System.Windows.Forms.DataGridViewTextBoxColumn();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.assignmentDataGridView)).BeginInit();
       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
@@ -72,6 +66,51 @@
       this.qualityView.Name = "qualityView";
       this.qualityView.ReadOnly = true;
-      this.qualityView.Size = new System.Drawing.Size(422, 21);
+      this.qualityView.Size = new System.Drawing.Size(413, 21);
       this.qualityView.TabIndex = 1;
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.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.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
+      this.splitContainer.Location = new System.Drawing.Point(0, 30);
+      this.splitContainer.Name = "splitContainer";
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.assignmentDataGridView);
+      this.splitContainer.Size = new System.Drawing.Size(413, 324);
+      this.splitContainer.SplitterDistance = 250;
+      this.splitContainer.TabIndex = 2;
+      // 
+      // assignmentDataGridView
+      // 
+      this.assignmentDataGridView.AllowUserToAddRows = false;
+      this.assignmentDataGridView.AllowUserToDeleteRows = false;
+      this.assignmentDataGridView.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.assignmentDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+      this.assignmentDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+            this.RowsColumn,
+            this.Columns});
+      this.assignmentDataGridView.Location = new System.Drawing.Point(3, 3);
+      this.assignmentDataGridView.Name = "assignmentDataGridView";
+      this.assignmentDataGridView.ReadOnly = true;
+      this.assignmentDataGridView.Size = new System.Drawing.Size(244, 318);
+      this.assignmentDataGridView.TabIndex = 0;
+      // 
+      // RowsColumn
+      // 
+      this.RowsColumn.HeaderText = "Rows";
+      this.RowsColumn.Name = "RowsColumn";
+      this.RowsColumn.ReadOnly = true;
+      // 
+      // Columns
+      // 
+      this.Columns.HeaderText = "Columns";
+      this.Columns.Name = "Columns";
+      this.Columns.ReadOnly = true;
       // 
       // LAPAssignmentView
@@ -79,8 +118,12 @@
       this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.splitContainer);
       this.Controls.Add(this.qualityView);
-      this.Controls.Add(this.assignmentView);
       this.Name = "LAPAssignmentView";
-      this.Size = new System.Drawing.Size(422, 160);
+      this.Size = new System.Drawing.Size(413, 354);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.assignmentDataGridView)).EndInit();
       this.ResumeLayout(false);
 
@@ -89,6 +132,9 @@
     #endregion
 
-    private Data.Views.StringConvertibleArrayView assignmentView;
     private Data.Views.StringConvertibleValueView qualityView;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.DataGridView assignmentDataGridView;
+    private System.Windows.Forms.DataGridViewTextBoxColumn RowsColumn;
+    private System.Windows.Forms.DataGridViewTextBoxColumn Columns;
   }
 }
Index: /trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.cs	(revision 8092)
+++ /trunk/sources/HeuristicLab.Problems.LinearAssignment.Views/3.3/LAPAssignmentView.cs	(revision 8093)
@@ -20,7 +20,10 @@
 #endregion
 
+using System;
 using System.ComponentModel;
 using System.Windows.Forms;
+using HeuristicLab.Common;
 using HeuristicLab.Core.Views;
+using HeuristicLab.Encodings.PermutationEncoding;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
@@ -30,4 +33,6 @@
   [Content(typeof(LAPAssignment), IsDefaultView = true)]
   public partial class LAPAssignmentView : ItemView {
+    private ViewHost assignmentViewHost;
+
     public new LAPAssignment Content {
       get { return (LAPAssignment)base.Content; }
@@ -37,4 +42,8 @@
     public LAPAssignmentView() {
       InitializeComponent();
+      assignmentViewHost = new ViewHost();
+      assignmentViewHost.Dock = DockStyle.Fill;
+      assignmentViewHost.ViewsLabelVisible = true;
+      splitContainer.Panel2.Controls.Add(assignmentViewHost);
     }
 
@@ -42,4 +51,7 @@
     protected override void DeregisterContentEvents() {
       Content.PropertyChanged -= new PropertyChangedEventHandler(Content_PropertyChanged);
+      if (Content.Assignment != null) Content.Assignment.ItemChanged -= new EventHandler<EventArgs<int>>(Assignment_ItemChanged);
+      if (Content.RowNames != null) Content.RowNames.ItemChanged += new EventHandler<EventArgs<int>>(Names_ItemChanged);
+      if (Content.ColumnNames != null) Content.ColumnNames.ItemChanged -= new EventHandler<EventArgs<int>>(Names_ItemChanged);
       base.DeregisterContentEvents();
     }
@@ -47,4 +59,17 @@
       base.RegisterContentEvents();
       Content.PropertyChanged += new PropertyChangedEventHandler(Content_PropertyChanged);
+      if (Content.Assignment != null) Content.Assignment.ItemChanged += new EventHandler<EventArgs<int>>(Assignment_ItemChanged);
+      if (Content.RowNames != null) Content.RowNames.ItemChanged += new EventHandler<EventArgs<int>>(Names_ItemChanged);
+      if (Content.ColumnNames != null) Content.ColumnNames.ItemChanged += new EventHandler<EventArgs<int>>(Names_ItemChanged);
+    }
+
+    private void Assignment_ItemChanged(object sender, EventArgs<int> e) {
+      if (sender != Content.Assignment)
+        ((Permutation)sender).ItemChanged -= new EventHandler<EventArgs<int>>(Assignment_ItemChanged);
+      else UpdateAssignmentMatrix();
+    }
+
+    private void Names_ItemChanged(object sender, EventArgs<int> e) {
+      UpdateAssignmentMatrix();
     }
     #endregion
@@ -54,8 +79,10 @@
       if (Content == null) {
         qualityView.Content = null;
-        assignmentView.Content = null;
+        assignmentViewHost.Content = null;
+        assignmentDataGridView.Rows.Clear();
       } else {
         qualityView.Content = Content.Quality;
-        assignmentView.Content = Content.Assignment;
+        assignmentViewHost.Content = Content.Assignment;
+        UpdateAssignmentMatrix();
       }
     }
@@ -63,4 +90,5 @@
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
+      assignmentDataGridView.Enabled = Content != null;
     }
 
@@ -70,5 +98,19 @@
         case "Quality": qualityView.Content = Content.Quality;
           break;
-        case "Assignment": assignmentView.Content = Content.Assignment;
+        case "Assignment":
+          if (Content.Assignment != null)
+            Content.Assignment.ItemChanged += new EventHandler<EventArgs<int>>(Assignment_ItemChanged);
+          assignmentViewHost.Content = Content.Assignment;
+          UpdateAssignmentMatrix();
+          break;
+        case "RowNames":
+          if (Content.RowNames != null)
+            Content.RowNames.ItemChanged += new EventHandler<EventArgs<int>>(Names_ItemChanged);
+          UpdateAssignmentMatrix();
+          break;
+        case "ColumnNames":
+          if (Content.ColumnNames != null)
+            Content.ColumnNames.ItemChanged += new EventHandler<EventArgs<int>>(Names_ItemChanged);
+          UpdateAssignmentMatrix();
           break;
         default: break;
@@ -76,4 +118,25 @@
     }
     #endregion
+
+    private void UpdateAssignmentMatrix() {
+      assignmentDataGridView.Rows.Clear();
+      if (Content.Assignment != null) {
+        string rowName, colName;
+        var rows = new DataGridViewRow[Content.Assignment.Length];
+        for (int i = 0; i < Content.Assignment.Length; i++) {
+          if (Content.RowNames != null && Content.RowNames.Length > i)
+            rowName = Content.RowNames[i];
+          else rowName = "Row " + (i + 1).ToString();
+          if (Content.ColumnNames != null && Content.ColumnNames.Length > Content.Assignment[i])
+            colName = Content.ColumnNames[Content.Assignment[i]];
+          else colName = "Column " + (Content.Assignment[i] + 1).ToString();
+          rows[i] = new DataGridViewRow();
+          rows[i].CreateCells(assignmentDataGridView, new string[] { rowName, colName });
+        }
+        assignmentDataGridView.Rows.AddRange(rows);
+        assignmentDataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
+      }
+    }
+
   }
 }
Index: /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Analyzers/BestLAPSolutionAnalyzer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Analyzers/BestLAPSolutionAnalyzer.cs	(revision 8092)
+++ /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/Analyzers/BestLAPSolutionAnalyzer.cs	(revision 8093)
@@ -42,4 +42,10 @@
       get { return (ILookupParameter<DoubleMatrix>)Parameters["Costs"]; }
     }
+    public IValueLookupParameter<StringArray> RowNamesParameter {
+      get { return (IValueLookupParameter<StringArray>)Parameters["RowNames"]; }
+    }
+    public IValueLookupParameter<StringArray> ColumnNamesParameter {
+      get { return (IValueLookupParameter<StringArray>)Parameters["ColumnNames"]; }
+    }
     public IScopeTreeLookupParameter<Permutation> AssignmentParameter {
       get { return (IScopeTreeLookupParameter<Permutation>)Parameters["Assignment"]; }
@@ -71,4 +77,6 @@
       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 ValueLookupParameter<StringArray>("RowNames", LinearAssignmentProblem.RowNamesDescription));
+      Parameters.Add(new ValueLookupParameter<StringArray>("ColumnNames", LinearAssignmentProblem.ColumnNamesDescription));
       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."));
@@ -86,4 +94,6 @@
     public override IOperation Apply() {
       var costs = CostsParameter.ActualValue;
+      var rowNames = RowNamesParameter.ActualValue;
+      var columnNames = ColumnNamesParameter.ActualValue;
       var permutations = AssignmentParameter.ActualValue;
       var qualities = QualityParameter.ActualValue;
@@ -122,5 +132,5 @@
       LAPAssignment assignment = BestSolutionParameter.ActualValue;
       if (assignment == null) {
-        assignment = new LAPAssignment(costs, (Permutation)permutations[i].Clone(), new DoubleValue(qualities[i].Value));
+        assignment = new LAPAssignment(costs, rowNames, columnNames, (Permutation)permutations[i].Clone(), new DoubleValue(qualities[i].Value));
         BestSolutionParameter.ActualValue = assignment;
         results.Add(new Result("Best LAP Solution", assignment));
@@ -131,4 +141,10 @@
           assignment.Assignment = (Permutation)permutations[i].Clone();
           assignment.Quality.Value = qualities[i].Value;
+          if (rowNames != null)
+            assignment.RowNames = rowNames;
+          else assignment.RowNames = null;
+          if (columnNames != null)
+            assignment.ColumnNames = columnNames;
+          else assignment.ColumnNames = null;
         }
       }
Index: /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/HungarianAlgorithm.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/HungarianAlgorithm.cs	(revision 8092)
+++ /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/HungarianAlgorithm.cs	(revision 8093)
@@ -52,5 +52,4 @@
       get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
     }
-
     #endregion
 
@@ -69,5 +68,4 @@
     private HungarianAlgorithm(HungarianAlgorithm original, Cloner cloner)
       : base(original, cloner) {
-      // TODO: clone your private fields here
       AttachEventHandlers();
     }
@@ -86,4 +84,6 @@
       UpdateAnalyzers();
       AttachEventHandlers();
+
+      Problem = new LinearAssignmentProblem();
     }
 
Index: /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LAPAssignment.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LAPAssignment.cs	(revision 8092)
+++ /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LAPAssignment.cs	(revision 8093)
@@ -44,4 +44,26 @@
 
     [Storable]
+    private StringArray rowNames;
+    public StringArray RowNames {
+      get { return rowNames; }
+      set {
+        bool changed = (rowNames != value);
+        rowNames = value;
+        if (changed) OnPropertyChanged("RowNames");
+      }
+    }
+
+    [Storable]
+    private StringArray columnNames;
+    public StringArray ColumnNames {
+      get { return columnNames; }
+      set {
+        bool changed = (columnNames != value);
+        columnNames = value;
+        if (changed) OnPropertyChanged("ColumnNames");
+      }
+    }
+
+    [Storable]
     private Permutation assignment;
     public Permutation Assignment {
@@ -81,4 +103,13 @@
       this.quality = quality;
     }
+    public LAPAssignment(DoubleMatrix costs, StringArray rowNames, StringArray columnNames, Permutation assignment)
+      : this(costs, assignment) {
+      this.rowNames = rowNames;
+      this.columnNames = columnNames;
+    }
+    public LAPAssignment(DoubleMatrix costs, StringArray rowNames, StringArray columnNames, Permutation assignment, DoubleValue quality)
+      : this(costs, rowNames, columnNames, assignment) {
+      this.quality = quality;
+    }
 
     public override IDeepCloneable Clone(Cloner cloner) {
Index: /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblem.cs	(revision 8092)
+++ /trunk/sources/HeuristicLab.Problems.LinearAssignment/3.3/LinearAssignmentProblem.cs	(revision 8093)
@@ -38,4 +38,6 @@
   public sealed class LinearAssignmentProblem : SingleObjectiveHeuristicOptimizationProblem<ILAPEvaluator, IPermutationCreator> {
     public static readonly string CostsDescription = "The cost matrix that describes the assignment of rows to columns.";
+    public static readonly string RowNamesDescription = "The elements represented by the rows of the costs matrix.";
+    public static readonly string ColumnNamesDescription = "The elements represented by the columns of the costs matrix.";
 
     public override Image ItemImage {
@@ -52,4 +54,10 @@
     public IValueParameter<Permutation> BestKnownSolutionParameter {
       get { return (IValueParameter<Permutation>)Parameters["BestKnownSolution"]; }
+    }
+    public IValueParameter<StringArray> RowNamesParameter {
+      get { return (IValueParameter<StringArray>)Parameters["RowNames"]; }
+    }
+    public IValueParameter<StringArray> ColumnNamesParameter {
+      get { return (IValueParameter<StringArray>)Parameters["ColumnNames"]; }
     }
     #endregion
@@ -59,4 +67,12 @@
       get { return CostsParameter.Value; }
       set { CostsParameter.Value = value; }
+    }
+    public StringArray RowNames {
+      get { return RowNamesParameter.Value; }
+      set { RowNamesParameter.Value = value; }
+    }
+    public StringArray ColumnNames {
+      get { return ColumnNamesParameter.Value; }
+      set { ColumnNamesParameter.Value = value; }
     }
     public ItemSet<Permutation> BestKnownSolutions {
@@ -85,6 +101,16 @@
       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));
-      
+      Parameters.Add(new OptionalValueParameter<StringArray>("RowNames", RowNamesDescription));
+      Parameters.Add(new OptionalValueParameter<StringArray>("ColumnNames", ColumnNamesDescription));
+
       ((ValueParameter<DoubleMatrix>)CostsParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
+      ((OptionalValueParameter<StringArray>)RowNamesParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
+      ((OptionalValueParameter<StringArray>)ColumnNamesParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
+
+      RowNames = new StringArray(new string[] { "Human", "Von Neumann machine", "Quantum computer" });
+      ColumnNames = new StringArray(new string[] { "Find a person's e-mail address", "Compute first 1000 decimals of Pi", "Factorize large integers" });
+      Costs[0, 0] = 1; Costs[0, 1] = 10; Costs[0, 2] = 100;
+      Costs[1, 0] = 10; Costs[1, 1] = 1; Costs[1, 2] = 100;
+      Costs[2, 0] = 100; Costs[2, 1] = 10; Costs[2, 1] = 1;
 
       bestLAPSolutionAnalyzer = new BestLAPSolutionAnalyzer();
