Example #1
0
        public void Execute()
        {
            for (int generation = 0; generation < totalGeneration; generation++)
            {
                double[] fObj                    = new double[chromosomes.Length];
                double[] fitnesses               = new double[chromosomes.Length];
                double[] probabilities           = new double[chromosomes.Length];
                double[] cumulativeProbabilities = new double[chromosomes.Length];
                double[] randoms                 = new double[chromosomes.Length];
                double   totalFitness            = 0;

                Print($"Initialize Generation #{generation+1}", tag: "h2");
                PrintChromosomes(chromosomes);
                Print();

                // Evaluation
                Print("Evaluation", tag: "h3");
                for (int i = 0; i < chromosomes.Length; i++)
                {
                    //Console.WriteLine($"Chromosome[{i+1}]: {chromosomes[i]}");
                    fObj[i]      = ObjectiveFunction.Invoke(chromosomes[i]);
                    fitnesses[i] = 1 / (1 + fObj[i]);
                    Print($"F_obj[{i + 1}] = {fObj[i]}");
                    totalFitness += fitnesses[i];
                }

                //Fitness
                for (int i = 0; i < fitnesses.Length; i++)
                {
                    Print($"Fitness[{i + 1}] = {fitnesses[i]}");
                }
                Print($"Total fitness = {totalFitness}");
                Print();

                Random random = new Random();

                Print("Probabilities");
                for (int i = 0; i < chromosomes.Length; i++)
                {
                    probabilities[i] = fitnesses[i] / totalFitness;
                    Print($"P[{i + 1}]: {probabilities[i]}");
                    cumulativeProbabilities[i] = probabilities.Sum();
                    randoms[i] = random.NextDouble();
                    //Console.WriteLine($"C[{i + 1}]{cumulativeProbabilities[i]}");
                }
                Print();

                Print("Cumulative probabilities");
                for (int i = 0; i < chromosomes.Length; i++)
                {
                    Print($"C[{i + 1}]: {cumulativeProbabilities[i]}");
                }
                Print();

                Print("Roulette-wheel", tag: "h3");
                for (int i = 0; i < chromosomes.Length; i++)
                {
                    Print($"R[{i + 1}]: {randoms[i]}");
                }
                Print();

                Chromosome <T>[] newChromosomes = new Chromosome <T> [chromosomes.Length];
                for (int i = 0; i < randoms.Length; i++)
                {
                    for (int j = 0; j < cumulativeProbabilities.Length; j++)
                    {
                        if (randoms[i] > cumulativeProbabilities[j])
                        {
                            continue;
                        }
                        newChromosomes[i]       = new Chromosome <T>();
                        newChromosomes[i].Genes = new T[chromosomes[j].Genes.Length];
                        chromosomes[j].Genes.CopyTo(newChromosomes[i].Genes, 0);
                        break;
                    }
                }

                Print("New selected chromosomes:", tag: "h3");
                PrintChromosomes(newChromosomes);
                Print();

                // Crossover
                int[] selectedIndexes = SelectChromosomes(chromosomes.Length).ToArray();

                Print("Crossover", tag: "h3", centered: true);
                //Console.WriteLine($"Indexcount:{selectedIndexes.Length}");
                if (selectedIndexes.Length > 1)
                {
                    Dictionary <int, T[]> offsprings = new Dictionary <int, T[]>();
                    for (int i = 0; i < selectedIndexes.Length; i++)
                    {
                        int cut     = random.Next(1, newChromosomes[selectedIndexes[i]].Genes.Length);
                        int targeti = i + 1 >= selectedIndexes.Length ? 0 : i + 1;
                        Print($"Cut:{cut}", centered: true);
                        Print($"Chromosome[{selectedIndexes[i] + 1}]><Chromosome[{selectedIndexes[targeti] + 1}]", centered: true);

                        var gene       = newChromosomes[selectedIndexes[i]].Genes;
                        var targetgene = newChromosomes[selectedIndexes[targeti]].Genes;
                        Print($"[{string.Join(';', gene)}]><[{string.Join(';', targetgene)}]", centered: true);

                        T[] offspring = new T[gene.Length];
                        for (int j = 0; j < offspring.Length; j++)
                        {
                            offspring[j] = gene[j];
                            if (j >= cut)
                            {
                                offspring[j] = targetgene[j];
                            }
                        }
                        Print($"[{string.Join(';', offspring)}]", centered: true);
                        Print();
                        offsprings.Add(selectedIndexes[i], offspring);
                    }
                    Print();

                    foreach (var item in offsprings)
                    {
                        item.Value.CopyTo(newChromosomes[item.Key].Genes, 0);
                    }

                    Print("New Generation Chromosomes");
                    PrintChromosomes(newChromosomes);
                }
                else
                {
                    Print("No crossover");
                }
                Print();

                // Mutation
                Print("Mutation", tag: "h3");
                (int x, int y)[] selectedGenes = SelectGeneForMutation(newChromosomes.Length, newChromosomes[0].Genes.Length).ToArray();