Index: /branches/QAP/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs
===================================================================
--- /branches/QAP/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs	(revision 5931)
+++ /branches/QAP/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs	(revision 5932)
@@ -68,5 +68,5 @@
     /// In every iteration it tries to find the best location for every item.</param>
     /// <returns>A Nx2 matrix where the first column represents the x- and the second column the y coordinates.</returns>
-    public static DoubleMatrix KruskalShepard(DoubleMatrix dissimilarities, DoubleMatrix coordinates, int maximumIterations = 100) {
+    public static DoubleMatrix KruskalShepard(DoubleMatrix dissimilarities, DoubleMatrix coordinates, int maximumIterations = 20) {
       int dimension = dissimilarities.Rows;
       if (dimension != dissimilarities.Columns || coordinates.Rows != dimension) throw new ArgumentException("The number of coordinates and the number of rows and columns in the dissimilarities matrix do not match.");
Index: /branches/QAP/HeuristicLab.Analysis/3.3/Tests/MultidimensionalScalingTest.cs
===================================================================
--- /branches/QAP/HeuristicLab.Analysis/3.3/Tests/MultidimensionalScalingTest.cs	(revision 5931)
+++ /branches/QAP/HeuristicLab.Analysis/3.3/Tests/MultidimensionalScalingTest.cs	(revision 5932)
@@ -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 HeuristicLab.Data;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/HeuristicLab.Problems.QuadraticAssignment.Views-3.3.csproj
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/HeuristicLab.Problems.QuadraticAssignment.Views-3.3.csproj	(revision 5931)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/HeuristicLab.Problems.QuadraticAssignment.Views-3.3.csproj	(revision 5932)
@@ -143,9 +143,9 @@
       <DependentUpon>QAPAssignmentView.cs</DependentUpon>
     </Compile>
-    <Compile Include="QAPView.cs">
+    <Compile Include="QAPVisualizationControl.cs">
       <SubType>UserControl</SubType>
     </Compile>
-    <Compile Include="QAPView.Designer.cs">
-      <DependentUpon>QAPView.cs</DependentUpon>
+    <Compile Include="QAPVisualizationControl.Designer.cs">
+      <DependentUpon>QAPVisualizationControl.cs</DependentUpon>
     </Compile>
     <Compile Include="QuadraticAssignmentProblemView.cs">
@@ -167,6 +167,6 @@
       <DependentUpon>QAPAssignmentView.cs</DependentUpon>
     </EmbeddedResource>
-    <EmbeddedResource Include="QAPView.resx">
-      <DependentUpon>QAPView.cs</DependentUpon>
+    <EmbeddedResource Include="QAPVisualizationControl.resx">
+      <DependentUpon>QAPVisualizationControl.cs</DependentUpon>
     </EmbeddedResource>
     <EmbeddedResource Include="QuadraticAssignmentProblemView.resx">
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPAssignmentView.Designer.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPAssignmentView.Designer.cs	(revision 5931)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPAssignmentView.Designer.cs	(revision 5932)
@@ -53,5 +53,5 @@
       this.assignmentGroupBox = new System.Windows.Forms.GroupBox();
       this.assignmentViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
-      this.qapView = new HeuristicLab.Problems.QuadraticAssignment.Views.QAPView();
+      this.qapView = new HeuristicLab.Problems.QuadraticAssignment.Views.QAPVisualizationControl();
       ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
       this.splitContainer.Panel1.SuspendLayout();
@@ -220,5 +220,5 @@
     private System.Windows.Forms.GroupBox assignmentGroupBox;
     private MainForm.WindowsForms.ViewHost assignmentViewHost;
-    private QAPView qapView;
+    private QAPVisualizationControl qapView;
   }
 }
Index: anches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPView.Designer.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPView.Designer.cs	(revision 5931)
+++ 	(revision )
@@ -1,165 +1,0 @@
-﻿#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
-
-namespace HeuristicLab.Problems.QuadraticAssignment.Views {
-  partial class QAPView {
-    /// <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) {
-      CustomDispose(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.redrawButton = new System.Windows.Forms.Button();
-      this.distancesRadioButton = new System.Windows.Forms.RadioButton();
-      this.weightsRadioButton = new System.Windows.Forms.RadioButton();
-      this.pictureBox = new System.Windows.Forms.PictureBox();
-      this.stressLabel = new System.Windows.Forms.Label();
-      this.assignmentRadioButton = new System.Windows.Forms.RadioButton();
-      this.label1 = new System.Windows.Forms.Label();
-      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
-      this.SuspendLayout();
-      // 
-      // redrawButton
-      // 
-      this.redrawButton.Location = new System.Drawing.Point(243, 3);
-      this.redrawButton.Name = "redrawButton";
-      this.redrawButton.Size = new System.Drawing.Size(74, 23);
-      this.redrawButton.TabIndex = 7;
-      this.redrawButton.Text = "Redraw";
-      this.redrawButton.UseVisualStyleBackColor = true;
-      this.redrawButton.Click += new System.EventHandler(this.Redraw);
-      // 
-      // distancesRadioButton
-      // 
-      this.distancesRadioButton.AutoSize = true;
-      this.distancesRadioButton.Checked = true;
-      this.distancesRadioButton.Location = new System.Drawing.Point(3, 6);
-      this.distancesRadioButton.Name = "distancesRadioButton";
-      this.distancesRadioButton.Size = new System.Drawing.Size(72, 17);
-      this.distancesRadioButton.TabIndex = 6;
-      this.distancesRadioButton.TabStop = true;
-      this.distancesRadioButton.Text = "Distances";
-      this.distancesRadioButton.UseVisualStyleBackColor = true;
-      this.distancesRadioButton.CheckedChanged += new System.EventHandler(this.Redraw);
-      // 
-      // weightsRadioButton
-      // 
-      this.weightsRadioButton.AutoSize = true;
-      this.weightsRadioButton.Location = new System.Drawing.Point(81, 6);
-      this.weightsRadioButton.Name = "weightsRadioButton";
-      this.weightsRadioButton.Size = new System.Drawing.Size(64, 17);
-      this.weightsRadioButton.TabIndex = 5;
-      this.weightsRadioButton.Text = "Weights";
-      this.weightsRadioButton.UseVisualStyleBackColor = true;
-      this.weightsRadioButton.CheckedChanged += new System.EventHandler(this.Redraw);
-      // 
-      // pictureBox
-      // 
-      this.pictureBox.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.pictureBox.BackColor = System.Drawing.Color.White;
-      this.pictureBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
-      this.pictureBox.Location = new System.Drawing.Point(0, 32);
-      this.pictureBox.Name = "pictureBox";
-      this.pictureBox.Size = new System.Drawing.Size(574, 422);
-      this.pictureBox.TabIndex = 4;
-      this.pictureBox.TabStop = false;
-      this.pictureBox.SizeChanged += new System.EventHandler(this.pictureBox_SizeChanged);
-      // 
-      // stressLabel
-      // 
-      this.stressLabel.AutoSize = true;
-      this.stressLabel.Location = new System.Drawing.Point(423, 8);
-      this.stressLabel.Name = "stressLabel";
-      this.stressLabel.Size = new System.Drawing.Size(10, 13);
-      this.stressLabel.TabIndex = 8;
-      this.stressLabel.Text = "-";
-      // 
-      // assignmentRadioButton
-      // 
-      this.assignmentRadioButton.AutoSize = true;
-      this.assignmentRadioButton.Location = new System.Drawing.Point(151, 6);
-      this.assignmentRadioButton.Name = "assignmentRadioButton";
-      this.assignmentRadioButton.Size = new System.Drawing.Size(79, 17);
-      this.assignmentRadioButton.TabIndex = 5;
-      this.assignmentRadioButton.Text = "Assignment";
-      this.assignmentRadioButton.UseVisualStyleBackColor = true;
-      this.assignmentRadioButton.CheckedChanged += new System.EventHandler(this.Redraw);
-      // 
-      // label1
-      // 
-      this.label1.AutoSize = true;
-      this.label1.Location = new System.Drawing.Point(323, 8);
-      this.label1.Name = "label1";
-      this.label1.Size = new System.Drawing.Size(94, 13);
-      this.label1.TabIndex = 8;
-      this.label1.Text = "Normalized Stress:";
-      // 
-      // QAPView
-      // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-      this.Controls.Add(this.label1);
-      this.Controls.Add(this.stressLabel);
-      this.Controls.Add(this.redrawButton);
-      this.Controls.Add(this.distancesRadioButton);
-      this.Controls.Add(this.assignmentRadioButton);
-      this.Controls.Add(this.weightsRadioButton);
-      this.Controls.Add(this.pictureBox);
-      this.Name = "QAPView";
-      this.Size = new System.Drawing.Size(574, 454);
-      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
-      this.ResumeLayout(false);
-      this.PerformLayout();
-
-    }
-
-    #endregion
-
-    private System.Windows.Forms.Button redrawButton;
-    private System.Windows.Forms.RadioButton distancesRadioButton;
-    private System.Windows.Forms.RadioButton weightsRadioButton;
-    private System.Windows.Forms.PictureBox pictureBox;
-    private System.Windows.Forms.Label stressLabel;
-    private System.Windows.Forms.RadioButton assignmentRadioButton;
-    private System.Windows.Forms.Label label1;
-
-  }
-}
Index: anches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPView.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPView.cs	(revision 5931)
+++ 	(revision )
@@ -1,484 +1,0 @@
-﻿#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.Drawing;
-using System.Drawing.Drawing2D;
-using System.Drawing.Text;
-using System.Globalization;
-using System.Windows.Forms;
-using HeuristicLab.Analysis;
-using HeuristicLab.Common;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.PermutationEncoding;
-
-namespace HeuristicLab.Problems.QuadraticAssignment.Views {
-  public partial class QAPView : UserControl {
-    private Bitmap bitmap;
-    private Bitmap defaultBitmap;
-
-    #region Properties
-    private DoubleMatrix distances;
-    public DoubleMatrix Distances {
-      get { return distances; }
-      set {
-        DeregisterDistancesEvents();
-        distances = value;
-        RegisterDistancesEvents();
-        OnRedraw();
-      }
-    }
-
-    private DoubleMatrix weights;
-    public DoubleMatrix Weights {
-      get { return weights; }
-      set {
-        DeregisterWeightsEvents();
-        weights = value;
-        RegisterWeightsEvents();
-        OnRedraw();
-      }
-    }
-
-    private Permutation assignment;
-    public Permutation Assignment {
-      get { return assignment; }
-      set {
-        DeregisterAssignmentEvents();
-        assignment = value;
-        RegisterAssignmentEvents();
-        OnRedraw();
-      }
-    }
-    #endregion
-
-    #region Event Handling
-    private void DeregisterDistancesEvents() {
-      if (Distances != null) {
-        Distances.Reset -= new EventHandler(Redraw);
-        Distances.RowsChanged -= new EventHandler(Redraw);
-        Distances.ColumnsChanged -= new EventHandler(Redraw);
-        Distances.ItemChanged -= new EventHandler<EventArgs<int, int>>(Redraw);
-      }
-    }
-
-    private void RegisterDistancesEvents() {
-      if (Distances != null) {
-        Distances.Reset += new EventHandler(Redraw);
-        Distances.RowsChanged += new EventHandler(Redraw);
-        Distances.ColumnsChanged += new EventHandler(Redraw);
-        Distances.ItemChanged += new EventHandler<EventArgs<int, int>>(Redraw);
-      }
-    }
-
-    private void DeregisterWeightsEvents() {
-      if (Weights != null) {
-        Weights.Reset -= new EventHandler(Redraw);
-        Weights.RowsChanged -= new EventHandler(Redraw);
-        Weights.ColumnsChanged -= new EventHandler(Redraw);
-        Weights.ItemChanged -= new EventHandler<EventArgs<int, int>>(Redraw);
-      }
-    }
-
-    private void RegisterWeightsEvents() {
-      if (Weights != null) {
-        Weights.Reset += new EventHandler(Redraw);
-        Weights.RowsChanged += new EventHandler(Redraw);
-        Weights.ColumnsChanged += new EventHandler(Redraw);
-        Weights.ItemChanged += new EventHandler<EventArgs<int, int>>(Redraw);
-      }
-    }
-
-    private void DeregisterAssignmentEvents() {
-      if (Assignment != null) {
-        Assignment.Reset -= new EventHandler(Redraw);
-        Assignment.ItemChanged -= new EventHandler<EventArgs<int>>(Redraw);
-      }
-    }
-
-    private void RegisterAssignmentEvents() {
-      if (Assignment != null) {
-        Assignment.Reset += new EventHandler(Redraw);
-        Assignment.ItemChanged += new EventHandler<EventArgs<int>>(Redraw);
-      }
-    }
-
-    private void Redraw(object sender, EventArgs e) {
-      if (sender is RadioButton && !((RadioButton)sender).Checked)
-        return;
-      OnRedraw();
-    }
-
-    private void Redraw(object sender, EventArgs<int, int> e) {
-      OnRedraw();
-    }
-
-    private void pictureBox_SizeChanged(object sender, EventArgs e) {
-      SetupDefaultBitmap();
-      OnRedraw();
-    }
-    #endregion
-
-    public QAPView() {
-      InitializeComponent();
-      SetupDefaultBitmap();
-    }
-
-    private void SetupDefaultBitmap() {
-      if (defaultBitmap != null) {
-        defaultBitmap.Dispose();
-        defaultBitmap = null;
-      }
-      if (pictureBox.Width > 0 && pictureBox.Height > 0) {
-        defaultBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
-        WriteCenteredTextToBitmap(ref defaultBitmap, "No visualization available");
-      }
-    }
-
-    private void WriteCenteredTextToBitmap(ref Bitmap bitmap, string text) {
-      if (bitmap == null) return;
-      using (Graphics g = Graphics.FromImage(bitmap)) {
-        g.TextRenderingHint = TextRenderingHint.AntiAlias;
-        g.SmoothingMode = SmoothingMode.AntiAlias;
-
-        SizeF strSize = g.MeasureString(text, Font);
-        g.DrawString(text, Font, Brushes.Black, (float)(pictureBox.Width - strSize.Width) / 2.0f, (float)(pictureBox.Height - strSize.Height) / 2.0f);
-      }
-    }
-
-    private void OnRedraw() {
-      if (InvokeRequired) {
-        Invoke((Action)OnRedraw, null);
-      } else {
-        GenerateImage();
-      }
-    }
-
-    private void GenerateImage() {
-      if (pictureBox.Width > 0 && pictureBox.Height > 0) {
-        Bitmap newBitmap = null;
-        stressLabel.Text = "-";
-        if (distancesRadioButton.Checked && Distances != null && Distances.Rows > 0
-          && Distances.Rows == Distances.Columns) {
-          if (Distances.Rows > 30) {
-            newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
-            WriteCenteredTextToBitmap(ref newBitmap, "Problem dimension too large for visualization.");
-          } else newBitmap = GenerateDistanceImage();
-        } else if (weightsRadioButton.Checked && Weights != null && Weights.Rows > 0
-          && Weights.Rows == Weights.Columns) {
-          if (Weights.Rows > 30) {
-            newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
-            WriteCenteredTextToBitmap(ref newBitmap, "Problem dimension too large for visualization.");
-          } else newBitmap = GenerateWeightsImage();
-        } else if (assignmentRadioButton.Checked
-          && Assignment != null && Assignment.Length > 0
-          && Weights != null && Weights.Rows > 0
-          && Distances != null && Distances.Rows > 0
-          && Weights.Rows == Weights.Columns
-          && Distances.Rows == Distances.Columns
-          && Assignment.Length == Weights.Rows
-          && Assignment.Length == Distances.Rows
-          && Assignment.Validate()) {
-          if (Assignment.Length > 30) {
-            newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
-            WriteCenteredTextToBitmap(ref newBitmap, "Problem dimension too large for visualization.");
-          } else newBitmap = GenerateAssignmentImage();
-        }
-
-        pictureBox.Image = newBitmap != null ? newBitmap : defaultBitmap;
-        if (bitmap != null) bitmap.Dispose();
-        if (newBitmap != null) bitmap = newBitmap;
-        else bitmap = null;
-      }
-    }
-
-    #region Draw distances
-    private Bitmap GenerateDistanceImage() {
-      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
-        Bitmap newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
-
-        DoubleMatrix coordinates;
-        double stress = double.NaN;
-        try {
-          coordinates = MultidimensionalScaling.KruskalShepard(distances);
-          stress = MultidimensionalScaling.CalculateNormalizedStress(distances, coordinates);
-          stressLabel.Text = stress.ToString("0.00", CultureInfo.CurrentCulture.NumberFormat);
-        } catch {
-          WriteCenteredTextToBitmap(ref newBitmap, "Distance matrix is not symmetric");
-          stressLabel.Text = "-";
-          return newBitmap;
-        }
-        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
-        double maxDistance = double.MinValue;
-        for (int i = 0; i < coordinates.Rows; i++) {
-          if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
-          if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
-          if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
-          if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
-
-          for (int j = i + 1; j < coordinates.Rows; j++) {
-            if (distances[i, j] > maxDistance) maxDistance = distances[i, j];
-            if (distances[j, i] > maxDistance) maxDistance = distances[j, i];
-          }
-        }
-
-        int border = 20;
-        double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1;
-        double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1;
-
-        Point[] points = new Point[coordinates.Rows];
-        for (int i = 0; i < coordinates.Rows; i++)
-          points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
-                                newBitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
-
-        Random rand = new Random();
-        using (Graphics graphics = Graphics.FromImage(newBitmap)) {
-          graphics.SmoothingMode = SmoothingMode.AntiAlias;
-          graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
-          graphics.DrawString("Showing locations spaced out according to their distances", Font, Brushes.Black, 5, 2);
-
-          for (int i = 0; i < coordinates.Rows - 1; i++) {
-            for (int j = i + 1; j < coordinates.Rows; j++) {
-              Point start = points[i], end = points[j];
-              string caption = String.Empty;
-              double d = Math.Max(distances[i, j], distances[j, i]);
-              float width = (float)Math.Ceiling(5.0 * d / maxDistance);
-              if (d > 0) {
-                graphics.DrawLine(new Pen(Color.IndianRed, width), start, end);
-                if (distances[i, j] != distances[j, i])
-                  caption = distances[i, j].ToString(CultureInfo.InvariantCulture.NumberFormat)
-                    + " / " + distances[j, i].ToString(CultureInfo.InvariantCulture.NumberFormat);
-                else
-                  caption = distances[i, j].ToString(CultureInfo.InvariantCulture.NumberFormat);
-              }
-              if (!String.IsNullOrEmpty(caption)) {
-                double r = rand.NextDouble();
-                while (r < 0.2 || r > 0.8) r = rand.NextDouble();
-                float x = (float)(start.X + (end.X - start.X) * r + 5);
-                float y = (float)(start.Y + (end.Y - start.Y) * r + 5);
-                graphics.DrawString(caption, Font, Brushes.Black, x, y);
-              }
-            }
-          }
-
-          for (int i = 0; i < points.Length; i++) {
-            Point p = new Point(points[i].X - 3, points[i].Y - 3);
-            graphics.FillRectangle(Brushes.Black, p.X, p.Y, 8, 8);
-            graphics.DrawString(i.ToString(), Font, Brushes.Black, p.X, p.Y + 10);
-          }
-        }
-        return newBitmap;
-      }
-      return null;
-    }
-    #endregion
-
-    #region Draw weights
-    private Bitmap GenerateWeightsImage() {
-      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
-        Bitmap newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
-
-        double maxWeight = double.MinValue;
-        for (int i = 0; i < weights.Rows; i++)
-          for (int j = i + 1; j < weights.Rows; j++) {
-            if (weights[i, j] > maxWeight)
-              maxWeight = weights[i, j] + weights[j, i];
-          }
-
-        DoubleMatrix distances = new DoubleMatrix(weights.Rows, weights.Columns);
-        for (int i = 0; i < distances.Rows; i++)
-          for (int j = 0; j < distances.Columns; j++) {
-            distances[i, j] = maxWeight + 1 - weights[i, j];
-          }
-
-        DoubleMatrix coordinates;
-        double stress = double.NaN;
-        try {
-          coordinates = MultidimensionalScaling.KruskalShepard(distances);
-          stress = MultidimensionalScaling.CalculateNormalizedStress(distances, coordinates);
-          stressLabel.Text = stress.ToString("0.00", CultureInfo.CurrentCulture.NumberFormat);
-        } catch {
-          WriteCenteredTextToBitmap(ref newBitmap, "Weights matrix is not symmetric");
-          stressLabel.Text = "-";
-          return newBitmap;
-        }
-        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
-        for (int i = 0; i < coordinates.Rows; i++) {
-          if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
-          if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
-          if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
-          if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
-        }
-
-        int border = 20;
-        double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1;
-        double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1;
-
-        Point[] points = new Point[coordinates.Rows];
-        for (int i = 0; i < coordinates.Rows; i++)
-          points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
-                                newBitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
-
-        Random rand = new Random();
-        using (Graphics graphics = Graphics.FromImage(newBitmap)) {
-          graphics.SmoothingMode = SmoothingMode.AntiAlias;
-          graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
-          graphics.DrawString("Showing facilities spaced out according to their weights", Font, Brushes.Black, 5, 2);
-
-          for (int i = 0; i < coordinates.Rows - 1; i++) {
-            for (int j = i + 1; j < coordinates.Rows; j++) {
-              Point start = points[i], end = points[j];
-              string caption = String.Empty;
-              double d = Math.Max(distances[i, j], distances[j, i]);
-              double w = weights[i, j];
-              if (w > 0) {
-                float width = (float)Math.Ceiling(3.0 * w / maxWeight);
-                graphics.DrawLine(new Pen(Color.MediumBlue, width), start, end);
-                caption = w.ToString(CultureInfo.InvariantCulture.NumberFormat);
-              }
-              if (!String.IsNullOrEmpty(caption)) {
-                double r = rand.NextDouble();
-                while (r < 0.2 || r > 0.8) r = rand.NextDouble();
-                float x = (float)(start.X + (end.X - start.X) * r + 5);
-                float y = (float)(start.Y + (end.Y - start.Y) * r + 5);
-                graphics.DrawString(caption, Font, Brushes.Black, x, y);
-              }
-            }
-          }
-          for (int i = 0; i < points.Length; i++) {
-            Point p = new Point(points[i].X - 3, points[i].Y - 3);
-            graphics.FillRectangle(Brushes.Black, p.X, p.Y, 8, 8);
-            graphics.DrawString(i.ToString(), Font, Brushes.Black, p.X, p.Y + 10);
-          }
-        }
-        return newBitmap;
-      }
-      return null;
-    }
-    #endregion
-
-    #region Draw assignment
-    private Bitmap GenerateAssignmentImage() {
-      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
-        Bitmap newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
-
-        for (int i = 0; i < distances.Rows; i++) {
-          for (int j = i + 1; j < distances.Rows; j++) {
-            if (distances[i, j] != distances[j, i]) {
-              WriteCenteredTextToBitmap(ref newBitmap, "Distance matrix is not symmetric");
-              stressLabel.Text = "-";
-              return newBitmap;
-            }
-            if (weights[i, j] != weights[j, i]) {
-              WriteCenteredTextToBitmap(ref newBitmap, "Weights matrix is not symmetric");
-              stressLabel.Text = "-";
-              return newBitmap;
-            }
-          }
-        }
-
-        DoubleMatrix coordinates = null;
-        double stress = double.NaN;
-        try {
-          coordinates = MultidimensionalScaling.KruskalShepard(distances);
-          stress = MultidimensionalScaling.CalculateNormalizedStress(distances, coordinates);
-          stressLabel.Text = stress.ToString("0.00", CultureInfo.CurrentCulture.NumberFormat);
-        } catch {
-          WriteCenteredTextToBitmap(ref newBitmap, "Unknown error");
-          stressLabel.Text = "-";
-          return newBitmap;
-        }
-
-        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
-        double maxWeight = double.MinValue;
-        for (int i = 0; i < coordinates.Rows; i++) {
-          if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
-          if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
-          if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
-          if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
-
-          for (int j = i + 1; j < coordinates.Rows; j++) {
-            if (weights[i, j] > maxWeight) maxWeight = weights[i, j];
-          }
-        }
-
-        int border = 20;
-        double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1;
-        double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1;
-
-        Point[] points = new Point[coordinates.Rows];
-        for (int i = 0; i < coordinates.Rows; i++)
-          points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
-                                newBitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
-
-        Random rand = new Random();
-        using (Graphics graphics = Graphics.FromImage(newBitmap)) {
-          graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
-          graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
-
-          for (int i = 0; i < assignment.Length - 1; i++) {
-            for (int j = i + 1; j < assignment.Length; j++) {
-              Point start, end;
-              string caption = String.Empty;
-              double d = distances[i, j];
-              start = points[assignment[i]];
-              end = points[assignment[j]];
-              double w = weights[i, j];
-              if (w > 0) {
-                float width = (float)Math.Ceiling(4.0 * w / maxWeight);
-                graphics.DrawLine(new Pen(Color.MediumBlue, width), start, end);
-                caption = w.ToString(CultureInfo.InvariantCulture.NumberFormat);
-              }
-              if (!String.IsNullOrEmpty(caption)) {
-                double r = rand.NextDouble();
-                while (r < 0.2 || r > 0.8) r = rand.NextDouble();
-                float x = (float)(start.X + (end.X - start.X) * r + 5);
-                float y = (float)(start.Y + (end.Y - start.Y) * r + 5);
-                graphics.DrawString(caption, Font, Brushes.Black, x, y);
-              }
-            }
-          }
-
-          for (int i = 0; i < points.Length; i++) {
-            Point p = new Point(points[i].X - 3, points[i].Y - 3);
-            graphics.FillRectangle(Brushes.Black, p.X, p.Y, 8, 8);
-            graphics.DrawString(i.ToString(), Font, Brushes.Black, p.X, p.Y + 10);
-          }
-        }
-        return newBitmap;
-      }
-      return null;
-    }
-    #endregion
-
-    private void CustomDispose(bool disposing) {
-      DeregisterDistancesEvents();
-      DeregisterWeightsEvents();
-      DeregisterAssignmentEvents();
-      if (bitmap != null) bitmap.Dispose();
-      bitmap = null;
-      if (defaultBitmap != null) {
-        defaultBitmap.Dispose();
-        defaultBitmap = null;
-      }
-    }
-  }
-}
Index: anches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPView.resx
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPView.resx	(revision 5931)
+++ 	(revision )
@@ -1,120 +1,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!-- 
-    Microsoft ResX Schema 
-    
-    Version 2.0
-    
-    The primary goals of this format is to allow a simple XML format 
-    that is mostly human readable. The generation and parsing of the 
-    various data types are done through the TypeConverter classes 
-    associated with the data types.
-    
-    Example:
-    
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-                
-    There are any number of "resheader" rows that contain simple 
-    name/value pairs.
-    
-    Each data row contains a name, and value. The row also contains a 
-    type or mimetype. Type corresponds to a .NET class that support 
-    text/value conversion through the TypeConverter architecture. 
-    Classes that don't support this are serialized and stored with the 
-    mimetype set.
-    
-    The mimetype is used for serialized objects, and tells the 
-    ResXResourceReader how to depersist the object. This is currently not 
-    extensible. For a given mimetype the value must be set accordingly:
-    
-    Note - application/x-microsoft.net.object.binary.base64 is the format 
-    that the ResXResourceWriter will generate, however the reader can 
-    read any of the formats listed below.
-    
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-    
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with 
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array 
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-</root>
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPVisualizationControl.Designer.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPVisualizationControl.Designer.cs	(revision 5932)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPVisualizationControl.Designer.cs	(revision 5932)
@@ -0,0 +1,165 @@
+﻿#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
+
+namespace HeuristicLab.Problems.QuadraticAssignment.Views {
+  partial class QAPVisualizationControl {
+    /// <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) {
+      CustomDispose(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.redrawButton = new System.Windows.Forms.Button();
+      this.distancesRadioButton = new System.Windows.Forms.RadioButton();
+      this.weightsRadioButton = new System.Windows.Forms.RadioButton();
+      this.pictureBox = new System.Windows.Forms.PictureBox();
+      this.stressLabel = new System.Windows.Forms.Label();
+      this.assignmentRadioButton = new System.Windows.Forms.RadioButton();
+      this.label1 = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // redrawButton
+      // 
+      this.redrawButton.Location = new System.Drawing.Point(3, 3);
+      this.redrawButton.Name = "redrawButton";
+      this.redrawButton.Size = new System.Drawing.Size(26, 23);
+      this.redrawButton.TabIndex = 7;
+      this.redrawButton.Text = "Redraw";
+      this.redrawButton.UseVisualStyleBackColor = true;
+      this.redrawButton.Click += new System.EventHandler(this.redrawButton_Click);
+      // 
+      // distancesRadioButton
+      // 
+      this.distancesRadioButton.AutoSize = true;
+      this.distancesRadioButton.Checked = true;
+      this.distancesRadioButton.Location = new System.Drawing.Point(35, 6);
+      this.distancesRadioButton.Name = "distancesRadioButton";
+      this.distancesRadioButton.Size = new System.Drawing.Size(72, 17);
+      this.distancesRadioButton.TabIndex = 6;
+      this.distancesRadioButton.TabStop = true;
+      this.distancesRadioButton.Text = "Distances";
+      this.distancesRadioButton.UseVisualStyleBackColor = true;
+      this.distancesRadioButton.CheckedChanged += new System.EventHandler(this.radio_CheckedChanged);
+      // 
+      // weightsRadioButton
+      // 
+      this.weightsRadioButton.AutoSize = true;
+      this.weightsRadioButton.Location = new System.Drawing.Point(113, 6);
+      this.weightsRadioButton.Name = "weightsRadioButton";
+      this.weightsRadioButton.Size = new System.Drawing.Size(64, 17);
+      this.weightsRadioButton.TabIndex = 5;
+      this.weightsRadioButton.Text = "Weights";
+      this.weightsRadioButton.UseVisualStyleBackColor = true;
+      this.weightsRadioButton.CheckedChanged += new System.EventHandler(this.radio_CheckedChanged);
+      // 
+      // pictureBox
+      // 
+      this.pictureBox.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.pictureBox.BackColor = System.Drawing.Color.White;
+      this.pictureBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.pictureBox.Location = new System.Drawing.Point(0, 32);
+      this.pictureBox.Name = "pictureBox";
+      this.pictureBox.Size = new System.Drawing.Size(574, 422);
+      this.pictureBox.TabIndex = 4;
+      this.pictureBox.TabStop = false;
+      this.pictureBox.SizeChanged += new System.EventHandler(this.pictureBox_SizeChanged);
+      // 
+      // stressLabel
+      // 
+      this.stressLabel.AutoSize = true;
+      this.stressLabel.Location = new System.Drawing.Point(393, 8);
+      this.stressLabel.Name = "stressLabel";
+      this.stressLabel.Size = new System.Drawing.Size(10, 13);
+      this.stressLabel.TabIndex = 8;
+      this.stressLabel.Text = "-";
+      // 
+      // assignmentRadioButton
+      // 
+      this.assignmentRadioButton.AutoSize = true;
+      this.assignmentRadioButton.Location = new System.Drawing.Point(183, 6);
+      this.assignmentRadioButton.Name = "assignmentRadioButton";
+      this.assignmentRadioButton.Size = new System.Drawing.Size(79, 17);
+      this.assignmentRadioButton.TabIndex = 5;
+      this.assignmentRadioButton.Text = "Assignment";
+      this.assignmentRadioButton.UseVisualStyleBackColor = true;
+      this.assignmentRadioButton.CheckedChanged += new System.EventHandler(this.radio_CheckedChanged);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(293, 8);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(94, 13);
+      this.label1.TabIndex = 8;
+      this.label1.Text = "Normalized Stress:";
+      // 
+      // QAPVisualizationControl
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.stressLabel);
+      this.Controls.Add(this.redrawButton);
+      this.Controls.Add(this.distancesRadioButton);
+      this.Controls.Add(this.assignmentRadioButton);
+      this.Controls.Add(this.weightsRadioButton);
+      this.Controls.Add(this.pictureBox);
+      this.Name = "QAPVisualizationControl";
+      this.Size = new System.Drawing.Size(574, 454);
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Button redrawButton;
+    private System.Windows.Forms.RadioButton distancesRadioButton;
+    private System.Windows.Forms.RadioButton weightsRadioButton;
+    private System.Windows.Forms.PictureBox pictureBox;
+    private System.Windows.Forms.Label stressLabel;
+    private System.Windows.Forms.RadioButton assignmentRadioButton;
+    private System.Windows.Forms.Label label1;
+
+  }
+}
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPVisualizationControl.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPVisualizationControl.cs	(revision 5932)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPVisualizationControl.cs	(revision 5932)
@@ -0,0 +1,543 @@
+﻿#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.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Text;
+using System.Globalization;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Forms;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+
+namespace HeuristicLab.Problems.QuadraticAssignment.Views {
+  public partial class QAPVisualizationControl : UserControl {
+    private Bitmap bitmap;
+    private Bitmap defaultBitmap;
+    private bool showingMessage;
+
+    #region Properties
+    private DoubleMatrix distances;
+    public DoubleMatrix Distances {
+      get { return distances; }
+      set {
+        DeregisterDistancesEvents();
+        distances = value;
+        RegisterDistancesEvents();
+        OnRedraw();
+      }
+    }
+
+    private DoubleMatrix weights;
+    public DoubleMatrix Weights {
+      get { return weights; }
+      set {
+        DeregisterWeightsEvents();
+        weights = value;
+        RegisterWeightsEvents();
+        OnRedraw();
+      }
+    }
+
+    private Permutation assignment;
+    public Permutation Assignment {
+      get { return assignment; }
+      set {
+        DeregisterAssignmentEvents();
+        assignment = value;
+        RegisterAssignmentEvents();
+        OnRedraw();
+      }
+    }
+    #endregion
+
+    #region Event Handling
+    private void DeregisterDistancesEvents() {
+      if (Distances != null) {
+        Distances.Reset -= new EventHandler(RedrawNecessary);
+        Distances.RowsChanged -= new EventHandler(RedrawNecessary);
+        Distances.ColumnsChanged -= new EventHandler(RedrawNecessary);
+        Distances.ItemChanged -= new EventHandler<EventArgs<int, int>>(RedrawNecessary);
+      }
+    }
+
+    private void RegisterDistancesEvents() {
+      if (Distances != null) {
+        Distances.Reset += new EventHandler(RedrawNecessary);
+        Distances.RowsChanged += new EventHandler(RedrawNecessary);
+        Distances.ColumnsChanged += new EventHandler(RedrawNecessary);
+        Distances.ItemChanged += new EventHandler<EventArgs<int, int>>(RedrawNecessary);
+      }
+    }
+
+    private void DeregisterWeightsEvents() {
+      if (Weights != null) {
+        Weights.Reset -= new EventHandler(RedrawNecessary);
+        Weights.RowsChanged -= new EventHandler(RedrawNecessary);
+        Weights.ColumnsChanged -= new EventHandler(RedrawNecessary);
+        Weights.ItemChanged -= new EventHandler<EventArgs<int, int>>(RedrawNecessary);
+      }
+    }
+
+    private void RegisterWeightsEvents() {
+      if (Weights != null) {
+        Weights.Reset += new EventHandler(RedrawNecessary);
+        Weights.RowsChanged += new EventHandler(RedrawNecessary);
+        Weights.ColumnsChanged += new EventHandler(RedrawNecessary);
+        Weights.ItemChanged += new EventHandler<EventArgs<int, int>>(RedrawNecessary);
+      }
+    }
+
+    private void DeregisterAssignmentEvents() {
+      if (Assignment != null) {
+        Assignment.Reset -= new EventHandler(RedrawNecessary);
+        Assignment.ItemChanged -= new EventHandler<EventArgs<int>>(RedrawNecessary);
+      }
+    }
+
+    private void RegisterAssignmentEvents() {
+      if (Assignment != null) {
+        Assignment.Reset += new EventHandler(RedrawNecessary);
+        Assignment.ItemChanged += new EventHandler<EventArgs<int>>(RedrawNecessary);
+      }
+    }
+
+    private void redrawButton_Click(object sender, EventArgs e) {
+      OnRedraw();
+    }
+
+    private void radio_CheckedChanged(object sender, EventArgs e) {
+      RadioButton rb = (sender as RadioButton);
+      if (rb != null && !rb.Checked) return;
+      else OnRedraw();
+    }
+
+    private void RedrawNecessary(object sender, EventArgs e) {
+      MarkRedrawNecessary();
+    }
+
+    private void RedrawNecessary(object sender, EventArgs<int, int> e) {
+      MarkRedrawNecessary();
+    }
+
+    private void pictureBox_SizeChanged(object sender, EventArgs e) {
+      SetupDefaultBitmap();
+      if (!showingMessage) MarkRedrawNecessary();
+      else OnRedraw();
+    }
+    #endregion
+
+    public QAPVisualizationControl() {
+      InitializeComponent();
+      showingMessage = false;
+      redrawButton.Text = String.Empty;
+      redrawButton.Image = VSImageLibrary.Refresh;
+      SetupDefaultBitmap();
+    }
+
+    private void SetupDefaultBitmap() {
+      if (defaultBitmap != null) {
+        defaultBitmap.Dispose();
+        defaultBitmap = null;
+      }
+      if (pictureBox.Width > 0 && pictureBox.Height > 0) {
+        defaultBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
+        WriteCenteredTextToBitmap(ref defaultBitmap, "No visualization available");
+      }
+    }
+
+    private void WriteCenteredTextToBitmap(ref Bitmap bitmap, string text) {
+      if (bitmap == null) return;
+      using (Graphics g = Graphics.FromImage(bitmap)) {
+        g.TextRenderingHint = TextRenderingHint.AntiAlias;
+        g.SmoothingMode = SmoothingMode.AntiAlias;
+
+        Font font = new Font(FontFamily.GenericSansSerif, 12, FontStyle.Regular);
+        SizeF strSize = g.MeasureString(text, font);
+        if (strSize.Width + 50 > pictureBox.Width) {
+          Match m = Regex.Match(text, @"\b\w+[.,]*\b*");
+          StringBuilder builder = new StringBuilder();
+          while (m.Success) {
+            builder.Append(m.Value + " ");
+            Match next = m.NextMatch();
+            if (g.MeasureString(builder.ToString() + " " + next.Value, font).Width + 50 > pictureBox.Width)
+              builder.AppendLine();
+            m = next;
+          }
+          builder.Remove(builder.Length - 1, 1);
+          text = builder.ToString();
+          strSize = g.MeasureString(text, font);
+        }
+        g.DrawString(text, font, Brushes.Black, (float)(pictureBox.Width - strSize.Width) / 2.0f, (float)(pictureBox.Height - strSize.Height) / 2.0f);
+      }
+    }
+
+    private void OnRedraw() {
+      if (InvokeRequired) {
+        Invoke((Action)OnRedraw, null);
+      } else {
+        GenerateImage();
+      }
+    }
+
+    private void GenerateImage() {
+      if (pictureBox.Width > 0 && pictureBox.Height > 0) {
+        Bitmap newBitmap = null;
+        stressLabel.Text = "-";
+        if (distancesRadioButton.Checked && Distances != null && Distances.Rows > 0
+          && Distances.Rows == Distances.Columns) {
+          if (Distances.Rows > 35) {
+            newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
+            WriteCenteredTextToBitmap(ref newBitmap, "Problem dimension is too large for visualization.");
+            showingMessage = true;
+          } else newBitmap = GenerateDistanceImage();
+        } else if (weightsRadioButton.Checked && Weights != null && Weights.Rows > 0
+          && Weights.Rows == Weights.Columns) {
+          if (Weights.Rows > 35) {
+            newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
+            WriteCenteredTextToBitmap(ref newBitmap, "Problem dimension is too large for visualization.");
+            showingMessage = true;
+          } else newBitmap = GenerateWeightsImage();
+        } else if (assignmentRadioButton.Checked
+          && Assignment != null && Assignment.Length > 0
+          && Weights != null && Weights.Rows > 0
+          && Distances != null && Distances.Rows > 0
+          && Weights.Rows == Weights.Columns
+          && Distances.Rows == Distances.Columns
+          && Assignment.Length == Weights.Rows
+          && Assignment.Length == Distances.Rows
+          && Assignment.Validate()) {
+          if (Assignment.Length > 35) {
+            newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
+            WriteCenteredTextToBitmap(ref newBitmap, "Problem dimension is too large for visualization.");
+            showingMessage = true;
+          } else newBitmap = GenerateAssignmentImage();
+        }
+
+        pictureBox.Image = newBitmap != null ? newBitmap : defaultBitmap;
+        if (bitmap != null) bitmap.Dispose();
+        if (newBitmap != null) bitmap = newBitmap;
+        else {
+          bitmap = null;
+          showingMessage = true;
+        }
+      }
+    }
+
+    private void MarkRedrawNecessary() {
+      if (pictureBox.Width > 0 && pictureBox.Height > 0) {
+        Bitmap newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
+        stressLabel.Text = "-";
+        WriteCenteredTextToBitmap(ref newBitmap, "Please refresh view.");
+        showingMessage = false; // we're showing a message, but we should be showing the visualization, so this is false
+
+        pictureBox.Image = newBitmap != null ? newBitmap : defaultBitmap;
+        if (bitmap != null) bitmap.Dispose();
+        if (newBitmap != null) bitmap = newBitmap;
+        else bitmap = null;
+      }
+    }
+
+    #region Draw distances
+    private Bitmap GenerateDistanceImage() {
+      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
+        Bitmap newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
+
+        DoubleMatrix coordinates;
+        double stress = double.NaN;
+        try {
+          coordinates = MultidimensionalScaling.KruskalShepard(distances);
+          stress = MultidimensionalScaling.CalculateNormalizedStress(distances, coordinates);
+          stressLabel.Text = stress.ToString("0.00", CultureInfo.CurrentCulture.NumberFormat);
+        } catch {
+          WriteCenteredTextToBitmap(ref newBitmap, "Distance matrix is not symmetric");
+          showingMessage = true;
+          stressLabel.Text = "-";
+          return newBitmap;
+        }
+        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
+        double maxDistance = double.MinValue;
+        for (int i = 0; i < coordinates.Rows; i++) {
+          if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
+          if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
+          if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
+          if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
+
+          for (int j = i + 1; j < coordinates.Rows; j++) {
+            if (distances[i, j] > maxDistance) maxDistance = distances[i, j];
+            if (distances[j, i] > maxDistance) maxDistance = distances[j, i];
+          }
+        }
+
+        int border = 20;
+        double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1;
+        double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1;
+
+        Point[] points = new Point[coordinates.Rows];
+        for (int i = 0; i < coordinates.Rows; i++)
+          points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
+                                newBitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
+
+        Random rand = new Random();
+        using (Graphics graphics = Graphics.FromImage(newBitmap)) {
+          graphics.SmoothingMode = SmoothingMode.AntiAlias;
+          graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
+          graphics.DrawString("Showing locations spaced out according to their distances", Font, Brushes.Black, 5, 2);
+
+          for (int i = 0; i < coordinates.Rows - 1; i++) {
+            for (int j = i + 1; j < coordinates.Rows; j++) {
+              Point start = points[i], end = points[j];
+              string caption = String.Empty;
+              double d = Math.Max(distances[i, j], distances[j, i]);
+              float width = (float)Math.Ceiling(5.0 * d / maxDistance);
+              if (d > 0) {
+                graphics.DrawLine(new Pen(Color.IndianRed, width), start, end);
+                if (distances[i, j] != distances[j, i])
+                  caption = distances[i, j].ToString(CultureInfo.InvariantCulture.NumberFormat)
+                    + " / " + distances[j, i].ToString(CultureInfo.InvariantCulture.NumberFormat);
+                else
+                  caption = distances[i, j].ToString(CultureInfo.InvariantCulture.NumberFormat);
+              }
+              if (!String.IsNullOrEmpty(caption)) {
+                double r = rand.NextDouble();
+                while (r < 0.2 || r > 0.8) r = rand.NextDouble();
+                float x = (float)(start.X + (end.X - start.X) * r + 5);
+                float y = (float)(start.Y + (end.Y - start.Y) * r + 5);
+                graphics.DrawString(caption, Font, Brushes.Black, x, y);
+              }
+            }
+          }
+
+          for (int i = 0; i < points.Length; i++) {
+            Point p = new Point(points[i].X - 3, points[i].Y - 3);
+            graphics.FillRectangle(Brushes.Black, p.X, p.Y, 8, 8);
+            graphics.DrawString(i.ToString(), Font, Brushes.Black, p.X, p.Y + 10);
+          }
+        }
+        showingMessage = false;
+        return newBitmap;
+      }
+      return null;
+    }
+    #endregion
+
+    #region Draw weights
+    private Bitmap GenerateWeightsImage() {
+      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
+        Bitmap newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
+
+        double maxWeight = double.MinValue;
+        for (int i = 0; i < weights.Rows; i++)
+          for (int j = i + 1; j < weights.Rows; j++) {
+            if (weights[i, j] > maxWeight)
+              maxWeight = weights[i, j] + weights[j, i];
+          }
+
+        DoubleMatrix distances = new DoubleMatrix(weights.Rows, weights.Columns);
+        for (int i = 0; i < distances.Rows; i++)
+          for (int j = 0; j < distances.Columns; j++) {
+            distances[i, j] = maxWeight + 1 - weights[i, j];
+          }
+
+        DoubleMatrix coordinates;
+        double stress = double.NaN;
+        try {
+          coordinates = MultidimensionalScaling.KruskalShepard(distances);
+          stress = MultidimensionalScaling.CalculateNormalizedStress(distances, coordinates);
+          stressLabel.Text = stress.ToString("0.00", CultureInfo.CurrentCulture.NumberFormat);
+        } catch {
+          WriteCenteredTextToBitmap(ref newBitmap, "Weights matrix is not symmetric");
+          showingMessage = true;
+          stressLabel.Text = "-";
+          return newBitmap;
+        }
+        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
+        for (int i = 0; i < coordinates.Rows; i++) {
+          if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
+          if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
+          if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
+          if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
+        }
+
+        int border = 20;
+        double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1;
+        double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1;
+
+        Point[] points = new Point[coordinates.Rows];
+        for (int i = 0; i < coordinates.Rows; i++)
+          points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
+                                newBitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
+
+        Random rand = new Random();
+        using (Graphics graphics = Graphics.FromImage(newBitmap)) {
+          graphics.SmoothingMode = SmoothingMode.AntiAlias;
+          graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
+          graphics.DrawString("Showing facilities spaced out according to their weights", Font, Brushes.Black, 5, 2);
+
+          for (int i = 0; i < coordinates.Rows - 1; i++) {
+            for (int j = i + 1; j < coordinates.Rows; j++) {
+              Point start = points[i], end = points[j];
+              string caption = String.Empty;
+              double d = Math.Max(distances[i, j], distances[j, i]);
+              double w = weights[i, j];
+              if (w > 0) {
+                float width = (float)Math.Ceiling(3.0 * w / maxWeight);
+                graphics.DrawLine(new Pen(Color.MediumBlue, width), start, end);
+                caption = w.ToString(CultureInfo.InvariantCulture.NumberFormat);
+              }
+              if (!String.IsNullOrEmpty(caption)) {
+                double r = rand.NextDouble();
+                while (r < 0.2 || r > 0.8) r = rand.NextDouble();
+                float x = (float)(start.X + (end.X - start.X) * r + 5);
+                float y = (float)(start.Y + (end.Y - start.Y) * r + 5);
+                graphics.DrawString(caption, Font, Brushes.Black, x, y);
+              }
+            }
+          }
+          for (int i = 0; i < points.Length; i++) {
+            Point p = new Point(points[i].X - 3, points[i].Y - 3);
+            graphics.FillRectangle(Brushes.Black, p.X, p.Y, 8, 8);
+            graphics.DrawString(i.ToString(), Font, Brushes.Black, p.X, p.Y + 10);
+          }
+        }
+        showingMessage = false;
+        return newBitmap;
+      }
+      return null;
+    }
+    #endregion
+
+    #region Draw assignment
+    private Bitmap GenerateAssignmentImage() {
+      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
+        Bitmap newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
+
+        for (int i = 0; i < distances.Rows; i++) {
+          for (int j = i + 1; j < distances.Rows; j++) {
+            if (distances[i, j] != distances[j, i]) {
+              WriteCenteredTextToBitmap(ref newBitmap, "Distance matrix is not symmetric");
+              stressLabel.Text = "-";
+              showingMessage = true;
+              return newBitmap;
+            }
+            if (weights[i, j] != weights[j, i]) {
+              WriteCenteredTextToBitmap(ref newBitmap, "Weights matrix is not symmetric");
+              stressLabel.Text = "-";
+              showingMessage = true;
+              return newBitmap;
+            }
+          }
+        }
+
+        DoubleMatrix coordinates = null;
+        double stress = double.NaN;
+        try {
+          coordinates = MultidimensionalScaling.KruskalShepard(distances);
+          stress = MultidimensionalScaling.CalculateNormalizedStress(distances, coordinates);
+          stressLabel.Text = stress.ToString("0.00", CultureInfo.CurrentCulture.NumberFormat);
+        } catch {
+          WriteCenteredTextToBitmap(ref newBitmap, "Unknown error");
+          showingMessage = true;
+          stressLabel.Text = "-";
+          return newBitmap;
+        }
+
+        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
+        double maxWeight = double.MinValue;
+        for (int i = 0; i < coordinates.Rows; i++) {
+          if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
+          if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
+          if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
+          if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
+
+          for (int j = i + 1; j < coordinates.Rows; j++) {
+            if (weights[i, j] > maxWeight) maxWeight = weights[i, j];
+          }
+        }
+
+        int border = 20;
+        double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1;
+        double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1;
+
+        Point[] points = new Point[coordinates.Rows];
+        for (int i = 0; i < coordinates.Rows; i++)
+          points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
+                                newBitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
+
+        Random rand = new Random();
+        using (Graphics graphics = Graphics.FromImage(newBitmap)) {
+          graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
+          graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
+
+          for (int i = 0; i < assignment.Length - 1; i++) {
+            for (int j = i + 1; j < assignment.Length; j++) {
+              Point start, end;
+              string caption = String.Empty;
+              double d = distances[i, j];
+              start = points[assignment[i]];
+              end = points[assignment[j]];
+              double w = weights[i, j];
+              if (w > 0) {
+                float width = (float)Math.Ceiling(4.0 * w / maxWeight);
+                graphics.DrawLine(new Pen(Color.MediumBlue, width), start, end);
+                caption = w.ToString(CultureInfo.InvariantCulture.NumberFormat);
+              }
+              if (!String.IsNullOrEmpty(caption)) {
+                double r = rand.NextDouble();
+                while (r < 0.2 || r > 0.8) r = rand.NextDouble();
+                float x = (float)(start.X + (end.X - start.X) * r + 5);
+                float y = (float)(start.Y + (end.Y - start.Y) * r + 5);
+                graphics.DrawString(caption, Font, Brushes.Black, x, y);
+              }
+            }
+          }
+
+          for (int i = 0; i < points.Length; i++) {
+            Point p = new Point(points[i].X - 3, points[i].Y - 3);
+            graphics.FillRectangle(Brushes.Black, p.X, p.Y, 8, 8);
+            graphics.DrawString(i.ToString(), Font, Brushes.Black, p.X, p.Y + 10);
+          }
+        }
+        showingMessage = false;
+        return newBitmap;
+      }
+      return null;
+    }
+    #endregion
+
+    private void CustomDispose(bool disposing) {
+      DeregisterDistancesEvents();
+      DeregisterWeightsEvents();
+      DeregisterAssignmentEvents();
+      if (bitmap != null) bitmap.Dispose();
+      bitmap = null;
+      if (defaultBitmap != null) {
+        defaultBitmap.Dispose();
+        defaultBitmap = null;
+      }
+    }
+  }
+}
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPVisualizationControl.resx
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPVisualizationControl.resx	(revision 5932)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPVisualizationControl.resx	(revision 5932)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QuadraticAssignmentProblemView.Designer.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QuadraticAssignmentProblemView.Designer.cs	(revision 5931)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QuadraticAssignmentProblemView.Designer.cs	(revision 5932)
@@ -53,5 +53,5 @@
       this.problemTabPage = new System.Windows.Forms.TabPage();
       this.visualizationTabPage = new System.Windows.Forms.TabPage();
-      this.qapView = new HeuristicLab.Problems.QuadraticAssignment.Views.QAPView();
+      this.qapView = new HeuristicLab.Problems.QuadraticAssignment.Views.QAPVisualizationControl();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
       this.tabControl.SuspendLayout();
@@ -218,5 +218,5 @@
     private System.Windows.Forms.TabPage problemTabPage;
     private System.Windows.Forms.TabPage visualizationTabPage;
-    private QAPView qapView;
+    private QAPVisualizationControl qapView;
   }
 }
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/QAPAssignment.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/QAPAssignment.cs	(revision 5931)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/QAPAssignment.cs	(revision 5932)
@@ -1,3 +1,24 @@
-﻿using System.ComponentModel;
+﻿#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.ComponentModel;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
Index: /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPLIBInstancesTest.cs
===================================================================
--- /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPLIBInstancesTest.cs	(revision 5931)
+++ /branches/QAP/HeuristicLab.Problems.QuadraticAssignment/3.3/Tests/QAPLIBInstancesTest.cs	(revision 5932)
@@ -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.Text;
 using HeuristicLab.Common;
