source: branches/VRP/HeuristicLab.Problems.VehicleRouting.Views/3.4/CVRPPDTWView.cs @ 6851

Last change on this file since 6851 was 6851, checked in by svonolfe, 8 years ago

Added support for multi depot CVRP instances (#1177)

File size: 7.9 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Data;
5using System.Drawing;
6using System.Text;
7using System.Windows.Forms;
8using HeuristicLab.MainForm;
9using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
10using HeuristicLab.Data;
11
12namespace HeuristicLab.Problems.VehicleRouting.Views {
13  [View("CVRPPDTWProblemInstance View")]
14  [Content(typeof(CVRPPDTWProblemInstance), true)]
15  public partial class CVRPPDTWView : VRPProblemInstanceView {
16    public new CVRPPDTWProblemInstance Content {
17      get { return (CVRPPDTWProblemInstance)base.Content; }
18      set { base.Content = value; }
19    }
20
21    public CVRPPDTWView() {
22      InitializeComponent();
23    }
24
25    private bool drawFlow = false;
26
27    protected override void pictureBox_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) {
28      if (e.Button == System.Windows.Forms.MouseButtons.Right) {
29        drawFlow = !drawFlow;
30        GenerateImage();
31      }     
32    }
33
34    protected override void DrawVisualization(Bitmap bitmap) {
35      DoubleMatrix coordinates = Content.Coordinates;
36      DoubleMatrix distanceMatrix = Content.DistanceMatrix;
37      BoolValue useDistanceMatrix = Content.UseDistanceMatrix;
38      DoubleArray dueTime = Content.DueTime;
39      DoubleArray serviceTime = Content.ServiceTime;
40      DoubleArray readyTime = Content.ReadyTime;
41      DoubleArray demand = Content.Demand;
42      IntArray pickupDeliveryLocation = Content.PickupDeliveryLocation;
43
44      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)),
45                    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)),
46                    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)),
47                    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)),
48                    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)),
49                    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)};
50
51      Pen flowPen = new Pen(Brushes.Red, 3);
52      flowPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
53      flowPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
54
55      if ((coordinates != null) && (coordinates.Rows > 0) && (coordinates.Columns == 2)) {
56        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
57        for (int i = 0; i < coordinates.Rows; i++) {
58          if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
59          if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
60          if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
61          if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
62        }
63
64        int border = 20;
65        double xStep = xMax != xMin ? (bitmap.Width - 2 * border) / (xMax - xMin) : 1;
66        double yStep = yMax != yMin ? (bitmap.Height - 2 * border) / (yMax - yMin) : 1;
67
68        using (Graphics graphics = Graphics.FromImage(bitmap)) {
69          if (Solution != null) {
70            int currentTour = 0;
71            foreach (Tour tour in Solution.GetTours()) {
72              double t = 0.0;
73              Point[] tourPoints = new Point[tour.Stops.Count + 2];
74              Brush[] customerBrushes = new Brush[tour.Stops.Count];
75              Pen[] customerPens = new Pen[tour.Stops.Count];
76              bool[] validPickupDelivery = new bool[tour.Stops.Count];
77              int lastCustomer = 0;
78
79              Dictionary<int, bool> stops = new Dictionary<int, bool>();
80              for (int i = -1; i <= tour.Stops.Count; i++) {
81                int location = 0;
82
83                if (i == -1 || i == tour.Stops.Count)
84                  location = 0; //depot
85                else
86                  location = tour.Stops[i];
87
88                Point locationPoint = new Point(border + ((int)((coordinates[location, 0] - xMin) * xStep)),
89                                bitmap.Height - (border + ((int)((coordinates[location, 1] - yMin) * yStep))));
90                tourPoints[i + 1] = locationPoint;
91
92                if (i != -1 && i != tour.Stops.Count) {
93                  Brush customerBrush = Brushes.Black;
94                  Pen customerPen = Pens.Black;
95
96                  t += Content.GetDistance(
97                    lastCustomer, location, Solution);
98
99                  if (t < readyTime[location]) {
100                    t = readyTime[location];
101                    customerBrush = Brushes.Orange;
102                    customerPen = Pens.Orange;
103
104                  } else if (t > dueTime[location]) {
105                    customerBrush = Brushes.Red;
106                    customerPen = Pens.Red;
107                  }
108
109                  t += serviceTime[location];
110
111                  validPickupDelivery[i] =
112                    ((demand[location] >= 0) ||
113                     (stops.ContainsKey(pickupDeliveryLocation[location])));
114
115                  customerBrushes[i] = customerBrush;
116                  customerPens[i] = customerPen;
117
118                  stops.Add(location, true);
119                }
120                lastCustomer = location;
121              }
122
123              if (!drawFlow)
124                graphics.DrawPolygon(pens[((currentTour >= pens.Length) ? (pens.Length - 1) : (currentTour))], tourPoints);
125
126              for (int i = 0; i < tour.Stops.Count; i++) {
127                if (validPickupDelivery[i]) {
128                  graphics.FillRectangle(customerBrushes[i], tourPoints[i + 1].X - 3, tourPoints[i + 1].Y - 3, 6, 6);
129
130                  if (demand[tour.Stops[i]] < 0 && drawFlow) {
131                    int location = pickupDeliveryLocation[tour.Stops[i]];
132                    int source = tour.Stops.IndexOf(location);
133
134                    graphics.DrawLine(flowPen, tourPoints[source + 1], tourPoints[i + 1]);
135                  }
136                } else
137                  graphics.DrawRectangle(customerPens[i], tourPoints[i + 1].X - 3, tourPoints[i + 1].Y - 3, 6, 6);
138              }
139
140              graphics.FillEllipse(Brushes.Blue, tourPoints[0].X - 5, tourPoints[0].Y - 5, 10, 10);
141
142              currentTour++;
143            }
144          } else {
145            {
146              Point[] locationPoints = new Point[coordinates.Rows];
147              //just draw customers
148              for (int i = 1; i < coordinates.Rows; i++) {
149                locationPoints[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
150                                bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
151
152                graphics.FillRectangle(Brushes.Black, locationPoints[i].X - 3, locationPoints[i].Y - 3, 6, 6);
153              }
154
155              if (drawFlow) {
156                for (int i = 1; i < coordinates.Rows; i++) {
157                  if (demand[i] < 0) {
158
159                    graphics.DrawLine(flowPen, locationPoints[pickupDeliveryLocation[i]], locationPoints[i]);
160                  }
161                }
162              }
163
164              Point locationPoint = new Point(border + ((int)((coordinates[0, 0] - xMin) * xStep)),
165                                bitmap.Height - (border + ((int)((coordinates[0, 1] - yMin) * yStep))));
166              graphics.FillEllipse(Brushes.Blue, locationPoint.X - 5, locationPoint.Y - 5, 10, 10);
167            }
168          }
169        }
170      }
171
172      for (int i = 0; i < pens.Length; i++)
173        pens[i].Dispose();
174
175      flowPen.Dispose();
176    }
177  }
178}
Note: See TracBrowser for help on using the repository browser.