using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using HeuristicLab.MainForm; using HeuristicLab.Problems.VehicleRouting.ProblemInstances; using HeuristicLab.Data; namespace HeuristicLab.Problems.VehicleRouting.Views { [View("MDCVRPPDTWProblemInstance View")] [Content(typeof(MDCVRPPDTWProblemInstance), true)] public partial class MDCVRPPDTWView : VRPProblemInstanceView { public new MDCVRPPDTWProblemInstance Content { get { return (MDCVRPPDTWProblemInstance)base.Content; } set { base.Content = value; } } public MDCVRPPDTWView() { InitializeComponent(); } private bool drawFlow = false; protected override void pictureBox_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { drawFlow = !drawFlow; GenerateImage(); } } protected override void DrawVisualization(Bitmap bitmap) { DoubleMatrix coordinates = Content.Coordinates; DoubleMatrix distanceMatrix = Content.DistanceMatrix; BoolValue useDistanceMatrix = Content.UseDistanceMatrix; DoubleArray dueTime = Content.DueTime; DoubleArray serviceTime = Content.ServiceTime; DoubleArray readyTime = Content.ReadyTime; DoubleArray demand = Content.Demand; IntArray pickupDeliveryLocation = Content.PickupDeliveryLocation; IntArray vehicleAssignment = Content.VehicleDepotAssignment; int depots = Content.Depots.Value; int cities = Content.Cities.Value; 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)), 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)), 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)), 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)), 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)), 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)}; Pen flowPen = new Pen(Brushes.Red, 3); flowPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor; flowPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; if ((coordinates != null) && (coordinates.Rows > 0) && (coordinates.Columns == 2)) { double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue; for (int i = 0; i < coordinates.Rows; i++) { if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0]; if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1]; if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0]; if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1]; } int border = 20; double xStep = xMax != xMin ? (bitmap.Width - 2 * border) / (xMax - xMin) : 1; double yStep = yMax != yMin ? (bitmap.Height - 2 * border) / (yMax - yMin) : 1; using (Graphics graphics = Graphics.FromImage(bitmap)) { if (Solution != null) { for (int i = 0; i < Content.Depots.Value; i++) { Point locationPoint = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)), bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep)))); graphics.FillEllipse(Brushes.Blue, locationPoint.X - 5, locationPoint.Y - 5, 10, 10); } int currentTour = 0; foreach (Tour tour in Solution.GetTours()) { int tourIndex = Solution.GetTourIndex(tour); int vehicle = Solution.GetVehicleAssignment(tourIndex); int depot = vehicleAssignment[vehicle]; double t = 0.0; Point[] tourPoints = new Point[tour.Stops.Count + 2]; Brush[] customerBrushes = new Brush[tour.Stops.Count]; Pen[] customerPens = new Pen[tour.Stops.Count]; bool[] validPickupDelivery = new bool[tour.Stops.Count]; int lastCustomer = 0; Dictionary stops = new Dictionary(); for (int i = -1; i <= tour.Stops.Count; i++) { int location = 0; if (i == -1 || i == tour.Stops.Count) location = 0; //depot else location = tour.Stops[i]; Point locationPoint; if (location == 0) { locationPoint = new Point(border + ((int)((Content.Coordinates[depot, 0] - xMin) * xStep)), bitmap.Height - (border + ((int)((Content.Coordinates[depot, 1] - yMin) * yStep)))); } else { locationPoint = new Point(border + ((int)((Content.GetCoordinates(location)[0] - xMin) * xStep)), bitmap.Height - (border + ((int)((Content.GetCoordinates(location)[1] - yMin) * yStep)))); } tourPoints[i + 1] = locationPoint; if (i != -1 && i != tour.Stops.Count) { Brush customerBrush = Brushes.Black; Pen customerPen = Pens.Black; t += Content.GetDistance( lastCustomer, location, Solution); int locationIndex; if (location == 0) locationIndex = depot; else locationIndex = location + depots - 1; if (t < readyTime[locationIndex]) { t = readyTime[locationIndex]; customerBrush = Brushes.Orange; customerPen = Pens.Orange; } else if (t > dueTime[locationIndex]) { customerBrush = Brushes.Red; customerPen = Pens.Red; } t += serviceTime[location - 1]; validPickupDelivery[i] = ((demand[location - 1] >= 0) || (stops.ContainsKey(pickupDeliveryLocation[location - 1]))); customerBrushes[i] = customerBrush; customerPens[i] = customerPen; stops.Add(location, true); } lastCustomer = location; } if (!drawFlow) graphics.DrawPolygon(pens[((currentTour >= pens.Length) ? (pens.Length - 1) : (currentTour))], tourPoints); for (int i = 0; i < tour.Stops.Count; i++) { if (validPickupDelivery[i]) { graphics.FillRectangle(customerBrushes[i], tourPoints[i + 1].X - 3, tourPoints[i + 1].Y - 3, 6, 6); if (demand[tour.Stops[i] - 1] < 0 && drawFlow) { int location = pickupDeliveryLocation[tour.Stops[i] - 1]; int source = tour.Stops.IndexOf(location); graphics.DrawLine(flowPen, tourPoints[source + 1], tourPoints[i + 1]); } } else graphics.DrawRectangle(customerPens[i], tourPoints[i + 1].X - 3, tourPoints[i + 1].Y - 3, 6, 6); } graphics.FillEllipse(Brushes.DarkBlue, tourPoints[0].X - 5, tourPoints[0].Y - 5, 10, 10); currentTour++; } } else { { Point[] locationPoints = new Point[cities]; //just draw customers for (int i = 0; i < cities; i++) { locationPoints[i] = new Point(border + ((int)((Content.GetCoordinates(i + 1)[0] - xMin) * xStep)), bitmap.Height - (border + ((int)((Content.GetCoordinates(i + 1)[1] - yMin) * yStep)))); graphics.FillRectangle(Brushes.Black, locationPoints[i].X - 3, locationPoints[i].Y - 3, 6, 6); } if (drawFlow) { for (int i = 0; i < cities; i++) { if (demand[i] < 0) { graphics.DrawLine(flowPen, locationPoints[pickupDeliveryLocation[i] - 1], locationPoints[i]); } } } for (int i = 0; i < Content.Depots.Value; i++) { Point locationPoint = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)), bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep)))); graphics.FillEllipse(Brushes.Blue, locationPoint.X - 5, locationPoint.Y - 5, 10, 10); } } } } } for (int i = 0; i < pens.Length; i++) pens[i].Dispose(); flowPen.Dispose(); } } }