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; using HeuristicLab.Problems.VehicleRouting.Views; using HeuristicLab.Problems.VehicleRouting; using HeuristicLab.PDPSimulation.Operators; namespace HeuristicLab.PDPSimulation.Views { [View("DynPDP View")] [Content(typeof(DynPDPProblemInstance), true)] public partial class DynPDPView : VRPProblemInstanceView { public new DynPDPProblemInstance Content { get { return (DynPDPProblemInstance)base.Content; } set { base.Content = value; } } public DynPDPView() { 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 depotCoordinates = Content.DepotCoordinates; 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; WaitingStrategy waitingStrategy = Content.WaitingStrategy; 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 && !Solution.GetTours().Exists(t => t.Stops.Exists(s => s > Content.Coordinates.Rows - Content.DepotCoordinates.Rows))) { 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) location = -1; //depot else if (i == tour.Stops.Count) location = 0; //depot else location = tour.Stops[i]; Point locationPoint; if (location == -1) { locationPoint = new Point(border + ((int)((coordinates[depot, 0] - xMin) * xStep)), bitmap.Height - (border + ((int)((coordinates[depot, 1] - yMin) * yStep)))); location = 0; } else if (location == 0) { locationPoint = new Point(border + ((int)((depotCoordinates[depot, 0] - xMin) * xStep)), bitmap.Height - (border + ((int)((depotCoordinates[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) { t = readyTime[depot]; } else if (i != tour.Stops.Count) { Brush customerBrush = Brushes.Black; Pen customerPen = Pens.Black; t += waitingStrategy.GetWaitingTime(t, Content, Solution, tour, i); 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) { Pen pen = pens[((currentTour >= pens.Length) ? (pens.Length - 1) : (currentTour))]; for (int i = 1; i < tourPoints.Length; i++) { Point start = tourPoints[i - 1]; Point end = tourPoints[i]; graphics.DrawLine(pen, start, end); } } 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(); } } }