/// <summary>
        /// Places cities into an individual.
        /// </summary>
        /// <param name="problem"></param>
        /// <param name="calculator"></param>
        /// <param name="genomes"></param>
        /// <param name="cities_to_place"></param>
        /// <returns></returns>
        public static BestPlacementResult CalculateBestPlacementInGenomes(
            Problem problem,
            FitnessCalculator calculator,
            List <Genome> genomes,
            List <int> cities_to_place)
        {
            // initialize the best placement result.
            BestPlacementResult result = null;

            // place all the cities until there are no more left.
            // try to place every city in every round.
            for (int round_idx = 0; round_idx < genomes.Count; round_idx++)
            {
                Genome genome = genomes[round_idx];
                BestPlacementResult new_result =
                    BestPlacementHelper.CalculateBestPlacementInGenome(
                        problem,
                        calculator,
                        genome,
                        cities_to_place);
                if (result == null ||
                    new_result.Increase < result.Increase)
                {
                    result          = new_result;
                    result.RoundIdx = round_idx;
                }
            }

            // return the result.
            return(result);
        }
        /// <summary>
        /// Places a city into an idividual.
        /// </summary>
        /// <param name="problem"></param>
        /// <param name="calculator"></param>
        /// <param name="round_idx"></param>
        /// <param name="individual"></param>
        /// <param name="city_to_place"></param>
        /// <returns></returns>
        internal static BestPlacementResult CalculateBestPlacementInIndividual(
            Problem problem,
            FitnessCalculator calculator,
            int round_idx,
            Individual <List <Genome>, Problem, Fitness> individual,
            int city_to_place)
        {
            // if the target round is empty best placement is impossible.
            Genome round = individual.Genomes[round_idx];

            // do best placement in the genome/round.
            BestPlacementResult result =
                BestPlacementHelper.CalculateBestPlacementInGenome(problem, calculator, round, city_to_place);

            // set the round index.
            result.RoundIdx = round_idx;
            if (!individual.FitnessCalculated)
            {
                individual.CalculateFitness(
                    problem, calculator);
            }
            result.Fitness = calculator.Adjust(
                problem,
                individual.Fitness,
                round_idx,
                result.Increase);

            // return the result.
            return(result);
        }
        internal static BestPlacementResult CalculateBestPlacementInGenome(
            Problem problem,
            FitnessCalculator calculator,
            Genome genome,
            List <int> cities_to_place)
        {
            // initialize the best placement result.
            BestPlacementResult result
                = new BestPlacementResult();

            result.RoundIdx = -1;

            // try and place all cities.
            for (int city_idx = 0; city_idx < cities_to_place.Count; city_idx++)
            {
                // try to place first city.
                int city = cities_to_place[city_idx];

                // place the city and check the result.
                BestPlacementResult current_result =
                    BestPlacementHelper.CalculateBestPlacementInGenome(
                        problem,
                        calculator,
                        genome,
                        city);

                // check current result
                //if (result.Increase == null ||
                //    current_result.Increase < result.Increase)
                if (current_result.Increase < result.Increase)
                {
                    result = current_result;
                }
            }

            return(result);
        }