Free cookie consent management tool by TermsFeed Policy Generator

source: branches/QAP/HeuristicLab.Problems.QuadraticAssignment.Views/3.3/QAPAssignmentView.cs @ 5598

Last change on this file since 5598 was 5598, checked in by abeham, 12 years ago

#1330

  • Updated solution view
  • Made distance matrix a mandatory parameter (solution instances are small anyway)
  • Added and set best known solution if available for a QAPLIB instance
File size: 9.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.ComponentModel;
24using System.Drawing;
25using System.Globalization;
26using System.Windows.Forms;
27using HeuristicLab.Core.Views;
28using HeuristicLab.Data;
29using HeuristicLab.Encodings.PermutationEncoding;
30using HeuristicLab.MainForm;
31
32namespace HeuristicLab.Problems.QuadraticAssignment.Views {
33  /// <summary>
34  /// The base class for visual representations of a path tour for a TSP.
35  /// </summary>
36  [View("QAPAssignment View")]
37  [Content(typeof(QAPAssignment), true)]
38  public sealed partial class QAPAssignmentView : ItemView {
39    private Bitmap bitmap;
40
41    public new QAPAssignment Content {
42      get { return (QAPAssignment)base.Content; }
43      set { base.Content = value; }
44    }
45
46    /// <summary>
47    /// Initializes a new instance of <see cref="PathTSPTourView"/>.
48    /// </summary>
49    public QAPAssignmentView() {
50      InitializeComponent();
51    }
52
53    protected override void DeregisterContentEvents() {
54      Content.PropertyChanged -= new PropertyChangedEventHandler(Content_PropertyChanged);
55      base.DeregisterContentEvents();
56    }
57    protected override void RegisterContentEvents() {
58      base.RegisterContentEvents();
59      Content.PropertyChanged += new PropertyChangedEventHandler(Content_PropertyChanged);
60    }
61
62    protected override void OnContentChanged() {
63      base.OnContentChanged();
64      if (Content == null) {
65        qualityViewHost.Content = null;
66        pictureBox.Image = null;
67        assignmentViewHost.Content = null;
68      } else {
69        qualityViewHost.Content = Content.Quality;
70        GenerateImage();
71        assignmentViewHost.Content = Content.Assignment;
72      }
73    }
74
75    protected override void SetEnabledStateOfControls() {
76      base.SetEnabledStateOfControls();
77      qualityGroupBox.Enabled = Content != null;
78      pictureBox.Enabled = Content != null;
79      assignmentGroupBox.Enabled = Content != null;
80    }
81
82    private void GenerateImage() {
83      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
84        if (Content == null) {
85          pictureBox.Image = null;
86          if (bitmap != null) bitmap.Dispose();
87          bitmap = null;
88        } else {
89          Bitmap newBitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
90          bool drawDistances = distancesRadioButton.Checked;
91          DoubleMatrix coordinates = Content.Coordinates;
92          DoubleMatrix distances = Content.Distances;
93
94          if ((coordinates == null || coordinates.Rows == 0)
95            && (distances == null || distances.Rows == 0)) {
96            using (Graphics g = Graphics.FromImage(newBitmap)) {
97              string str = "No coordinates and no distance matrix specified.";
98              SizeF strSize = g.MeasureString(str, Font);
99              g.DrawString(str, Font, Brushes.Black, (float)(newBitmap.Width - strSize.Width) / 2.0f, (float)(newBitmap.Height - strSize.Height) / 2.0f);
100            }
101          } else {
102            if ((coordinates == null || coordinates.Rows == 0)
103              && Content.ViewCoordinates == null) {
104              coordinates = new DoubleMatrix(distances.Rows, 2);
105              double rad = (2 * Math.PI) / coordinates.Rows;
106              for (int i = 0; i < coordinates.Rows; i++) {
107                coordinates[i, 0] = 10 * Math.Cos(rad * i);
108                coordinates[i, 1] = 10 * Math.Sin(rad * i);
109              }
110              Content.ViewCoordinates = coordinates;
111            } else if ((coordinates == null || coordinates.Rows == 0)
112              && Content.ViewCoordinates != null) {
113              coordinates = Content.ViewCoordinates;
114            }
115
116            DoubleMatrix weights = Content.Weights;
117            Permutation assignment = Content.Assignment;
118
119            double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
120            double maxWeight = double.MinValue, maxDistance = double.MinValue;
121            for (int i = 0; i < coordinates.Rows; i++) {
122              if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
123              if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
124              if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
125              if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
126
127              for (int j = i + 1; j < coordinates.Rows; j++) {
128                if (weights[i, j] + weights[j, i] > maxWeight)
129                  maxWeight = weights[i, j] + weights[j, i];
130
131                if (distances[i, j] > maxDistance)
132                  maxDistance = distances[i, j];
133                else if (distances[j, i] > maxDistance)
134                  maxDistance = distances[j, i];
135              }
136            }
137
138            int border = 20;
139            double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1;
140            double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1;
141
142            Point[] points = new Point[coordinates.Rows];
143            for (int i = 0; i < coordinates.Rows; i++)
144              points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
145                                    newBitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
146
147            Random rand = new Random();
148            using (Graphics graphics = Graphics.FromImage(newBitmap)) {
149              graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
150              graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
151              if ((assignment != null) && (assignment.Length == coordinates.Rows) && (assignment.Validate())) {
152                for (int i = 0; i < assignment.Length - 1; i++) {
153                  for (int j = i + 1; j < assignment.Length; j++) {
154                    Point start = points[assignment[i]], end = points[assignment[j]];
155                    string caption = String.Empty;
156                    double d = Math.Max(distances[i, j], distances[j, i]);
157                    if (drawDistances) {
158                      float width = (float)Math.Ceiling(5.0 * d / maxDistance);
159                      graphics.DrawLine(new Pen(Color.IndianRed, width), start, end);
160                      if (distances[i, j] != distances[j, i])
161                        caption = distances[i, j].ToString(CultureInfo.InvariantCulture.NumberFormat)
162                          + " / " + distances[j, i].ToString(CultureInfo.InvariantCulture.NumberFormat);
163                      else
164                        caption = distances[i, j].ToString(CultureInfo.InvariantCulture.NumberFormat);
165                    } else {
166                      double w = weights[i, j] + weights[j, i];
167                      if (w > 0) {
168                        float width = (float)Math.Ceiling(5.0 * w / maxWeight);
169                        graphics.DrawLine(new Pen(Color.MediumBlue, width), start, end);
170                        caption = w.ToString(CultureInfo.InvariantCulture.NumberFormat);
171                      }
172                      if (!String.IsNullOrEmpty(caption)) {
173                        double r = rand.NextDouble();
174                        while (r < 0.2 || r > 0.8) r = rand.NextDouble();
175                        float x = (float)(start.X + (end.X - start.X) * r + 5);
176                        float y = (float)(start.Y + (end.Y - start.Y) * r + 5);
177                        graphics.DrawString(caption, Font, Brushes.Black, x, y);
178                      }
179                    }
180                  }
181                }
182              }
183              for (int i = 0; i < points.Length; i++) {
184                Point p = new Point(points[assignment[i]].X - 3, points[assignment[i]].Y - 3);
185                graphics.FillRectangle(Brushes.Black, p.X, p.Y, 8, 8);
186                graphics.DrawString(i.ToString(), Font, Brushes.Black, p.X, p.Y + 10);
187              }
188            }
189          }
190          pictureBox.Image = newBitmap;
191          if (bitmap != null) bitmap.Dispose();
192          bitmap = newBitmap;
193        }
194      }
195    }
196
197    private void Content_PropertyChanged(object sender, PropertyChangedEventArgs e) {
198      if (InvokeRequired)
199        Invoke(new PropertyChangedEventHandler(Content_PropertyChanged), sender, e);
200      else {
201        switch (e.PropertyName) {
202          case "Coordinates":
203          case "Distances":
204          case "Weights":
205            GenerateImage();
206            break;
207          case "Assignment":
208            GenerateImage();
209            assignmentViewHost.Content = Content.Assignment;
210            break;
211          case "Quality":
212            break;
213          default:
214            break;
215        }
216      }
217    }
218
219    private void pictureBox_SizeChanged(object sender, EventArgs e) {
220      GenerateImage();
221    }
222
223    private void radioButton_CheckedChanged(object sender, EventArgs e) {
224      GenerateImage();
225    }
226  }
227}
Note: See TracBrowser for help on using the repository browser.