Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/10/11 01:49:10 (13 years ago)
Author:
abeham
Message:

#1330

  • Unified QAP visualization in solution and problem view
  • Fixed bug in gradient-descent gradient calculation when performing multidimensional scaling
  • Extended QAPLIB parsers to cover some file format variations
  • Added unit tests to check if all QAPLIB instances import without error
  • Changed BestKnownSolution to be an OptionalValueParameter
Location:
branches/QAP
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/QAP

    • Property svn:ignore
      •  

        old new  
        11*.suo
         2TestResults
  • branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPView.cs

    r5641 r5648  
    3535    private Bitmap defaultBitmap;
    3636
     37    #region Properties
    3738    private DoubleMatrix distances;
    3839    public DoubleMatrix Distances {
     
    6768      }
    6869    }
    69 
     70    #endregion
     71
     72    #region Event Handling
    7073    private void DeregisterDistancesEvents() {
    7174      if (Distances != null) {
     
    128131    }
    129132
     133    private void pictureBox_SizeChanged(object sender, EventArgs e) {
     134      SetupDefaultBitmap();
     135      OnRedraw();
     136    }
     137    #endregion
     138
    130139    public QAPView() {
    131140      InitializeComponent();
    132141      SetupDefaultBitmap();
    133       pictureBox.Resize += new EventHandler(pictureBox_Resize);
    134     }
    135 
    136     private void pictureBox_Resize(object sender, EventArgs e) {
    137       SetupDefaultBitmap();
    138142    }
    139143
     
    141145      if (defaultBitmap != null) defaultBitmap.Dispose();
    142146      defaultBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
    143       using (Graphics g = Graphics.FromImage(defaultBitmap)) {
     147      WriteCenteredTextToBitmap(ref defaultBitmap, "No visualization available");
     148    }
     149
     150    private void WriteCenteredTextToBitmap(ref Bitmap bitmap, string text) {
     151      using (Graphics g = Graphics.FromImage(bitmap)) {
    144152        g.TextRenderingHint = TextRenderingHint.AntiAlias;
    145153        g.SmoothingMode = SmoothingMode.AntiAlias;
    146154
    147         string msg = "No visualization available";
    148         SizeF strSize = g.MeasureString(msg, Font);
    149         g.DrawString(msg, Font, Brushes.Black, (float)(pictureBox.Width - strSize.Width) / 2.0f, (float)(pictureBox.Height - strSize.Height) / 2.0f);
     155        SizeF strSize = g.MeasureString(text, Font);
     156        g.DrawString(text, Font, Brushes.Black, (float)(pictureBox.Width - strSize.Width) / 2.0f, (float)(pictureBox.Height - strSize.Height) / 2.0f);
    150157      }
    151158    }
     
    161168    private void GenerateImage() {
    162169      Bitmap newBitmap = null;
    163       errorLabel.Text = "Error: -";
     170      stressLabel.Text = "-";
    164171      if (distancesRadioButton.Checked && Distances != null && Distances.Rows > 0
    165172        && Distances.Rows == Distances.Columns) {
    166         newBitmap = GenerateDistanceImage();
     173        if (Distances.Rows > 30) {
     174          newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
     175          WriteCenteredTextToBitmap(ref newBitmap, "Problem dimension too large for visualization.");
     176        } else newBitmap = GenerateDistanceImage();
    167177      } else if (weightsRadioButton.Checked && Weights != null && Weights.Rows > 0
    168178        && Weights.Rows == Weights.Columns) {
    169         newBitmap = GenerateWeightsImage();
     179        if (Weights.Rows > 30) {
     180          newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
     181          WriteCenteredTextToBitmap(ref newBitmap, "Problem dimension too large for visualization.");
     182        } else newBitmap = GenerateWeightsImage();
    170183      } else if (assignmentRadioButton.Checked
    171184        && Assignment != null && Assignment.Length > 0
     
    175188        && Distances.Rows == Distances.Columns
    176189        && Assignment.Length == Weights.Rows
    177         && Assignment.Length == Distances.Rows) {
     190        && Assignment.Length == Distances.Rows
     191        && Assignment.Validate()) {
    178192        newBitmap = GenerateAssignmentImage();
    179193      }
     
    181195      pictureBox.Image = newBitmap != null ? newBitmap : defaultBitmap;
    182196      if (bitmap != null) bitmap.Dispose();
    183       bitmap = newBitmap;
    184     }
    185 
     197      if (newBitmap != null) bitmap = newBitmap;
     198      else bitmap = null;
     199    }
     200
     201    #region Draw distances
    186202    private Bitmap GenerateDistanceImage() {
    187203      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
    188204        Bitmap newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
    189205
    190         double error;
    191         DoubleMatrix coordinates = MultidimensionalScaling.Metric(distances, out error);
    192         errorLabel.Text = "Error: " + error.ToString(CultureInfo.CurrentCulture.NumberFormat);
     206        for (int i = 0; i < distances.Rows; i++) {
     207          for (int j = i + 1; j < distances.Rows; j++)
     208            if (distances[i, j] != distances[j, i]) {
     209              WriteCenteredTextToBitmap(ref newBitmap, "Distance matrix is not symmetric");
     210              return newBitmap;
     211            }
     212        }
     213
     214        double stress;
     215        DoubleMatrix coordinates = MultidimensionalScaling.MetricByDistance(distances, out stress);
     216        stressLabel.Text = stress.ToString("0.00", CultureInfo.CurrentCulture.NumberFormat);
    193217        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
    194218        double maxDistance = double.MinValue;
     
    214238                                newBitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
    215239
     240        Random rand = new Random();
    216241        using (Graphics graphics = Graphics.FromImage(newBitmap)) {
    217242          graphics.SmoothingMode = SmoothingMode.AntiAlias;
    218243          graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
    219           graphics.DrawString("Showing Locations spaced out according to their distances", Font, Brushes.Black, 5, 2);
     244          graphics.DrawString("Showing locations spaced out according to their distances", Font, Brushes.Black, 5, 2);
    220245
    221246          for (int i = 0; i < coordinates.Rows - 1; i++) {
     
    233258                  caption = distances[i, j].ToString(CultureInfo.InvariantCulture.NumberFormat);
    234259              }
     260              if (!String.IsNullOrEmpty(caption)) {
     261                double r = rand.NextDouble();
     262                while (r < 0.2 || r > 0.8) r = rand.NextDouble();
     263                float x = (float)(start.X + (end.X - start.X) * r + 5);
     264                float y = (float)(start.Y + (end.Y - start.Y) * r + 5);
     265                graphics.DrawString(caption, Font, Brushes.Black, x, y);
     266              }
    235267            }
    236268          }
     
    246278      return null;
    247279    }
    248 
     280    #endregion
     281
     282    #region Draw weights
    249283    private Bitmap GenerateWeightsImage() {
    250284      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
    251285        Bitmap newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
    252286
    253         double error;
    254         DoubleMatrix coordinates = MultidimensionalScaling.Classic(weights, out error);
    255         errorLabel.Text = "Error: " + error.ToString(CultureInfo.CurrentCulture.NumberFormat);
     287        double maxWeight = double.MinValue;
     288        for (int i = 0; i < weights.Rows; i++)
     289          for (int j = i + 1; j < weights.Rows; j++) {
     290            if (weights[i, j] > maxWeight)
     291              maxWeight = weights[i, j] + weights[j, i];
     292
     293            if (weights[i, j] != weights[j, i]) {
     294              WriteCenteredTextToBitmap(ref newBitmap, "Weights matrix is not symmetric");
     295              return newBitmap;
     296            }
     297          }
     298
     299        DoubleMatrix distances = new DoubleMatrix(weights.Rows, weights.Columns);
     300        for (int i = 0; i < distances.Rows; i++)
     301          for (int j = 0; j < distances.Columns; j++) {
     302            distances[i, j] = maxWeight + 1 - weights[i, j];
     303          }
     304
     305        double stress;
     306        DoubleMatrix coordinates = MultidimensionalScaling.MetricByDistance(distances, out stress);
     307        stressLabel.Text = stress.ToString("0.00", CultureInfo.CurrentCulture.NumberFormat);
     308        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
     309        for (int i = 0; i < coordinates.Rows; i++) {
     310          if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
     311          if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
     312          if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
     313          if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
     314        }
     315
     316        int border = 20;
     317        double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1;
     318        double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1;
     319
     320        Point[] points = new Point[coordinates.Rows];
     321        for (int i = 0; i < coordinates.Rows; i++)
     322          points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
     323                                newBitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
     324
     325        Random rand = new Random();
     326        using (Graphics graphics = Graphics.FromImage(newBitmap)) {
     327          graphics.SmoothingMode = SmoothingMode.AntiAlias;
     328          graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
     329          graphics.DrawString("Showing facilities spaced out according to their weights", Font, Brushes.Black, 5, 2);
     330
     331          for (int i = 0; i < coordinates.Rows - 1; i++) {
     332            for (int j = i + 1; j < coordinates.Rows; j++) {
     333              Point start = points[i], end = points[j];
     334              string caption = String.Empty;
     335              double d = Math.Max(distances[i, j], distances[j, i]);
     336              double w = weights[i, j];
     337              if (w > 0) {
     338                float width = (float)Math.Ceiling(3.0 * w / maxWeight);
     339                graphics.DrawLine(new Pen(Color.MediumBlue, width), start, end);
     340                caption = w.ToString(CultureInfo.InvariantCulture.NumberFormat);
     341              }
     342              if (!String.IsNullOrEmpty(caption)) {
     343                double r = rand.NextDouble();
     344                while (r < 0.2 || r > 0.8) r = rand.NextDouble();
     345                float x = (float)(start.X + (end.X - start.X) * r + 5);
     346                float y = (float)(start.Y + (end.Y - start.Y) * r + 5);
     347                graphics.DrawString(caption, Font, Brushes.Black, x, y);
     348              }
     349            }
     350          }
     351          for (int i = 0; i < points.Length; i++) {
     352            Point p = new Point(points[i].X - 3, points[i].Y - 3);
     353            graphics.FillRectangle(Brushes.Black, p.X, p.Y, 8, 8);
     354            graphics.DrawString(i.ToString(), Font, Brushes.Black, p.X, p.Y + 10);
     355          }
     356        }
     357        return newBitmap;
     358      }
     359      return null;
     360    }
     361    #endregion
     362
     363    #region Draw assignment
     364    private Bitmap GenerateAssignmentImage() {
     365      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
     366        Bitmap newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
     367
     368        for (int i = 0; i < distances.Rows; i++) {
     369          for (int j = i + 1; j < distances.Rows; j++) {
     370            if (distances[i, j] != distances[j, i]) {
     371              WriteCenteredTextToBitmap(ref newBitmap, "Distance matrix is not symmetric");
     372              return newBitmap;
     373            }
     374            if (weights[i, j] != weights[j, i]) {
     375              WriteCenteredTextToBitmap(ref newBitmap, "Weights matrix is not symmetric");
     376            }
     377          }
     378        }
     379
     380        double stress;
     381        DoubleMatrix coordinates = MultidimensionalScaling.MetricByDistance(distances, out stress);
     382        stressLabel.Text = stress.ToString("0.00", CultureInfo.CurrentCulture.NumberFormat);
    256383        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
    257384        double maxWeight = double.MinValue;
     
    263390
    264391          for (int j = i + 1; j < coordinates.Rows; j++) {
    265             if (weights[i, j] + weights[j, i] > maxWeight)
    266               maxWeight = weights[i, j] + weights[j, i];
     392            if (weights[i, j] > maxWeight) maxWeight = weights[i, j];
    267393          }
    268394        }
     
    279405        Random rand = new Random();
    280406        using (Graphics graphics = Graphics.FromImage(newBitmap)) {
    281           graphics.SmoothingMode = SmoothingMode.AntiAlias;
    282           graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
    283           graphics.DrawString("Showing Facilities spaced out according to their weights", Font, Brushes.Black, 5, 2);
    284 
    285           for (int i = 0; i < coordinates.Rows - 1; i++) {
    286             for (int j = i + 1; j < coordinates.Rows; j++) {
    287               Point start = points[i], end = points[j];
     407          graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
     408          graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
     409
     410          for (int i = 0; i < assignment.Length - 1; i++) {
     411            for (int j = i + 1; j < assignment.Length; j++) {
     412              Point start, end;
    288413              string caption = String.Empty;
    289               double d = Math.Max(distances[i, j], distances[j, i]);
    290               double w = weights[i, j] + weights[j, i];
     414              double d = distances[i, j];
     415              start = points[assignment[i]];
     416              end = points[assignment[j]];
     417              double w = weights[i, j];
    291418              if (w > 0) {
    292                 float width = (float)Math.Ceiling(3.0 * w / maxWeight);
     419                float width = (float)Math.Ceiling(4.0 * w / maxWeight);
    293420                graphics.DrawLine(new Pen(Color.MediumBlue, width), start, end);
    294421                caption = w.ToString(CultureInfo.InvariantCulture.NumberFormat);
     
    303430            }
    304431          }
     432
    305433          for (int i = 0; i < points.Length; i++) {
    306434            Point p = new Point(points[i].X - 3, points[i].Y - 3);
     
    313441      return null;
    314442    }
    315 
    316     private Bitmap GenerateAssignmentImage() {
    317       return null;
    318     }
     443    #endregion
    319444
    320445    private void CustomDispose(bool disposing) {
Note: See TracChangeset for help on using the changeset viewer.