コード例 #1
0
ファイル: GeneticAlgorithm.cs プロジェクト: harkin-s/FYP_GA
        // Use the temp population to get the next gerneration using crossover and partner selection
        public static List <Organism> generateNextGen(List <Organism> gen)
        {
            List <int>      gene        = new List <int>();
            List <int>      crossPoitns = new List <int>();
            List <Organism> nextGen     = new List <Organism>();

            if (elitism)
            {
                Organism elite = new Organism(GENES);
                foreach (Organism org in gen)
                {
                    if (org.fitness + org.numberOfdecptives > elite.fitness + elite.numberOfdecptives)
                    {
                        elite = org;
                    }
                }
                nextGen.Add(elite);
            }

            //Cross over first


            for (var pop = nextGen.Count; pop < POPULATION; pop++)
            {
                // Get best partner for organism
                var parentB = getPartner(gen, pop);
                nextGen.Add(new Organism(GENES));

                if (!weightedCrossover)
                {
                    while (crossPoitns.Count < numOfCrossPoints)
                    {
                        var point = GetRandomNumber(0, GENES);
                        if (!crossPoitns.Contains(point))
                        {
                            crossPoitns.Add(point);
                        }
                    }
                }
                else if (weightedCrossover && numOfCrossPoints == 1)
                {
                    float fitnessA = gen[pop].fitness + (gen[pop].numberOfdecptives * 10);
                    float fitnessB = gen[parentB].fitness + (gen[parentB].numberOfdecptives * 10);
                    float com      = fitnessA + fitnessB;
                    float cross    = (fitnessA / com);
                    cross = cross * GENES;
                    crossPoitns.Add((int)cross);
                }


                crossPoitns.Add(0);
                crossPoitns.Sort();

                // This is the cross over algorithm uses random cross point.
                // Test use of different number of cross points
                // Maybe add weighted cross over or min differenc between cross points
                // Add ability for multiple cross over.
                // Should cross points change for each cross over or stay the same for each generation


                var endPoint = 0;
                var parent   = 0;
                if (!uniformCrossover && !halfUniformCrossover)
                {
                    for (var b = 0; b < crossPoitns.Count; b++)
                    {
                        endPoint = b + 1 < crossPoitns.Count ? crossPoitns[b + 1] : GENES;
                        if (parent == 0)
                        {
                            gene = gen[pop].spliceGenes(crossPoitns[b], endPoint);
                            nextGen[pop].addGenes(gene, crossPoitns[b], endPoint);
                            parent = 1;
                        }
                        else if (parent == 1)
                        {
                            gene = gen[parentB].spliceGenes(crossPoitns[b], endPoint);
                            nextGen[pop].addGenes(gene, crossPoitns[b], endPoint);
                            parent = 0;
                        }
                    }
                    nextGen[pop] = mutate(nextGen[pop]);
                    crossPoitns.Clear();
                }
                else if (uniformCrossover)
                {
                    var end   = 0;
                    var start = 0;
                    for (var g = 0; g < ALLELES; g++)
                    {
                        var rand = GetRandomNumber(1, 10);
                        if (rand < 5)
                        {
                            end += alleleSizes[g];
                            var genes = gen[parent].spliceGenes(start, end);
                            nextGen[pop].addGenes(genes, start, end);
                        }
                        else
                        {
                            end += alleleSizes[g];
                            var genes = gen[parentB].spliceGenes(start, end);
                            nextGen[pop].addGenes(genes, start, end);
                        }
                        start = end;
                    }
                    nextGen[pop].fitness           = 0;
                    nextGen[pop].numberOfdecptives = 0;
                    nextGen[pop] = mutate(nextGen[pop]);
                    crossPoitns.Clear();
                }
                else if (halfUniformCrossover)
                {
                    var toSwap = getHammingDistance(gen[pop], gen[parentB]) / 2;
                    nextGen[pop].genes = gen[pop].genes;

                    var        swaped  = 0;
                    List <int> changed = new List <int>();
                    while (swaped != toSwap)
                    {
                        var rand = GetRandomNumber(0, GENES - 1);

                        if (!changed.Contains(rand))
                        {
                            changed.Add(rand);
                            if (gen[pop].genes[rand] != gen[parentB].genes[rand])
                            {
                                nextGen[pop].genes.SetValue(gen[parentB].genes[rand], rand);
                                swaped++;
                            }
                        }
                    }
                    nextGen[pop].fitness           = 0;
                    nextGen[pop].numberOfdecptives = 0;
                    nextGen[pop] = mutate(nextGen[pop]);
                    crossPoitns.Clear();
                }
            }


            if (!useEpistasis)
            {
                checkForIdeal(nextGen);
            }

            return(nextGen);
        }