Пример #1
0
    private void GenerateInitialNetsAsCopy(NEATNet net)
    {
        generationNumber = 0; //0 since simulaiton has no been started yet
        testCounter      = 0; //none have been tested
        speciesManager   = new Species(this);

        for (int i = 0; i < populationSize; i++)
        {                                       //run through population size
            NEATNet netCopy = new NEATNet(net); //create net with consultor, perceptron information and test time
            netCopy.SetNetFitness(0f);
            netCopy.SetTimeLived(0f);
            netCopy.SetTestTime(testTime);
            netCopy.ClearNodeValues();
            netCopy.GenerateNeuralNetworkFromGenome();  //< NEW LSES ADDITION

            Population population = speciesManager.ClosestSpecies(netCopy);

            if (population == null)
            {
                population = speciesManager.CreateNewSpecie(new Color(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f)));
                population.Add(netCopy);
            }
            else
            {
                population.Add(netCopy);
            }
        }
    }
Пример #2
0
        private static void initializeGeneticAlgorithm(
            int populationSize,
            int parentalChromosomesSurviveCount,
            OptimizableNeuralNetwork baseNeuralNetwork)
        {
            Population <OptimizableNeuralNetwork> brains = new Population <OptimizableNeuralNetwork>();

            for (int i = 0; i < (populationSize - 1); i++)
            {
                if (baseNeuralNetwork == null)
                {
                    brains.Add(NeuralNetworkDrivenAgent.randomNeuralNetworkBrain());
                }
                else
                {
                    brains.Add(baseNeuralNetwork.Mutate());
                }
            }
            if (baseNeuralNetwork != null)
            {
                brains.Add(baseNeuralNetwork);
            }
            else
            {
                brains.Add(NeuralNetworkDrivenAgent.randomNeuralNetworkBrain());
            }

            ga = new GeneticAlgorithm <OptimizableNeuralNetwork, double>(brains, TournamentEnvironmentFitness.Calculate);

            ga.ParentChromosomesSurviveCount = parentalChromosomesSurviveCount;
        }
Пример #3
0
        public void PopuationEnumerationShouldNotProduceNull()
        {
            void AssertNoNulls()
            {
                foreach (var p in population)
                {
                    p.Should().NotBeNull();
                }
            }

            AssertNoNulls();

            population.Add(CreatePhenotypeMock(1).Object);
            AssertNoNulls();

            population.Fill(() => CreatePhenotypeMock(1).Object);
            AssertNoNulls();

            population.Clear(2, EAMode.MaximizeFitness);
            AssertNoNulls();

            population.Fill(() => CreatePhenotypeMock(1).Object);
            population.Clear(1, EAMode.MaximizeFitness);
            AssertNoNulls();

            population.Clear();
            AssertNoNulls();
        }
Пример #4
0
        public void TestSelection()
        {
            var offspring  = new Population(2);
            var population = new Population(2);

            var o0 = new P("o0", 1.0);

            offspring.Add(o0);
            var o1 = new P("o1", 0.0);

            offspring.Add(o1);
            var p0 = new P("p0", 1.0);

            population.Add(p0);
            var p1 = new P("p1", 0.0);

            population.Add(p1);

            var genmix = new GenerationalReplacementAdultSelection();

            genmix.SelectAdults(offspring, population, 2, EAMode.MaximizeFitness);

            Assert.IsTrue(population.Contains(o0));
            Assert.IsTrue(population.Contains(o1));
            Assert.IsFalse(population.Contains(p0));
            Assert.IsFalse(population.Contains(p1));
        }
Пример #5
0
        public void ClearWithOneEliteShouldLeavePhenotypeWithMinFitness()
        {
            var popsize = 3;

            population = new Population(popsize);

            var m0 = new Mock <IPhenotype>();

            m0.SetupGet(p => p.Fitness).Returns(1.0);
            population.Add(m0.Object);

            var m1 = new Mock <IPhenotype>();

            m1.Setup(p => p.Fitness).Returns(0.8);
            population.Add(m1.Object);

            var m2 = new Mock <IPhenotype>();

            m2.Setup(p => p.Fitness).Returns(0.6);
            population.Add(m2.Object);

            population.Evaluate(true, null);
            population.Clear(1, EAMode.MinimizeFitness);

            for (int i = 1; i < population.Size; i++)
            {
                Assert.IsNull(population[i]);
            }
            population[0].Fitness.Should().Be(0.6);
        }
Пример #6
0
        public void TestSelectionWithMinimizing()
        {
            var offspring  = new Population(2);
            var population = new Population(2);

            var o0 = new P("o0", 1.0);

            offspring.Add(o0);
            var o1 = new P("o1", 0.0);

            offspring.Add(o1);
            var p0 = new P("p0", 1.0);

            population.Add(p0);
            var p1 = new P("p1", 0.0);

            population.Add(p1);

            var genmix = new GenerationalMixingAdultSelection(new DefaultRandomNumberGenerator());

            genmix.SelectAdults(offspring, population, 2, EAMode.MinimizeFitness);

            Assert.IsFalse(population.Contains(o0));
            Assert.IsTrue(population.Contains(o1));
            Assert.IsFalse(population.Contains(p0));
            Assert.IsTrue(population.Contains(p1));
        }
Пример #7
0
 private void CreateChildrenAndPutThemIntoPopulation(Population population)
 {
     for (var k = 0; k < population.Count / 2; k++)
     {
         population.Add(CreateChildrenFromParents(population[k], population[k + 1]));
         population.Add(CreateChildrenFromParents(population[k + 1], population[k]));
     }
 }
Пример #8
0
    /// <summary>
    /// Generate initial neural network, where all inputs perceptrons are connected to all output perceptrons.
    /// Each of these nerual networks is mutated one time for slight change.
    /// And then they are paired up into species.
    /// </summary>
    private void GenerateInitialNets()
    {
        generationNumber = 0; //0 since simulaiton has no been started yet
        testCounter      = 0; //none have been tested
        speciesManager   = new Species(this);
        //species = new List<List<NEATNet>>(); //create an empty population list

        for (int i = 0; i < populationSize; i++)
        {                                                                                                        //run through population size
            NEATNet net = new NEATNet(consultor, numberOfInputPerceptrons, numberOfOutputPerceptrons, testTime); //create net with consultor, perceptron information and test time
            net.Mutate();                                                                                        //mutate once for diversity (must make sure SJW's aren't triggered)
            net.GenerateNeuralNetworkFromGenome();                                                               //< NEW LSES ADDITION

            Population population = speciesManager.ClosestSpecies(net);

            if (population == null)
            {
                population = speciesManager.CreateNewSpecie(new Color(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f)));
                population.Add(net);
            }
            else
            {
                population.Add(net);
            }

            /*if (species.Count == 0) { //if nothing exists yet
             *  List<NEATNet> newSpecies = new List<NEATNet>(); //create a new species
             *  newSpecies.Add(net); //add net to this new species
             *  species.Add(newSpecies); //add new species to species list
             * }
             * else { //if at least one species exists
             *  int numberOfSpecies = species.Count; //save species count
             *  int location = -1; //-1 means no species match found,  0 >= will mean a species match has been found at a given index
             *
             *  for (int j = 0; j < numberOfSpecies; j++) { //run through species count
             *      int numberOfNets = species[j].Count; //number of organisum in species at index j
             *      int randomIndex = UnityEngine.Random.Range(0, numberOfNets); //pick a random network within this species
             *
             *      if (NEATNet.SameSpeciesV2(species[j][randomIndex], net)) { //check if new network and random network belong to the same species
             *          location = j; //new species can be added to index j
             *          break; //break out of loop
             *      }
             *  }
             *
             *  if (location == -1) { //if no species found
             *      //create new species and add to that
             *      List<NEATNet> newSpecies = new List<NEATNet>();
             *      newSpecies.Add(net);
             *      species.Add(newSpecies);
             *  }
             *  else { //found species that match this network
             *      species[location].Add(net); //add net to the matched species list
             *  }
             * }*/
        }
    }
Пример #9
0
        void PopulateNextGeneration(Population <T> nextGen, List <Individual <T> > fittestList)
        {
            fittestList.ForEach(f => nextGen.Add(f));

            while (nextGen.PopulationSize < _population.PopulationSize)
            {
                Individual <T>[] parents = SelectParents(fittestList);
                Individual <T>   child   = CrossoverProvider.GetNextCrossover().PerformCrossover(parents [0], parents [1]);
                nextGen.Add(child);
            }
            ;
        }
Пример #10
0
        public void CrossoverPopulation(Population population)
        {
            for (int i = 0; i < population.RemoveCount / 2; i++)
            {
                var firstParent  = population.GetRandomMember();
                var secondParent = population.GetRandomMember();

                var children = Crossover(firstParent, secondParent, population.DietaryReferenceIntakes, population.Foods);

                population.Add(children[0]);
                population.Add(children[1]);
            }
        }
Пример #11
0
        public void SelectAdults(Population offspring, Population population, int n, EAMode mode)
        {
            var roulette = new Roulette <IPhenotype>(_rng, offspring.Size + population.Size);

            if (mode == EAMode.MaximizeFitness)
            {
                roulette.AddAll(offspring, e => e.Fitness);
                roulette.AddAll(population, e => e.Fitness);

                population.Clear();
                for (int i = 0; i < n; i++)
                {
                    population.Add(roulette.SpinAndRemove());
                }
            }
            else if (mode == EAMode.MinimizeFitness)
            {
                double p_max = Double.MinValue;
                double p_min = Double.MaxValue;

                foreach (var e in offspring)
                {
                    p_max = Math.Max(e.Fitness, p_max);
                    p_min = Math.Min(e.Fitness, p_min);
                }
                foreach (var e in population)
                {
                    p_max = Math.Max(e.Fitness, p_max);
                    p_min = Math.Min(e.Fitness, p_min);
                }

                foreach (var e in offspring)
                {
                    roulette.Add(e, (p_max + p_min) - e.Fitness);
                }
                foreach (var e in population)
                {
                    roulette.Add(e, (p_max + p_min) - e.Fitness);
                }

                population.Clear();
                for (int i = 0; i < n; i++)
                {
                    population.Add(roulette.SpinAndRemove());
                }
            }
            else
            {
                throw new NotImplementedException(mode.ToString());
            }
        }
Пример #12
0
        /// <summary>
        /// Operator's operate method.
        /// </summary>
        /// <param name="parents">parents</param>
        /// <param name="offspring">offspring</param>
        public void Operate(Population parents, Population offspring)
        {
            int size = parents.GetPopulationSize();

            for (int i = 0; i < size / 2; i++)
            {
                Individual p1 = parents.Get(2 * i);
                Individual p2 = parents.Get(2 * i + 1);

                Individual o1 = (Individual)p1.Clone();
                Individual o2 = (Individual)p2.Clone();

                if (rng.NextDouble() < xOverProb)
                {
                    HashSet <int> indices = new HashSet <int>();
                    bool          flipper = true;

                    // select crossover points
                    while (indices.Count < numberOfPoints)
                    {
                        indices.Add(rng.NextInt(p1.Length()));
                    }

                    // perform the crossover
                    for (int j = 0; j < p1.Length(); j++)
                    {
                        if (indices.Contains(j))
                        {
                            flipper = flipper == true ? false : true;
                        }

                        if (flipper)
                        {
                            o1.SetActivityOnEdge(j, p1.IsActiveOnEdge(j));
                            o2.SetActivityOnEdge(j, p2.IsActiveOnEdge(j));
                        }
                        else
                        {
                            o1.SetActivityOnEdge(j, p2.IsActiveOnEdge(j));
                            o2.SetActivityOnEdge(j, p1.IsActiveOnEdge(j));
                        }
                    }
                    o1.changed = true;
                    o2.changed = true;
                }
                offspring.Add(o1);
                offspring.Add(o2);
            }
        }
Пример #13
0
 public bool LoadGeneration(string filePath, bool Encript)
 {
     if (!System.IO.File.Exists(filePath))
     {
         return(false);
     }
     SaveData.GeneticSaveData <T> save = null;
     if (Encript)
     {
         save = Utils.FileReadWrite.ReadEncryptedFromBinaryFile <SaveData.GeneticSaveData <T> >(filePath);
     }
     else
     {
         save = Utils.FileReadWrite.ReadFromBinaryFile <SaveData.GeneticSaveData <T> >(filePath);
     }
     Generation = save.Generation;
     for (int i = 0; i < save.PopulationGenes.Count; i++)
     {
         if (i >= Population.Count)
         {
             Population.Add(new DNA <T>(dnaSize, random, getRandomGene, fitnessFunction, false));
         }
         Array.Copy(save.PopulationGenes[i], Population[i].Genes, dnaSize);
     }
     return(true);
 }
Пример #14
0
        /// <summary>
        /// Selecting howMany individuals from from to to
        /// </summary>
        /// <param name="howMany">number of individuals to select</param>
        /// <param name="from">old population</param>
        /// <param name="to">new population</param>
        public void Select(int howMany, Population from, Population to)
        {
            double fitnessSum = 0.0;

            for (int i = 0; i < from.GetPopulationSize(); i++)
            {
                fitnessSum += from.Get(i).GetFitnessValue();
            }

            double[] fitnesses = new double[from.GetPopulationSize()];

            for (int i = 0; i < fitnesses.Length; i++)
            {
                fitnesses[i] = from.Get(i).GetFitnessValue() / fitnessSum;
            }

            for (int i = 0; i < howMany; i++)
            {
                double ball = rng.NextDouble();
                double sum  = 0;

                for (int j = 0; j < fitnesses.Length; j++)
                {
                    sum += fitnesses[j];
                    if (sum > ball)
                    {
                        to.Add((Individual)from.Get(j).Clone());
                        break;
                    }
                }
            }
        }
Пример #15
0
        public ViewModel()
        {
            this.Population = new ObservableCollection <Model>();
            ChartThemes     = Enum.GetValues(typeof(Syncfusion.SfSkinManager.VisualStyles)).OfType <object>().ToList();
            ChartThemes.RemoveAt(0);
            DateTime date = new DateTime(2006, 1, 1);

            Population.Add(new Model {
                Year = date.AddYears(1), China = 1307.56, India = 1101.32
            });
            Population.Add(new Model {
                Year = date.AddYears(2), China = 1314.48, India = 1117.73
            });
            Population.Add(new Model {
                Year = date.AddYears(3), China = 1321.29, India = 1134.02
            });
            Population.Add(new Model {
                Year = date.AddYears(4), China = 1328.2, India = 1150.2
            });
            Population.Add(new Model {
                Year = date.AddYears(5), China = 1334.5, India = 1166.23
            });
            Population.Add(new Model {
                Year = date.AddYears(6), China = 1340.91, India = 1186
            });
            Population.Add(new Model {
                Year = date.AddYears(7), China = 1347.35, India = 1210.57
            });
            Population.Add(new Model {
                Year = date.AddYears(8), China = 1353.04, India = 1213.37
            });
        }
Пример #16
0
        public void TestGetProbabilitySelectorWithMinimizeMode()
        {
            var pMocks = new List <Mock <IPhenotype> >();

            pMocks.Add(CreatePhenotypeMock(1));
            pMocks.Add(CreatePhenotypeMock(2));
            pMocks.Add(CreatePhenotypeMock(3));
            pMocks.Add(CreatePhenotypeMock(5));

            var expected = new List <double>()
            {
                5, 4, 3, 1
            };

            population = new Population(4);
            foreach (var mock in pMocks)
            {
                population.Add(mock.Object);
            }

            var probSelector = population.GetProbabilitySelector(EAMode.MinimizeFitness);

            for (int i = 0; i < pMocks.Count; i++)
            {
                probSelector(pMocks[i].Object).Should().Be(expected[i]);
            }
        }
Пример #17
0
        /// <summary>
        /// Selecting howMany individuals from from to to
        /// </summary>
        /// <param name="howMany">number of individuals to select</param>
        /// <param name="from">old population</param>
        /// <param name="to">new population</param>
        public void Select(int howMany, Population from, Population to)
        {
            for (int i = 0; i < howMany; i++)
            {
                List <int> players = new List <int>();

                for (int j = 0; j < competitors; j++)
                {
                    players.Add(rng.NextInt(from.GetPopulationSize()));
                }

                while (players.Count > 1)
                {
                    if (from.Get(players[0]).GetFitnessValue() > from.Get(players[1]).GetFitnessValue() &&
                        rng.NextDouble() > weakerProb)
                    {
                        players.Remove(players[1]);
                    }
                    else
                    {
                        players.Remove(players[0]);
                    }
                }

                to.Add((Individual)from.Get(players[0]).Clone());
            }
        }
Пример #18
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);
        }
Пример #19
0
    // init demographics
    void initProfession(int professionID, int Ammount)
    {
        Stopwatch stopwatch = new Stopwatch();

        stopwatch.Start();

        // Type type = getProfession(professionID);
        Profession prof = (Profession)professionID;

        for (int j = 0; j < Ammount; j++)
        {
            // try {
            //     Person temp = (Person)Activator.CreateInstance(type);
            //     Population.Add(temp);
            //     Demographics[professionID].Add(temp);
            // } catch (Exception e) {
            //     Console.WriteLine("Error: Could not initialize Person from type");
            //     Console.WriteLine(e);
            // }
            Person temp = prof.ToPerson();
            Population.Add(temp);
            Demographics[professionID].Add(temp);
        }
        // test
        Console.WriteLine(prof.ToString() + "\t" + stopwatch.Elapsed.TotalMilliseconds.ToString());
    }
Пример #20
0
 private static void InitialisePopulation()
 {
     for (var i = 0; i < PopulationSize; i++)
     {
         Population.Add(new Chromosome(Random));
     }
 }
Пример #21
0
        /// <summary>
        /// Operator operate method
        /// </summary>
        /// <param name="parents">parents</param>
        /// <param name="offspring">offspring</param>
        public void Operate(Population parents, Population offspring)
        {
            int size = parents.GetPopulationSize();

            for (int i = 0; i < size; i++)
            {
                Individual p1 = parents.Get(i);
                Individual o1 = (Individual)p1.Clone();

                if (rng.NextDouble() < mutationProbability)
                {
                    // any nondetoured edge might get activated
                    List <Edge> nondetouredEdges = p1.GetUndetoured();
                    if (nondetouredEdges.Count > 0)
                    {
                        foreach (var edge in Program.graph.GetEdges())
                        {
                            if (rng.NextDouble() < bitFlipProbability &&
                                nondetouredEdges.Contains(edge))
                            {
                                o1.SetActivityOnEdge(edge.ID, 1);
                                o1.changed = true;
                            }
                        }
                    }
                }
                offspring.Add(o1);
            }
        }
Пример #22
0
        /// <summary>
        /// Initializes the populations
        /// </summary>
        /// <param name="initialPopulation">Size of the initial population</param>
        private void Initialize(int initialPopulation)
        {
            for (var i = 0; i < initialPopulation; i++)
            {
                var enumeration = Enumerable.Range(0, Configuration.People.Count).Shuffle(Random).ToList();
                var arrangement = new Arrangement(Configuration.NumberOfTables, Configuration.PeoplePerTable);

                foreach (var index in enumeration)
                {
                    while (true)
                    {
                        var nextTable = Random.Next(0, Configuration.NumberOfTables);
                        var nextSeat  = Random.Next(0, Configuration.PeoplePerTable);

                        if (arrangement.Tables[nextTable].People[nextSeat] == null)
                        {
                            arrangement.Tables[nextTable].People[nextSeat] = Configuration.People[index];
                            break;
                        }
                    }
                }

                arrangement.Score = CalculateFitness(arrangement);
                Population.Add(arrangement);
            }
        }
Пример #23
0
    void RespawnBankruptPeople()
    {
        // divide number of bankrupt people in profAmmount ammount of integer parts
        int [] afterDiv = Helper.IntegerDivision(DeadPeople.Count, profAmmount);

        for (int i = 0; i < DeadPeople.Count; i++)
        {
            // delete person references
            Person person = DeadPeople[i];
            Population.Remove(person);
            Demographics[(int)person.Role].Remove(person);
            // lostCash += person.Cash;
            currentMoneySupply -= person.Cash;
        }
        for (int prof = 0; prof < afterDiv.Length; prof++)
        {
            for (int i = 0; i < afterDiv[prof]; i++)
            {
                // check money supply
                decimal cash = 0;
                if (MoneySupply - currentMoneySupply > 10)
                {
                    currentMoneySupply += 10;
                    cash = 10;
                }
                // initialize new person
                // Person temp = (Person)Activator.CreateInstance(type);
                Person temp = ((Profession)prof).ToPerson();
                temp.Transaction(cash, 0, 0);
                // create references
                Demographics[prof].Add(temp);
                Population.Add(temp);
            }
        }
    }
Пример #24
0
 public void SelectAdults(Population offspring, Population population, int n, EAMode eamode)
 {
     population.Clear();
     for (int i = 0; i < n; i++)
     {
         population.Add(offspring[i]);
     }
 }
 private void ConvertBoidPopulationToViewModels(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
 {
     Population.Clear();
     foreach (Boid boid in world.Population)
     {
         Population.Add(new BoidViewModel(boid));
     }
 }
Пример #26
0
 private void HandleChange(object sender, NotifyCollectionChangedEventArgs e)
 {
     foreach (var item in e.NewItems)
     {
         var boid   = (Boid)item;
         var boidVM = new BoidViewModel(boid);
         Population.Add(boidVM);
     }
 }
 private void InitializePopulation()
 {
     for (var i = 0; i < PopulationSize; i++)
     {
         var chromosome = new Chromosome(ChromosomeSize);
         chromosome.Fitness = FitnessFunction.CalculateFitness(chromosome);
         Population.Add(chromosome);
     }
 }
 private void InitializePopulation()
 {
     for (int i = 0; i < PopulationSize; i++)
     {
         var chromosome = new Chromosome(BusStops, Students);
         chromosome.Fitness = FitnessFunction.CalculateFitness(chromosome);
         Population.Add(chromosome);
     }
 }
Пример #29
0
        public void LoadData(string filePath)
        {
            SaveData save = FileReadWrite.ReadFromJsonFile <SaveData>(filePath);

            for (int i = 0; i < loadExternalGenes; i++)
            {
                Population.Add(save.SavedMember[i]);
            }
        }
Пример #30
0
        private void generateNeuroPopulation_()
        {
            var networkState = NeuralNetwork.GetNetworkState();

            for (var i = 0; i < TestPopulationCount; i++)
            {
                Population.Add(generateNeuroChromosomeByTemplate(networkState));
            }
        }
        public bool testCrossoverPopulation()
        {
            Population parents = new Population();

            Chromosome[] chr_tab = { new Chromosome(new bool[] {false, false, false}), new Chromosome(new bool[] { true, true, true })};
            Individual[] ind_tab = new Individual[4];

            for (int i = 0; i < 4; i++)
            {
                ind_tab[i] = new Individual(chr_tab[i % 2]);
                parents.Add(ind_tab[i]);
            }

            int[] permutation = new int[] { 0, 2, 1, 3};
            int random1 = 2;
            int random2 = 0;

            Population orphans = this.crossoverHelper(parents, random1, random2, permutation);
            for (int i = 0; i < 4; i++)
            {
                if (i < 2)
                {
                    for (int j = 0; j < orphans.getIndividual(0).chromosome.Count; j++)
                    {
                        if (orphans.getIndividual(i).chromosome[j] != false) return false;
                    }
                }
                else
                {
                    for (int j = 0; j < orphans.getIndividual(0).chromosome.Count; j++)
                    {
                        if (orphans.getIndividual(i).chromosome[j] != true) return false;
                    }
                }
            }
            return true;
        }
        /// <summary>
        /// Solve the next iteration of the algorithm.
        /// </summary>
        public void SolveStep()
        {
            // checkPopDupes();
            if (this.properties.Objectives.Length < 1)
            {
                throw new Exception("You cannot optimise with 0 objectives.");
            }

            this.iteration = this.Iteration + 1;

            Console.WriteLine("Solving step {0}...", this.Iteration);

            this.progress = 0;

            var sw = Stopwatch.StartNew();

            // var r = new Population(population[0].Union(population[1]));

            /*
            foreach (var c in r)
            {
                double totalDistance = 0.0;
                foreach (var c2 in r)
                {
                    /*
                    totalDistance += Math.Max(Math.Max(Math.Abs(c.Fitness.PercentBuses - c2.Fitness.PercentBuses) ,
                                     Math.Abs(c.Fitness.PercentTrains - c2.Fitness.PercentTrains)) ,
                                     Math.Abs(c.Fitness.PercentTrams - c2.Fitness.PercentTrams));

                    totalDistance += Math.Sqrt(Math.Pow(c.Fitness.PercentBuses - c2.Fitness.PercentBuses,2.0)+
                                   Math.Pow(c.Fitness.PercentTrains - c2.Fitness.PercentTrains,2.0) +
                                    Math.Pow(c.Fitness.PercentTrams - c2.Fitness.PercentTrams,2.0));
                }
                c.Fitness.DiversityMetric = totalDistance;
            }

            double jtMaxTime = r.Max(c => c.Fitness.TotalJourneyTime).TotalHours;
            double jtMinTime = r.Min(c => c.Fitness.TotalJourneyTime).TotalHours;
            double ttMaxTime = r.Max(c => c.Fitness.TotalDistance);
            double ttMinTime = r.Min(c => c.Fitness.TotalDistance);
            double minDM = r.Min(c => c.Fitness.DiversityMetric);
            double maxDM = r.Max(c => c.Fitness.DiversityMetric);
            int maxChanges = r.Max(c => c.Fitness.Changes);
            int minChanges = r.Min(c => c.Fitness.Changes);

            foreach (var c in r)
            {
                c.Fitness.NormalisedJourneyTime = (c.Fitness.TotalJourneyTime.TotalHours-jtMinTime) / (jtMaxTime - jtMinTime);
                c.Fitness.NormalisedChanges = (double)(c.Fitness.Changes-minChanges) / (maxChanges - minChanges);
                c.Fitness.NormalisedTravelTime = (c.Fitness.TotalDistance-ttMinTime) / (ttMaxTime - ttMinTime);
                c.Fitness.DiversityMetric = (c.Fitness.DiversityMetric-minDM)/(maxDM - minDM);

                if (double.IsInfinity(c.Fitness.NormalisedChanges))
                {
                    c.Fitness.NormalisedChanges = 0;
                }
                if ((double.IsInfinity(c.Fitness.NormalisedJourneyTime)))
                {
                    c.Fitness.NormalisedJourneyTime = 0;
                }
                if ((double.IsInfinity(c.Fitness.NormalisedTravelTime)))
                {
                    c.Fitness.NormalisedTravelTime = 0;
                }

                   if ((double.IsInfinity(c.Fitness.DiversityMetric)))
                {
                    c.Fitness.DiversityMetric = 0;
                }

                Console.WriteLine("{0}, {1},{2},{3}", c.Fitness.NormalisedJourneyTime, c.Fitness.NormalisedChanges, c.Fitness.PercentBuses, c.Fitness.PercentTrains);
                c.N = 0;
                c.Rank = 0;
                //c.Distance = 0;
            }

            this.nonDominatedSort(r);

            var ranks = r.GroupBy(g => g.Rank);
            foreach (var rank in ranks)
            {
                foreach (var c1 in rank)
                {
                    foreach (var c2 in rank)
                    {
                        Assert.That(!this.Dominates(c1, c2), "Members of a front should be non dominate to each other.");

                    }
                }

            }
            */
            this.population[1] = new Population();

            for (int i = 0; i < this.Properties.PopulationSize / 2; i++)
            {
                var first = this.TournamentSelect();
                var second = this.TournamentSelect();

                Assert.That(first.DepartureTime != default(DateTime) && second.DepartureTime != default(DateTime));

                bool doCrossover = this.random.NextDouble() <= this.Properties.CrossoverRate;
                bool doMutation = this.random.NextDouble() <= this.Properties.MutationRate;
                Critter[] children = doCrossover
                                         ? this.Properties.Breeder.Crossover(first, second)
                                         : new[] { first, second };

                if (doMutation)
                {
                    children[0] = this.Properties.Mutator.Mutate(children[0]);
                    children[1] = this.Properties.Mutator.Mutate(children[1]);
                }

                Assert.That(
                    children[0].DepartureTime != default(DateTime) && children[1].DepartureTime != default(DateTime));

                if (doCrossover || doMutation)
                {
                    children[0].Fitness = this.Properties.FitnessFunction.GetFitness(
                        children[0].Route, children[0].DepartureTime);
                    children[1].Fitness = this.Properties.FitnessFunction.GetFitness(
                        children[1].Route, children[1].DepartureTime);
                }

                // var ff = (AlFitnessFunction)this.properties.FitnessFunction;
                Assert.That(
                    children[0].DepartureTime != default(DateTime) && children[1].DepartureTime != default(DateTime));

                this.population[1].AddRange(children);

                this.progress++;
            }

            /*

            var q = new List<Critter>(this.Properties.PopulationSize);
            foreach (var c1 in f)
            {
                c1.Clear();
            }
            f.Clear();

            for (int i = 0; i < this.Properties.PopulationSize/2; i ++)
            {
                var first = TournamentSelect();
                var second = TournamentSelect();

                Assert.That(first.departureTime != default(DateTime) && second.departureTime != default(DateTime));

                bool doCrossover = this.random.NextDouble() <= this.Properties.CrossoverRate;
                bool doMutation = this.random.NextDouble() <= this.Properties.MutationRate;
                Critter[] children = doCrossover
                                         ? this.Properties.Breeder.Crossover(first, second)
                                         : new[] { first, second };

                if (doMutation)
                {
                    children[0] = this.Properties.Mutator.Mutate(children[0]);
                    children[1] = this.Properties.Mutator.Mutate(children[1]);
                }

                Assert.That(children[0].departureTime != default(DateTime) && children[1].departureTime != default(DateTime));

                if (doCrossover || doMutation)
                {
                    children[0].Fitness = this.Properties.FitnessFunction.GetFitness(children[0].Route, children[0].departureTime);
                    children[1].Fitness = this.Properties.FitnessFunction.GetFitness(children[1].Route, children[1].departureTime);
                }
                //var ff = (AlFitnessFunction)this.properties.FitnessFunction;

                Assert.That(children[0].departureTime != default(DateTime) && children[1].departureTime != default(DateTime));

                q.AddRange(children);

                progress++;
            }

            var r = this.population.Select(p => (Critter)p.Clone()).ToList();

            checkPopDupes();

            //r.AddRange(this.population);
            r.AddRange(q);

            double maxTime = r.Max(c => c.Fitness.TotalJourneyTime).TotalHours;
            double minTime = r.Min(c => c.Fitness.TotalJourneyTime).TotalHours;
            int maxChanges = r.Max(c => c.Fitness.Changes);
            int minChanges = r.Min(c => c.Fitness.Changes);

            foreach (var c in r)
            {
                c.Fitness.NormalisedJourneyTime = c.Fitness.TotalJourneyTime.TotalHours / (maxTime - minTime);
                c.Fitness.NormalisedChanges = (double) c.Fitness.Changes / (maxChanges - minChanges);
                Console.WriteLine("{0}, {1},{2},{3}",c.Fitness.NormalisedJourneyTime,c.Fitness.NormalisedChanges,c.Fitness.PercentBuses,c.Fitness.PercentTrains);
                c.N = 0;
                c.Rank = 0;
                c.Distance = 0;
            }

            //this.crowdingDistanceAssignment(r);

            this.nonDominatedSort(r);

            foreach (var front in Fronts)
            {
                foreach (var c1 in front)
                {
                    foreach (var c2 in front)
                    {
                        Assert.That(!this.Dominates(c1,c2), "Members of a front should be non dominate to each other.");

                    }
                }
            }

            checkPopDupes();

            this.population.Clear();
            int j = 0;

            while (this.population.Count + this.Fronts[j].Count <= this.Properties.PopulationSize)
            {
                var front = this.Fronts[j];
                this.crowdingDistanceAssignment(front);
                this.population.AddRange(front);

                j++;
            }

            for (int i = 0; i < this.Fronts.Count; i++)
            {
                var front = this.Fronts[i];
                foreach (var critter in front)
                {
                    Assert.That(critter.Rank == i + 1);

                }
            }
            /*
            for (int i = 0; i < this.Fronts.Count; i++)
            {
                var front = this.Fronts[i];
                foreach (var critter in front)
                {
                    critter.Rank = i + 1;
                }
            }

            var ranks = this.population.GroupBy(g => g.Rank);
            foreach (var rank in ranks)
            {
                foreach (var c1 in rank)
                {
                    foreach (var c2 in rank)
                    {
                        Assert.That(!this.Dominates(c1, c2), "Members of a front should be non dominate to each other.");

                    }
                }

            }

            checkPopDupes();

            this.Fronts[j].Sort(CompareCritters);
            /*
            this.Fronts[j].Sort((c1, c2) =>
                {
                    if (c1.Rank < c2.Rank || (c1.Rank == c2.Rank && c1.Distance > c2.Distance))
                    {
                        return 1;
                    }
                    return -1;
                });

            this.population.AddRange(this.Fronts[j].GetRange(0, this.Properties.PopulationSize-this.population.Count));

            checkPopDupes();

               /*
            foreach (var eliteCritter in eliteCritters)
            {
                Tools.ToLinkedNodes(eliteCritter.Route.GetNodes(true));
            }

            /*
            this.nonDominatedSort(this.population);

            var ranks = this.population.GroupBy(g => g.Rank);
            foreach (var rank in ranks)
            {
                foreach (var c1 in rank)
                {
                    foreach (var c2 in rank)
                    {
                        Assert.That(!this.Dominates(c1, c2), "Members of a front should be non dominate to each other.");

                    }
                }

            }

            sw.Stop();

            this.result.Totaltime = sw.Elapsed;

            ranks = this.population.GroupBy(g => g.Rank);
            foreach (var rank in ranks)
            {
                foreach (var c1 in rank)
                {
                    foreach (var c2 in rank)
                    {
                        Assert.That(!this.Dominates(c1, c2), "Members of a front should be non dominate to each other.");

                    }
                }

            }
            */
            var distinct = new Population();

            foreach (var c in this.population[0])
            {
                bool same = false;
                foreach (var fitnessParameter in this.properties.Objectives)
                {
                    if (
                        distinct.Any(
                            c2 => Math.Abs(c2.Fitness[fitnessParameter] - c.Fitness[fitnessParameter]) < Epsilon))
                    {
                        same = true;
                    }
                }

                if (!same)
                {
                    distinct.Add(c);
                }
            }

            this.result.Cardinality = distinct.Count;

            /*
             ranks = distinct.GroupBy(g => g.Rank);
            foreach (var rank in ranks)
            {
                foreach (var c1 in rank)
                {
                    foreach (var c2 in rank)
                    {
                        Assert.That(!this.Dominates(c1, c2), "Members of a front should be non dominate to each other.");

                    }
                }

            }
            */
            this.population[0] = this.population[1];
            this.result.Population = (Population)this.population[0].Clone();

            // foreach (var critter in this.Population)
            // {
            // this.result.AverageFitness += critter.Fitness;
            // }
            // this.result.AverageFitness /= population.Count;
            // var sorted = this.Population.OrderBy(z => z.Fitness.TotalJourneyTime);
            // this.result.MinimumFitness = sorted.First().Fitness;
            // this.result.BestPath = sorted.First().Route;

            // Tools.SavePopulation(this.population.GetRange(0, 25), ++this.generation, this.properties);

            // this.BestNode = Tools.ToLinkedNodes(this.Population[0].Route);

            // Console.WriteLine("Average fitness: {0}", this.result.MinimumFitness);
            // return false;
        }
        /// <summary>
        /// Returns a solution found using best-placement.
        /// </summary>
        /// <returns></returns>
        protected override IRoute DoSolve(OsmSharp.Tools.Math.TSP.Problems.IProblem problem)
        {
            // create the settings.
            SolverSettings settings = new SolverSettings(
                -1,
                -1,
                1000000000,
                -1,
                -1,
                -1);

            Solver<List<int>, GeneticProblem, Fitness> solver =
                new Solver<List<int>, GeneticProblem, Fitness>(
                new GeneticProblem(problem),
                settings,
                null,
                null,
                null,
                _generation_operation,
                new FitnessCalculator(),
                true, false);

            Population<List<int>, GeneticProblem, Fitness> population =
                new Population<List<int>, GeneticProblem, Fitness>(true);
            while (population.Count < _population_size)
            {
                // generate new.
                Individual<List<int>, GeneticProblem, Fitness> new_individual =
                    _generation_operation.Generate(solver);

                // add to population.
                population.Add(new_individual);
            }

            // select each individual once.
            Population<List<int>, GeneticProblem, Fitness> new_population =
                new Population<List<int>, GeneticProblem, Fitness>(true);
            Individual<List<int>, GeneticProblem, Fitness> best = null;
            int stagnation = 0;
            while (stagnation < _stagnation)
            {
                while (new_population.Count < _population_size)
                {
                    // select an individual and the next one.
                    int idx = OsmSharp.Tools.Math.Random.StaticRandomGenerator.Get().Generate(population.Count);
                    Individual<List<int>, GeneticProblem, Fitness> individual1 = population[idx];
                    Individual<List<int>, GeneticProblem, Fitness> individual2 = null;
                    if (idx == population.Count - 1)
                    {
                        individual2 = population[0];
                    }
                    else
                    {
                        individual2 = population[idx + 1];
                    }
                    population.RemoveAt(idx);

                    Individual<List<int>, GeneticProblem, Fitness> new_individual = _cross_over_operation.CrossOver(solver,
                        individual1, individual2);

                    new_individual.CalculateFitness(solver.Problem, solver.FitnessCalculator);
                    if (new_individual.Fitness.CompareTo(
                        individual1.Fitness) < 0)
                    {
                        new_population.Add(new_individual);
                    }
                    else
                    {
                        new_population.Add(individual1);
                    }
                }

                population = new_population;
                population.Sort(solver, solver.FitnessCalculator);

                new_population = new Population<List<int>, GeneticProblem, Fitness>(true);

                if (best == null ||
                    best.Fitness.CompareTo(population[0].Fitness) > 0)
                {
                    stagnation = 0;
                    best = population[0];
                }
                else
                {
                    stagnation++;
                }

                //// report progress.
                //OsmSharp.Tools.Output.OutputStreamHost.ReportProgress(stagnation,_stagnation,
                //    "OsmSharp.Tools.Math.TSP.EdgeAssemblyGenetic.EdgeAssemblyCrossOverSolver",
                //    "Solving using EAX...");
            }

            List<int> result = new List<int>(best.Genomes);
            result.Insert(0, 0);
            //return new SimpleAsymmetricRoute(result, true);
            return DynamicAsymmetricRoute.CreateFrom(result);
        }