Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 4847 was 4722, checked in by swagner, 13 years ago

Merged cloning refactoring branch back into trunk (#922)

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