//List<string> text = new List<string>();

        public LargeNeighbourhoodSearch(RoutingPlan plan, int maxIterations, int discrepancies,
                                        int attempts, int determinism)
        {
            this.bestPlan      = plan;
            this.bestPlanCost  = bestPlan.CalculateCost();
            this.maxIterations = maxIterations;
            this.discrepancies = discrepancies;
            this.attempts      = attempts;
            this.determinism   = determinism;



            for (int i = 0; i < 100; i++)
            {
                List <int> row = new List <int>();
                for (int j = 0; j < 100; j++)
                {
                    row.Add(0);
                }
                wereInRouteTogether.Add(row);
            }
        }
        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 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);
        }