Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.VehicleRouting.Views/3.3/VRPSolutionView.cs @ 7142

Last change on this file since 7142 was 6447, checked in by svonolfe, 13 years ago

Replaced tour data table with a text box as a tour visualization to prevent out of memory exceptions for large instances (#1561)

File size: 9.6 KB
RevLine 
[3938]1#region License Information
2/* HeuristicLab
[5445]3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[3938]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.Drawing;
24using System.Windows.Forms;
25using HeuristicLab.Core.Views;
26using HeuristicLab.Data;
27using HeuristicLab.MainForm;
[4722]28using HeuristicLab.Parameters;
[3938]29using HeuristicLab.Problems.VehicleRouting.Encodings;
[6447]30using System.Text;
[3938]31
32namespace HeuristicLab.Problems.VehicleRouting.Views {
33  /// <summary>
34  /// The base class for visual representations of items.
35  /// </summary>
36  [View("VRPSolution View")]
37  [Content(typeof(VRPSolution), true)]
38  public sealed partial class VRPSolutionView : ItemView {
39    public new VRPSolution Content {
40      get { return (VRPSolution)base.Content; }
41      set { base.Content = value; }
42    }
43
44    /// <summary>
45    /// Initializes a new instance of <see cref="ItemBaseView"/>.
46    /// </summary>
47    public VRPSolutionView() {
48      InitializeComponent();
[4185]49
50      ToolTip tt = new ToolTip();
51      tt.SetToolTip(pictureBox, "Legend: Blue = Depot, Black = City (OK), Orange = City (too early), Red = City (too late)");
[3938]52    }
53
54    protected override void DeregisterContentEvents() {
55      Content.CoordinatesChanged -= new EventHandler(Content_CoordinatesChanged);
56      Content.SolutionChanged -= new EventHandler(Content_SolutionChanged);
57      base.DeregisterContentEvents();
58    }
59    protected override void RegisterContentEvents() {
60      base.RegisterContentEvents();
61      Content.CoordinatesChanged += new EventHandler(Content_CoordinatesChanged);
62      Content.SolutionChanged += new EventHandler(Content_SolutionChanged);
63    }
64
65    protected override void OnContentChanged() {
66      base.OnContentChanged();
67      if (Content == null) {
68        pictureBox.Image = null;
69      } else {
70        GenerateImage();
[4352]71        UpdateTourView();
[3938]72      }
73    }
74
75    protected override void OnReadOnlyChanged() {
76      base.OnReadOnlyChanged();
77      SetEnabledStateOfControls();
78    }
79
80    protected override void SetEnabledStateOfControls() {
81      base.SetEnabledStateOfControls();
82      pictureBox.Enabled = Content != null;
83      tourGroupBox.Enabled = Content != null;
84    }
85
[4352]86    private void UpdateTourView() {
[6447]87      StringBuilder sb = new StringBuilder();
[4352]88
89      if (Content != null && Content.Solution != null) {
90        foreach (Tour tour in Content.Solution.GetTours(new ValueLookupParameter<DoubleMatrix>("DistanceMatrix", Content.DistanceMatrix))) {
91          foreach (int city in tour.Cities) {
[6447]92            sb.Append(city);
93            sb.Append(" ");
[4352]94          }
[6447]95          sb.AppendLine();
[4352]96        }
97      }
[6447]98
99      valueTextBox.Text = sb.ToString();
[4352]100    }
101
[3938]102    private void GenerateImage() {
103      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
104        if (Content == null) {
105          pictureBox.Image = null;
106        } else {
107          DoubleMatrix coordinates = Content.Coordinates;
[4015]108          DoubleMatrix distanceMatrix = Content.DistanceMatrix;
109          BoolValue useDistanceMatrix = Content.UseDistanceMatrix;
110          DoubleArray dueTime = Content.DueTime;
111          DoubleArray serviceTime = Content.ServiceTime;
112          DoubleArray readyTime = Content.ReadyTime;
113
[3938]114          Bitmap bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
115
[4015]116          Pen[] pens = {new Pen(Color.FromArgb(92,20,237)), new Pen(Color.FromArgb(237,183,20)), new Pen(Color.FromArgb(237,20,219)), new Pen(Color.FromArgb(20,237,76)),
117                    new Pen(Color.FromArgb(237,61,20)), new Pen(Color.FromArgb(115,78,26)), new Pen(Color.FromArgb(20,237,229)), new Pen(Color.FromArgb(39,101,19)),
118                    new Pen(Color.FromArgb(230,170,229)), new Pen(Color.FromArgb(142,136,89)), new Pen(Color.FromArgb(157,217,166)), new Pen(Color.FromArgb(31,19,101)),
119                    new Pen(Color.FromArgb(173,237,20)), new Pen(Color.FromArgb(230,231,161)), new Pen(Color.FromArgb(142,89,89)), new Pen(Color.FromArgb(93,89,142)),
120                    new Pen(Color.FromArgb(146,203,217)), new Pen(Color.FromArgb(101,19,75)), new Pen(Color.FromArgb(198,20,237)), new Pen(Color.FromArgb(185,185,185)),
121                    new Pen(Color.FromArgb(179,32,32)), new Pen(Color.FromArgb(18,119,115)), new Pen(Color.FromArgb(104,158,239)), new Pen(Color.Black)};
122
[3938]123          if ((coordinates != null) && (coordinates.Rows > 0) && (coordinates.Columns == 2)) {
124            double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
125            for (int i = 0; i < coordinates.Rows; i++) {
126              if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
127              if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
128              if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
129              if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
130            }
131
132            int border = 20;
133            double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1;
134            double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1;
135
136            using (Graphics graphics = Graphics.FromImage(bitmap)) {
137              if (Content.Solution != null) {
[4015]138                int currentTour = 0;
[4352]139                foreach (Tour tour in Content.Solution.GetTours(new ValueLookupParameter<DoubleMatrix>("DistanceMatrix", distanceMatrix))) {
[4015]140                  double t = 0.0;
[4174]141                  Point[] tourPoints = new Point[tour.Cities.Count + 2];
[4185]142                  Brush[] customerBrushes = new Brush[tour.Cities.Count];
[4015]143                  int lastCustomer = 0;
144
[4174]145                  for (int i = -1; i <= tour.Cities.Count; i++) {
[4151]146                    int location = 0;
[4015]147
[4174]148                    if (i == -1 || i == tour.Cities.Count)
[4151]149                      location = 0; //depot
150                    else
[4174]151                      location = tour.Cities[i];
[4015]152
[4151]153                    Point locationPoint = new Point(border + ((int)((coordinates[location, 0] - xMin) * xStep)),
154                                    bitmap.Height - (border + ((int)((coordinates[location, 1] - yMin) * yStep))));
155                    tourPoints[i + 1] = locationPoint;
156
[4174]157                    if (i != -1 && i != tour.Cities.Count) {
[4015]158                      Brush customerBrush = Brushes.Black;
159
[4154]160                      t += VRPUtilities.GetDistance(
[4151]161                        lastCustomer, location, coordinates, distanceMatrix, useDistanceMatrix);
[4015]162
[4151]163                      if (t < readyTime[location]) {
164                        t = readyTime[location];
[4185]165                        customerBrush = Brushes.Orange;
[4151]166                      } else if (t > dueTime[location]) {
[4015]167                        customerBrush = Brushes.Red;
168                      }
169
[4151]170                      t += serviceTime[location];
[4185]171                      customerBrushes[i] = customerBrush;
[4015]172                    }
[4151]173                    lastCustomer = location;
[3938]174                  }
[4015]175
176                  graphics.DrawPolygon(pens[((currentTour >= pens.Length) ? (pens.Length - 1) : (currentTour))], tourPoints);
[4185]177
178                  for (int i = 0; i < tour.Cities.Count; i++) {
179                    graphics.FillRectangle(customerBrushes[i], tourPoints[i + 1].X - 3, tourPoints[i + 1].Y - 3, 6, 6);
180                  }
181
182                  graphics.FillEllipse(Brushes.Blue, tourPoints[0].X - 5, tourPoints[0].Y - 5, 10, 10);
183
[4015]184                  currentTour++;
[3938]185                }
[4185]186              } else {
187                Point locationPoint;
188                //just draw customers
189                for (int i = 1; i < coordinates.Rows; i++) {
190                  locationPoint = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
191                                  bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
192
193                  graphics.FillRectangle(Brushes.Black, locationPoint.X - 3, locationPoint.Y - 3, 6, 6);
194                }
195
196                locationPoint = new Point(border + ((int)((coordinates[0, 0] - xMin) * xStep)),
197                                  bitmap.Height - (border + ((int)((coordinates[0, 1] - yMin) * yStep))));
198                graphics.FillEllipse(Brushes.Blue, locationPoint.X - 5, locationPoint.Y - 5, 10, 10);
[4068]199              }
[3938]200            }
201          }
[4015]202
203          for (int i = 0; i < pens.Length; i++)
204            pens[i].Dispose();
205
[3938]206          pictureBox.Image = bitmap;
207        }
208      }
209    }
210
211    private void Content_CoordinatesChanged(object sender, EventArgs e) {
212      if (InvokeRequired)
213        Invoke(new EventHandler(Content_CoordinatesChanged), sender, e);
214      else
215        GenerateImage();
216    }
217    private void Content_SolutionChanged(object sender, EventArgs e) {
218      if (InvokeRequired)
219        Invoke(new EventHandler(Content_SolutionChanged), sender, e);
220      else {
221        GenerateImage();
[4352]222        UpdateTourView();
[3938]223      }
224    }
225    private void pictureBox_SizeChanged(object sender, EventArgs e) {
226      GenerateImage();
227    }
228  }
229}
Note: See TracBrowser for help on using the repository browser.