//edge recombination operation
        public void MutateERO(Population population, List <Distance> listOfDistances, List <City> citiesList)
        {
            _calc.OrderPopulation(population);
            int sizeOfPopulation = population.PopulationList.Count();

            Track bestTrack   = population.PopulationList[0];
            int   sizeOfTrack = population.PopulationList[0].CitiesList.Count();

            int licznikPoprawy = 0;

            List <NeighborList> NLList = new List <NeighborList>();

            for (int i = 0; i < sizeOfTrack; i++)
            {
                NLList.Add(new NeighborList(citiesList[i].CityName, 0));
            }

            bool poprawiono = false;

            do
            {
                decimal toKill1 = Convert.ToDecimal(sizeOfPopulation) * 0.2m;
                decimal toKill2 = Convert.ToDecimal(sizeOfPopulation) - toKill1;
                population.PopulationList.RemoveRange(Convert.ToInt16(toKill1), Convert.ToInt16(toKill2));
                int z = 0;
                for (int i = population.PopulationList.Count; i < sizeOfPopulation; i++)
                {
                    for (int j = 0; j < sizeOfTrack; j++)
                    {
                        NeighborList jList = new NeighborList();
                        jList.CityName = citiesList[j].CityName;
                        NLList[j]      = jList;
                    }
                    int   newSizeOfPopulation = population.PopulationList.Count();
                    int   parent1Index        = _rand.Next(0, newSizeOfPopulation);
                    int   parent2Index        = _rand.Next(0, newSizeOfPopulation);
                    Track parent1             = population.PopulationList[parent1Index];
                    Track parent2             = population.PopulationList[parent2Index];


                    Track       child        = new Track();
                    City        nullCity     = new City(0, 0, "N");
                    List <City> nullCityList = new List <City>();
                    for (int j = 0; j < sizeOfTrack; j++)
                    {
                        nullCityList.Add(nullCity);
                    }
                    child.CitiesList = nullCityList;

                    string[] parent1Table = new string[sizeOfTrack];
                    string[] parent2Table = new string[sizeOfTrack];
                    string[] childTable   = new string[sizeOfTrack];


                    for (int j = 0; j < sizeOfTrack; j++)
                    {
                        parent1Table[j] = parent1.CitiesList[j].CityName;
                        parent2Table[j] = parent2.CitiesList[j].CityName;
                    }


#if DEBUG
                    string[] P1 = new string[sizeOfTrack];
                    string[] P2 = new string[sizeOfTrack];

                    for (int j = 0; j < sizeOfTrack; j++)
                    {
                        P1[j] = parent1Table[j];
                        P2[j] = parent2Table[j];
                    }
#endif

                    NLList = generateNeighborLists(NLList, parent2Table, parent1Table);

                    childTable[0]   = parent1Table[0];
                    parent1Table[0] = "X";

                    for (int j = 0; j < parent2Table.Length; j++)
                    {
                        if (parent2Table[j] == childTable[0])
                        {
                            parent2Table[j] = "X";
                        }
                    }

                    int idx = NLList.Select((value, index) => new { value, index })
                              .Where(x => x.value.CityName == childTable[0]).Select(x => x.index).FirstOrDefault();

                    NeighborList zaz = new NeighborList();
                    zaz.CityName = "X";
                    NLList[idx]  = zaz;


                    for (int j = 1; j < sizeOfTrack; j++)
                    {
                        int           r             = 0;
                        List <string> minimalCities = new List <string>();
                        int           minumum       = 4;
                        for (int k = 0; k < sizeOfTrack; k++)
                        {
                            if (NLList[k].Neighbors < minumum && NLList[k].CityName != "X")
                            {
                                minumum = NLList[k].Neighbors;
                            }
                        }
                        for (int k = 0; k < sizeOfTrack; k++)
                        {
                            if (NLList[k].Neighbors == minumum)
                            {
                                minimalCities.Add(NLList[k].CityName);
                            }
                        }

                        if (minimalCities.Count == 0)
                        {
                            Console.WriteLine("AAA");
                        }

                        try
                        {
                            r = _rand.Next(0, minimalCities.Count());
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("ERROR: Pusta lista miast z minimalną liczbą sąsiadów!!!");
                            throw;
                        }

                        childTable[j] = minimalCities[r];
                        for (int k = 0; k < parent2Table.Length; k++)
                        {
                            if (parent2Table[k] == minimalCities[r])
                            {
                                parent2Table[k] = "X";
                            }
                        }
                        for (int k = 0; k < parent1Table.Length; k++)
                        {
                            if (parent1Table[k] == minimalCities[r])
                            {
                                parent1Table[k] = "X";
                            }
                        }
                        int indeks = NLList.Select((value, index) => new { value, index })
                                     .Where(x => x.value.CityName == childTable[j]).Select(x => x.index).FirstOrDefault();

                        NeighborList zaa = new NeighborList();
                        zaa.CityName   = "X";
                        r              = indeks;
                        NLList[indeks] = zaa;
                    }

                    City[] citiesTable = new City[sizeOfTrack];
                    for (int j = 0; j < sizeOfTrack; j++)
                    {
                        City c  = new City(0, 0, "X");
                        var  cc = citiesList.Where(x => x.CityName == childTable[j]).GroupBy(x => x.CityName)
                                  .Select(x => x.FirstOrDefault());
                        foreach (var VARIABLE in cc)
                        {
                            c = VARIABLE;
                        }
                        citiesTable[j] = c;
                    }

                    for (int j = 0; j < sizeOfTrack; j++)
                    {
                        child.CitiesList[j] = citiesTable[j];
                    }
                    _calc.CalculateTotalDistance(child, listOfDistances);
                    population.PopulationList.Add(child);
                }

                _calc.OrderPopulation(population);

                decimal oldBest   = bestTrack.TotalDistance;
                decimal pretender = population.PopulationList[0].TotalDistance;

                if (population.PopulationList[0].TotalDistance < bestTrack.TotalDistance)
                {
                    bestTrack      = population.PopulationList[0];
                    licznikPoprawy = 0;
                }
                else
                {
                    licznikPoprawy++;
                }
                Iterations++;
                Console.WriteLine($"Iteracja {Iterations}, current best: {bestTrack.TotalDistance}");
                z++;
            } while (licznikPoprawy <= 20);
        }