コード例 #1
0
        /// <summary>
        /// Generates a random individual.
        /// </summary>
        /// <param name="solver"></param>
        /// <returns></returns>
        public Individual <List <int>, GeneticProblem, Fitness> Generate(
            Solver <List <int>, GeneticProblem, Fitness> solver)
        {
            // create new genomes list.
            List <int> genome = new List <int>();

            // build cities to place (in a thread-safe way!)
            List <int> cities_to_place = new List <int>();

            lock (solver)
            {
                for (int idx = 0; idx < solver.Problem.Along.Count; idx++)
                {
                    cities_to_place.Add(solver.Problem.Along[idx]);
                }
            }

            BestPlacementHelper helper = BestPlacementHelper.Instance();

            helper.DoFast(
                solver.Problem,
                solver.FitnessCalculator as FitnessCalculator,
                genome,
                cities_to_place);

            Individual individual = new Individual(genome);

            individual.CalculateFitness(solver.Problem, solver.FitnessCalculator);
            return(individual);
        }
コード例 #2
0
        internal static Population <List <Genome>, Problem, Fitness> InitializePopulation(
            Problem problem, Second target, int population_size, int round_count)
        {
            IRandomGenerator random = new RandomGenerator();

            // generate a list of cities to place.
            List <int> cities = new List <int>();

            for (int city_to_place = 0; city_to_place < problem.Cities; city_to_place++)
            {
                cities.Add(city_to_place);
            }

            // create the population
            Population <List <Genome>, Problem, Fitness> population = new Population <List <Genome>, Problem, Fitness>(
                null, false);

            // create the fitness calculator.
            FitnessCalculator fitness_calculator = new FitnessCalculator(5);

            while (population.Count < population_size)
            {
                OsmSharp.Logging.Log.TraceEvent("OsmSharp.Math.VRP.MultiSalesman.Facade", System.Diagnostics.TraceEventType.Information,
                                                "Initializing population individual {0}/{1}...", population.Count + 1, population_size);

                // create copy of cities
                List <int> cities_list = new List <int>(cities);

                // create new individuals.
                Individual individual =
                    new Individual(new List <Genome>());

                // place one random city in each round.
                for (int round_idx = 0; round_idx < round_count; round_idx++)
                {
                    // select a random city to place.
                    int city_idx = random.Generate(cities_list.Count);
                    int city     = cities_list[city_idx];
                    cities_list.RemoveAt(city_idx);

                    // create new genome.
                    Genome genome = new Genome();
                    genome.Add(city);
                    individual.Genomes.Add(genome);
                }

                individual = BestPlacementHelper.Do(
                    problem,
                    fitness_calculator,
                    individual,
                    cities_list);

                // add inidividual to the population.
                population.Add(individual);

                OsmSharp.Logging.Log.TraceEvent("OsmSharp.Math.VRP.MultiSalesman.Facade", System.Diagnostics.TraceEventType.Information,
                                                "Done!");
            }
            return(population);
        }
コード例 #3
0
        /// <summary>
        /// Re-places all the cities again to their own best place.
        /// </summary>
        /// <param name="solver"></param>
        /// <param name="mutating"></param>
        /// <returns></returns>
        private Individual <List <int>, GeneticProblem, Fitness> MutateByRePlacement(
            Solver <List <int>, GeneticProblem, Fitness> solver,
            Individual <List <int>, GeneticProblem, Fitness> mutating)
        {
            List <int> nodes_to_re_place = mutating.Genomes.ToList <int>();
            List <int> current_placement = mutating.Genomes.ToList <int>();

            foreach (int node_to_place in nodes_to_re_place)
            {
                // take the node out.
                current_placement.Remove(node_to_place);

                // place the node back in.
                BestPlacementHelper helper = BestPlacementHelper.Instance();
                helper.Do(
                    solver.Problem,
                    solver.FitnessCalculator as FitnessCalculator,
                    current_placement,
                    node_to_place);
            }

            Individual individual = new Individual(current_placement);

            individual.CalculateFitness(solver.Problem, solver.FitnessCalculator);
            return(individual);
        }
コード例 #4
0
        /// <summary>
        /// Mutates a given individual.
        /// </summary>
        /// <param name="solver"></param>
        /// <param name="mutating"></param>
        /// <returns></returns>
        public Individual <List <int>, GeneticProblem, Fitness> Mutate(
            Solver <List <int>, GeneticProblem, Fitness> solver,
            Individual <List <int>, GeneticProblem, Fitness> mutating)
        {
            // take a random piece.
            int idx = solver.Random.Next(mutating.Genomes.Count);

            List <int> new_genome = new List <int>(mutating.Genomes);
            int        customer   = new_genome[idx];

            new_genome.RemoveAt(idx);

            // apply best placement algorithm to place the selected genomes.
            BestPlacementHelper helper = BestPlacementHelper.Instance();

            helper.Do(
                solver.Problem,
                solver.FitnessCalculator as FitnessCalculator,
                new_genome,
                customer);

            Individual individual = new Individual(new_genome);

            individual.CalculateFitness(solver.Problem, solver.FitnessCalculator);
            return(individual);
        }
コード例 #5
0
        /// <summary>
        /// Take a piece of the genome and re-do best placement.
        /// </summary>
        /// <param name="solver"></param>
        /// <param name="mutating"></param>
        /// <returns></returns>
        private Individual <List <int>, GeneticProblem, Fitness> MutateByTakingPiece(
            Solver <List <int>, GeneticProblem, Fitness> solver,
            Individual <List <int>, GeneticProblem, Fitness> mutating)
        {
            // take a random piece.
            int idx1 = 0;
            int idx2 = 0;

            while (idx2 - idx1 == 0)
            {
                idx1 = solver.Random.Next(mutating.Genomes.Count - 1) + 1;
                idx2 = solver.Random.Next(mutating.Genomes.Count - 1) + 1;
                if (idx1 > idx2)
                {
                    int temp = idx1;
                    idx1 = idx2;
                    idx2 = temp;
                }
            }

            // if the genome range is big take it from the best individual.
            Individual <List <int>, GeneticProblem, Fitness> source =
                (mutating as Individual <List <int>, GeneticProblem, Fitness>);
            Individual <List <int>, GeneticProblem, Fitness> target =
                (mutating as Individual <List <int>, GeneticProblem, Fitness>);

            List <int> source_piece = source.Genomes.GetRange(idx1, idx2 - idx1);
            List <int> new_genome   = target.Genomes.GetRange(0, target.Genomes.Count);

            // insert the piece into the worst individual.
            // remove nodes in the source_piece.
            foreach (int source_node in source_piece)
            {
                new_genome.Remove(source_node);
            }

            // apply best placement algorithm to place the selected genomes.
            //List<int> genome = new List<int>();
            BestPlacementHelper helper = BestPlacementHelper.Instance();

            helper.DoFast(
                solver.Problem,
                solver.FitnessCalculator as FitnessCalculator,
                new_genome,
                source_piece);

            Individual individual = new Individual(new_genome);

            individual.CalculateFitness(solver.Problem, solver.FitnessCalculator);
            return(individual);
        }
コード例 #6
0
        /// <summary>
        /// Generates one individual.
        /// </summary>
        /// <param name="solver"></param>
        /// <returns></returns>
        public Individual <List <Genome>, Problem, Fitness> Generate(
            Solver <List <Genome>, Problem, Fitness> solver)
        {
            IRandomGenerator random = new RandomGenerator();

            // generate a list of cities to place.
            List <int> cities = new List <int>();

            for (int city_to_place = 0; city_to_place < solver.Problem.Cities; city_to_place++)
            {
                cities.Add(city_to_place);
            }

            // create new individuals.
            Individual individual =
                new Individual(new List <Genome>());

            //individual.Initialize();

            // place one random city in each round.
            for (int round_idx = 0; round_idx < solver.Problem.InitialVehicles; round_idx++)
            {
                // select a random city to place.
                int city_idx = random.Generate(cities.Count);
                int city     = cities[city_idx];
                cities.RemoveAt(city_idx);

                // create new genome.
                Genome genome = new Genome();
                genome.Add(city);
                individual.Genomes.Add(genome);
            }

            individual = BestPlacementHelper.DoFast(
                solver.Problem,
                (solver.FitnessCalculator as FitnessCalculator),
                individual,
                cities);

            return(individual);
        }
コード例 #7
0
        internal static List <Genome> EstimateVehicles <EdgeType, VertexType>(
            Problem problem,
            Second min, Second max)
            where EdgeType : class
            where VertexType : class, IEquatable <VertexType>
        {
            // create the fitness calculator.
            FitnessCalculator fitness_calculator = new FitnessCalculator(5);

            IRandomGenerator random = new RandomGenerator();

            double average_time  = (min.Value + max.Value) / 2.0;
            double previous_time = average_time;

            // generate a list of cities to place.
            List <int> cities = new List <int>();

            for (int city_to_place = 0; city_to_place < problem.Cities; city_to_place++)
            {
                cities.Add(city_to_place);
            }

            // first optimize the number of vehicles; this means generate rounds that are as close to the max as possible.
            List <Genome> generated_rounds = new List <Genome>();
            bool          new_round        = true;
            Genome        current_round    = null;

            while (cities.Count > 0)
            {
                OsmSharp.Logging.Log.TraceEvent("OsmSharp.Math.VRP.MultiSalesman.Facade", System.Diagnostics.TraceEventType.Information,
                                                "Placing cities {0}/{1}", cities.Count, problem.Cities);
                if (_registered_progress_reporter != null)
                {
                    ProgressStatus status = new ProgressStatus();
                    status.TotalNumber   = problem.Cities;
                    status.CurrentNumber = problem.Cities - cities.Count;
                    status.Message       = "Placing cities...";
                    _registered_progress_reporter.Report(status);
                }

                // create a new round if needed.
                int city;
                int city_idx;
                if (new_round)
                {
                    new_round     = false;
                    current_round = new Genome();

                    // select a random city to place.
                    city_idx = random.Generate(cities.Count);
                    city     = cities[city_idx];
                    cities.RemoveAt(city_idx);
                    current_round.Add(city);

                    previous_time = average_time;
                }

                if (cities.Count > 0)
                {
                    // find the best city to place next.
                    // calculate the best position to place the next city.
                    BestPlacementHelper.BestPlacementResult new_position_to_place =
                        BestPlacementHelper.CalculateBestPlacementInGenome(
                            problem,
                            fitness_calculator,
                            current_round,
                            cities);

                    city = new_position_to_place.City;

                    // remove the node from the source list.
                    cities.Remove(city);

                    // place the node.
                    current_round.Insert(new_position_to_place.CityIdx, new_position_to_place.City);

                    // calculate the time.
                    double time = fitness_calculator.CalculateTime(
                        problem, current_round);

                    if (average_time < time)
                    { // time limit has been reached.
                        double diff_average  = time - average_time;
                        double diff_previous = average_time - previous_time;

                        if (diff_average > diff_previous)
                        { // remove the last added city.
                            current_round.Remove(city);
                            cities.Add(city);
                        }
                        else
                        { // keep the last city.
                        }

                        // keep the generated round.
                        generated_rounds.Add(current_round);
                        new_round = true;
                    }
                    previous_time = time;
                }
            }

            return(generated_rounds);
        }
コード例 #8
0
        CrossOver(Solver <List <int>, GeneticProblem, Fitness> solver,
                  Individual <List <int>, GeneticProblem, Fitness> parent1,
                  Individual <List <int>, GeneticProblem, Fitness> parent2)
        {
            // take a random piece.
            int idx1 = 0;
            int idx2 = 0;

            while (idx2 - idx1 == 0)
            {
                idx1 = solver.Random.Next(parent1.Genomes.Count - 1) + 1;
                idx2 = solver.Random.Next(parent2.Genomes.Count - 1) + 1;
                if (idx1 > idx2)
                {
                    int temp = idx1;
                    idx1 = idx2;
                    idx2 = temp;
                }
            }

            // if the genome range is big take it from the best individual.
            Individual <List <int>, GeneticProblem, Fitness> source =
                (parent1 as Individual <List <int>, GeneticProblem, Fitness>);
            Individual <List <int>, GeneticProblem, Fitness> target =
                (parent2 as Individual <List <int>, GeneticProblem, Fitness>);

            if (idx2 - idx1 < parent1.Genomes.Count / 2)
            { // the range is small; take the worste genomes.
                if (source.Fitness.CompareTo(target.Fitness) > 0)
                {
                    Individual <List <int>, GeneticProblem, Fitness> temp = source;
                    source = target;
                    target = temp;
                }
                else
                {
                    // do nothing.
                }
            }
            else
            { // the range is big; take the good genomes.
                if (source.Fitness.CompareTo(target.Fitness) > 0)
                {
                    // do nothing.
                }
                else
                {
                    Individual <List <int>, GeneticProblem, Fitness> temp = source;
                    source = target;
                    target = temp;
                }
            }
            List <int> source_piece = source.Genomes.GetRange(idx1, idx2 - idx1);
            List <int> new_genome   = target.Genomes.GetRange(0, target.Genomes.Count);

            // insert the piece into the worst individual.
            // remove nodes in the source_piece.
            foreach (int source_node in source_piece)
            {
                new_genome.Remove(source_node);
            }

            // apply best placement algorithm to place the selected genomes.
            //List<int> genome = new List<int>();
            BestPlacementHelper helper = BestPlacementHelper.Instance();

            helper.DoFast(
                solver.Problem,
                solver.FitnessCalculator as FitnessCalculator,
                new_genome,
                source_piece);

            // return a new individual based on the new genome list.
            Individual individual = new Individual(new_genome);

            individual.CalculateFitness(solver.Problem, solver.FitnessCalculator);
            return(individual);
        }