public void Reinsert(RoutingPlan plan, List <Visit> toInsert, int discrep)//List<Route> routes, List<Visit> toInsert, int discrep)
        {
            iterations++;

            if (toInsert.Count == 0)
            {
                double newCost = plan.CalculateCost();
                if (newCost < bestPlanCost)
                {
                    bestPlan     = plan;
                    bestPlanCost = newCost;
                }
            }
            else
            {
                Visit visit = plan.ChooseFarthest(toInsert);
                toInsert.Remove(visit);

                int i = 0;
                foreach ((int, int)position in plan.RankedPositions(visit))
                {
                    if (i <= discrep)
                    {
                        // Copy bestPlan
                        RoutingPlan newPlan = new RoutingPlan(plan.CopyRoutes(), plan.GetProblem());
                        //Console.WriteLine("derdst" + toInsert.Count);
                        // Make new plan and call reinsert
                        newPlan.PlaceVisit(visit, position);
                        //Console.WriteLine("viertst" + toInsert.Count);
                        Reinsert(newPlan, toInsert, discrep - i);
                        i++;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
        public void Draw(RoutingPlan plan)
        {
            // FIND MAX DISTANCE
            (int, int, int, int) extrema = plan.GetExtrema();
            int maxX = extrema.Item3; //- extrema.Item1;
            int maxY = extrema.Item4; //- extrema.Item2;

            Random rand = new Random();
            using (var bmp = new Bitmap(maxX * 5, maxY * 5))
            using (var gfx = Graphics.FromImage(bmp))
            using (var pen = new Pen(Color.Black))
            {
                pen.Width = 3.0F;
                gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                gfx.Clear(Color.White);

                Visit lastVisit = plan.GetProblem().GetDepot();
                int depotX = lastVisit.GetX() * 5;
                int depotY = lastVisit.GetY() * 5;

                // Draw depot
                Rectangle rect = new Rectangle(depotX - 3, depotY - 3, 6, 6);
                gfx.DrawEllipse(pen, rect);

                PointF point1;
                PointF point2;

                foreach (Route route in plan.GetRoutes())
                {
                    pen.Color = Color.FromArgb(rand.Next());

                    // Get visits and depot
                    List<Visit> visits = route.GetVisits();

                    // Start with depot
                    int lastX = depotX;
                    int lastY = depotY;

                    foreach (Visit visit in visits)
                    {
                        // Draw visit
                        int xVisit = visit.GetX() * 5;
                        int yVisit = visit.GetY() * 5;
                        rect = new Rectangle(xVisit - 3, yVisit - 3, 6, 6);
                        gfx.DrawEllipse(pen, rect);

                        // Draw line to visit
                        point1 = new PointF(lastX, lastY);
                        point2 = new PointF(xVisit, yVisit);
                        gfx.DrawLine(pen, point1, point2);

                        // Change last visit
                        lastX = xVisit;
                        lastY = yVisit;
                    }

                    // Draw line back to depot
                    point1 = new PointF(lastX, lastY);
                    point2 = new PointF(depotX, depotY);
                    gfx.DrawLine(pen, point1, point2);
                }

                bmp.Save("RouteVisualisation.png");
            }
        }
        public RoutingPlan Search()
        {
            currentAttempts   = 0;
            bestEachIteration = new List <int>();

            capacityEachIteration         = new List <int>();
            routesEachIteration           = new List <int>();
            maxDistanceEachIteration      = new List <int>();
            AverageDeviationEachIteration = new List <int>();
            meanEachIteration             = new List <int>();
            costEachIteration             = new List <int> {
                (int)(bestPlan.CalculateCost() * 100)
            };
            toRemoveEachIteration = new List <int>();
            totalRemoved          = 0;

            for (int i = 0; i < maxIterations; i++)
            {
                //while (bestPlan.GetAmountOfRoutes() > 10) {



                // Check if currentAttempts >= attempts
                if (currentAttempts >= attempts)
                {
                    if (toRemove < 100)
                    {
                        toRemove++;
                    }
                    currentAttempts = 0;
                }

                double currentCost = bestPlan.CalculateCost();
                iterations = 0;

                // Copy bestPlan
                RoutingPlan newPlan  = new RoutingPlan(bestPlan.CopyRoutes(), bestPlan.GetProblem());
                RoutingPlan copyPlan = new RoutingPlan(bestPlan.CopyRoutes(), bestPlan.GetProblem());

                List <Visit> removed = RemoveVisits(newPlan);
                totalRemoved += toRemove;

                // copy removed
                List <Visit> removedCopy = new List <Visit>();
                foreach (Visit visit1 in removed)
                {
                    removedCopy.Add(visit1);
                }

                Reinsert(newPlan, removed, discrepancies);

                if (bestPlan.CalculateCost() < currentCost)
                {
                    currentAttempts = 0;

                    // Add to weretogether
                    foreach (Route route in copyPlan.GetRoutes())
                    {
                        foreach (Visit visit in removedCopy)
                        {
                            if (route.GetIds().Contains(visit.GetId()))
                            {
                                foreach (Visit v in route.GetVisits())
                                {
                                    if (v.GetId() != visit.GetId())
                                    {
                                        wereInRouteTogether[visit.GetId() - 1][v.GetId() - 1]++;
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    currentAttempts++;
                }

                bestEachIteration.Add(bestPlan.GetAmountOfRoutes());

                capacityEachIteration.Add(bestPlan.GetPercentageCapacity());
                routesEachIteration.Add(bestPlan.GetAmountOfRoutes());
                maxDistanceEachIteration.Add(bestPlan.GetLongestNormDistance());
                AverageDeviationEachIteration.Add(bestPlan.GetAverageDeviationRouteLength());
                meanEachIteration.Add((int)(bestPlan.GetAverageRouteLength() * 100));
                costEachIteration.Add((int)(bestPlan.CalculateCost() * 100));
                toRemoveEachIteration.Add(toRemove);
            }

            //Console.WriteLine(totalRemoved);

            return(bestPlan);
        }