示例#1
0
        public double GetObjective(Chromosome c)
        {
            double value;
            int cost;

            cost = 0;
            value = 0;
            for(int i=0;i<numberOfItems;i++)
            {
                if ( (BinaryGene)c.Genes[i] )
                {
                    cost += costs[i];
                    value += values[i];
                }
            }

            if ( cost > maxCost )
            {
                return maxCost-cost;    // always negative
            }
            else
            {
                return value;
            }
        }
示例#2
0
文件: Ackley.cs 项目: mykwillis/genX
        /// <summary>
        /// Calculates the objective based on Ackley's function.
        /// </summary>
        /// <param name="c"></param>
        /// <returns></returns>
        /// <remarks>
        /// Ackley's function is given by:
        /// 
        ///             F(x) = 20 + e
        ///                    - 20*exp(-0.2*sqrt((1/n)*Sum(i=1,n) {x_i^2}))
        ///                    - exp((1/n)*Sum(i=1,n){cos(2*pi*x_i)}) 

        /// </remarks>
        public static double AckleyMinimizationObjective(Chromosome c)
        {
            int n = c.Genes.Length;
            DoubleGene[] x = new DoubleGene[c.Genes.Length];
            Array.Copy(c.Genes, x,c.Genes.Length);  // performs type casting for each element
            double f;
            double objective;


            // Split the equation into three parts:
            // F(x) = 
            //  (a)    20 + e
            //  (b)    - 20*exp(-0.2*sqrt((1/n)*Sum(i=1,n) {x_i^2}))
            //  (c)    - exp((1/n)*Sum(i=1,n){cos(2*pi*x_i)}) 


            //
            // Calculate the (c) part.
            //
            double f_c = 0;
            for(int i=0;i<n;i++)
            {
                f_c += Math.Cos(2*Math.PI*x[i].Value);
            }
            f_c *= ( 1.0/n );
            f_c = -Math.Exp( f_c );

            //
            // Calculate the (b) part
            //
            double f_b = 0;
            for(int i=0;i<n;i++)
            {
                double sum;
                sum = (x[i].Value * x[i].Value)/n;                
                f_b += sum;
            }
            f_b = Math.Sqrt( f_b );
            f_b *= -0.2;
            f_b = Math.Exp( f_b );
            f_b *= -20.0;

            //
            // Calculate the (a) part
            //
            double f_a = 0;
            f_a = 20.0 + Math.E;


            //
            // Calculate the total as (a) + (b) + (c)
            //
            f = f_a + f_b + f_c;

            objective = Math.Abs(f);

            return objective;
        }
示例#3
0
 static double BinaryMaximizationObjective(Chromosome chromosome)
 {
     int objective = 0;
     foreach(BinaryGene g in chromosome.Genes)
     {
         if ( g.Value ) objective++;
     }
     return objective;
 }
示例#4
0
文件: Scaling.cs 项目: mykwillis/genX
 /// <summary>
 /// Scales a collection of chromosome's objective values and puts
 /// the result in the Fitness property.
 /// </summary>
 /// <param name="Chromosomes">
 /// An array of chromosomes.
 /// </param>
 public static void Scale(Chromosome[] Chromosomes)
 {
     // In proportional scaling, the fitness of each individual is
     // simply that individual's objective value.
     foreach(Chromosome c in Chromosomes)
     {
         c.Fitness = c.NormalizedObjective;
     }
 }
示例#5
0
 //
 // Objective function that rewards higher-valued integer Genes.  The
 // return value of this function is a value that is the arithmetic sum 
 // of all integers in the Chromosome.
 //
 public static double IntegerMaximizationObjective(Chromosome chromosome)
 {
     double objective = 0;
     foreach(IntegerGene g in chromosome.Genes)
     {
         objective += g.Value;
     }
     return objective;
 }
示例#6
0
        public double LinearDiophantineObjective(Chromosome c)
        {
            double r = 0;
            for(int i=0;i<Coefficients.Length;i++)
            {
                IntegerGene g = (IntegerGene) c.Genes[i];
                r += ((double)Coefficients[i] * (double)g.Value);
            }

            return System.Math.Abs((double)Result - r);
        }        
示例#7
0
 //
 /// Objective function that gives higher values for chromosomes
 /// with binary genes that alternate between 0 and 1.
 //
 static double BinaryAlternateObjective(Chromosome chromosome)
 {
     int objective = 0;
     bool matchValue = false;
     foreach(BinaryGene g in chromosome.Genes)
     {
         if ( g.Value == matchValue ) objective++;
         matchValue = !matchValue;
     }
     return objective;
 }
示例#8
0
 public object ChromosomeToObject(Chromosome c)
 {
     object o = Activator.CreateInstance(type);
     foreach(Gene g in c.Genes)
     {
         GeneDescriptor desc = g.Descriptor;
         FieldInfo fi = type.GetField(desc.Name);
         fi.SetValue(o,g.ObjectValue);
     }
     return o;
 }
示例#9
0
 public int GetValue(Chromosome c)
 {
     int val=0;
     for(int i=0;i<numberOfItems;i++)
     {
         if ( (BinaryGene)c.Genes[i] )
         {
             val += values[i];
         }
     }
     return val;
 }
示例#10
0
 public int GetCost(Chromosome c)
 {
     int cost=0;
     for(int i=0;i<numberOfItems;i++)
     {
         if ( (BinaryGene)c.Genes[i] )
         {
             cost += costs[i];
         }
     }
     return cost;
 }
示例#11
0
        /// <summary>
        /// Selects a single chromosome for reproduction based on roulette
        /// selection.
        /// </summary>
        /// <param name="chromosomes">The array of candidate chromosomes.</param>
        /// <param name="n">The number of chromosomes to select.</param>
        /// <returns>
        /// A Chromosome that should be used for reproduction.
        /// </returns>
        public static Chromosome[] Select(Chromosome[] chromosomes, int n)
        {
            // "stochastic sampling with replacement"
            Chromosome[] cs = new Chromosome[n];

            /*
                The individuals are mapped to contiguous segments of a line, such 
                that each individual's segment is equal in size to its fitness. 
                A random number is generated and the individual whose segment 
                spans the random number is selected. The process is repeated until 
                the desired number of individuals is obtained (called mating 
                population). This technique is analogous to a roulette wheel with 
                each slice proportional in size to the fitness. 
                */
            double TotalFitness = 0;
            foreach(Chromosome c in chromosomes)
            {
                TotalFitness += c.Fitness;
            }

            for(int i=0;i<n;i++)
            {
                double d = Utils.Rand.NextDouble() * TotalFitness;

                double CumulativeFitness = 0;
                int j;
                // OPTIMIZE: this should work from the end and go back, because the
                // low fitness individuals are at the beginning of the array.
                for(j=0;j<chromosomes.Length & d > CumulativeFitness;j++)
                {
                    CumulativeFitness += chromosomes[j].Fitness;
                }
                if (j!=0)
                {
                    cs[i] = chromosomes[j-1];
                }
                else 
                {
                    cs[i] = chromosomes[0];
                }
            }
            return cs;
        }
示例#12
0
        public double GetObjective(Chromosome c)
        {
            double distance = 0;
            int currentPosition = 0;
            int initialPosition = 0;
            for(int i=0;i<c.Genes.Length;i++)
            {
                IntegerGene ig = (IntegerGene) c.Genes[i];
                if ( i==0 )
                {
                    initialPosition = cities[ig.Label];
                    currentPosition = cities[ig.Label];
                }
                else
                {
                    distance += Math.Abs( cities[ig.Label] - currentPosition );
                    currentPosition = cities[ig.Label];
                }
            }
            IntegerGene lastGene = (IntegerGene) c.Genes[c.Genes.Length-1];
            distance += Math.Abs( cities[lastGene.Label] - initialPosition );

            return distance;
        }
示例#13
0
        public double GetObjective(Chromosome c)
        {
            double distance = 0;
            Point currentPosition = cities[0];
            Point initialPosition = cities[0];
            for(int i=0;i<c.Genes.Length;i++)
            {
                Gene g = c.Genes[i];
                if ( i==0 )
                {
                    initialPosition = cities[g.Label];
                    currentPosition = cities[g.Label];
                }
                else
                {
                    distance += cities[g.Label].Distance(currentPosition);
                    currentPosition = cities[g.Label];
                }
            }
            Gene lastGene = c.Genes[c.Genes.Length-1];
            distance += cities[lastGene.Label].Distance(initialPosition);

            return distance;
        }
示例#14
0
        /// <summary>
        /// Selects a number of individuals for reproduction.
        /// </summary>
        /// <param name="chromosomes"></param>
        /// <param name="nc"></param>
        /// <returns></returns>
        public static Chromosome[] Select(Chromosome[] chromosomes, int nc)
        {
            Chromosome[] mates = new Chromosome[nc];
            int n=0;

            double[] expectedSelectionCounts = new double[nc];
            double[] fractionalExpectedSelectionCounts = new double[nc];

            double totalFitness=0;
            foreach(Chromosome c in chromosomes)
            {
                totalFitness += c.Fitness;
            }
            for(int i=0;i<nc;i++)
            {
                Chromosome c = chromosomes[i];

                expectedSelectionCounts[i] = (c.Fitness / totalFitness) * chromosomes.Length;
                double sc = expectedSelectionCounts[i];
                while ( sc - 1.0 > 0 && n < nc)
                {
                    mates[n++] = c;
                    sc -= 1.0;
                }
                fractionalExpectedSelectionCounts[i] = sc;
            }

            // calculate total fractional expected count
            double totalFractionalExpectedSelectionCount=0;
            for(int i=0;i<nc;i++)
            {
                totalFractionalExpectedSelectionCount += fractionalExpectedSelectionCounts[i];
            }

            // do roulette selection based on fractional expected count

            int diff = nc - n;
            for(int i=n;i<nc;i++)
            {
                double d = Utils.Rand.NextDouble() * totalFractionalExpectedSelectionCount;

                double CumulativeCount = 0;
                int j;
                for(j=0;j<nc && d > CumulativeCount;j++)
                {
                    CumulativeCount += fractionalExpectedSelectionCounts[j];
                }
                if (j!=0)
                {
                    mates[i] = chromosomes[j-1];
                }
                else 
                {
                    mates[i] = chromosomes[0];
                }
            }

            // randomize the results, since Recombine will mate each adjacent
            // pair.
            Chromosome[] randomMates = new Chromosome[nc];
            for(int i=0;i<nc;i++)
            {
                do
                {
                    int r = Utils.Rand.Next(nc);
                    randomMates[i] = mates[ r ];
                    mates[r] = null;
                }
                while ( randomMates[i] == null );
            }            
            return randomMates;
        }
示例#15
0
文件: ga.cs 项目: mykwillis/genX
        // There's at least two major problems here.
        // First, there's the problem that the Parents array is coming back such
        // that highly fit individuals will be consecutive in the array; it's essentially
        // a sorted array (at least in the case of StachasticRemainderSelectionWtihoutReplacement).
        // The real problem is that we allow chromosomes to mate with themselves to breed a
        // new generation.  This is dumb, I think.  We allow the recombination probability
        // to be less than 1.0 to allow for some individuals to make it through unscatche,
        // so when we do recombine, we have to make sure the parents are different.

        // I Fixed the selector to randomize the order of chromosomes.  The issue of
        // mating one chromosome with another remains.

        Chromosome[] Recombine(Chromosome[] Parents)
        {
            Chromosome[] children;
            Chromosome[] newPopulation = new Chromosome[PopulationSize];

            for(int i=0;i<PopulationSize-1;i++)
            {
                if ( Utils.Rand.NextDouble() < RecombinationProbability )
                {
                    // HACK: each parent reproduces at least once, but its mate
                    // HACK: is chosen from the others in the selection pool.
                    //Chromosome parent2 = Parents[ Utils.Rand.Next(PopulationSize) ];
                    // Uncomment this line to get previous behavior:
                    Chromosome parent2 = Parents[i+1];
                    
                    children = Recombinator(Parents[i], parent2);
                    Chromosome[] parents = new Chromosome[] { Parents[i], parent2 };
                    children[0].Parents[0] = Parents[i];
                    children[0].Parents[1] = parent2;
                    children[1].Parents[0] = Parents[i];
                    children[1].Parents[1] = parent2;
                }
                else
                {
                    children = new Chromosome[] { (Chromosome)Parents[i].Clone(), (Chromosome)Parents[i+1].Clone() };
                    children[0].Parents[0] = Parents[i];
                    children[0].Parents[1] = null;
                    children[1].Parents[0] = Parents[i+1];
                    children[1].Parents[1] = null;
                }
                newPopulation[i] = children[0];
                newPopulation[i+1] = children[1];
            }
            return newPopulation;
        }
示例#16
0
        /// <summary>
        /// Selects a single chromosome for reproduction based on tournament
        /// selection.
        /// </summary>
        /// <param name="chromosomes">The array of candidate chromosomes.</param>
        /// <returns>
        /// A Chromosome that should be used for reproduction.
        /// </returns>
        public Chromosome Select(Chromosome[] chromosomes)
        {
            if ( TourSize > chromosomes.Length || TourSize < 1 )
            {
                throw new ArgumentOutOfRangeException(
                    "TourSize",
                    TourSize,
                    "TourSize must be between 1 and the population size."                    
                    );
            }

            Chromosome c;
            Chromosome highestChromosome=null;
            int highestFitness = 0;
            for(int i=0;i<TourSize;i++)
            {
                c = chromosomes[ genX.Utils.Rand.Next(TourSize) ];
                if ( c.Fitness > highestFitness )
                {
                    highestChromosome = c;
                }
            }

            return highestChromosome;
        }
示例#17
0
文件: Scaling.cs 项目: mykwillis/genX
        /// <summary>
        /// Truncates the Fitness value 
        /// </summary>
        /// <param name="chromosomes"></param>
        public void Truncate(Chromosome[] chromosomes)
        {
            //
            //
            // This code ripped from PopulationSummary for now.
            // >>>>
            //
            double totalObjective;            
            double meanObjective;
            double variance;
            double standardDeviation;

            totalObjective = 0;

            foreach( Chromosome c in chromosomes )
            {
                totalObjective += c.NormalizedObjective;
            }
            meanObjective = totalObjective / chromosomes.Length;


            //
            // Variance is the average squared deviation from the mean.
            // Standard Deviation is just the square root of this.
            //
            double sum = 0;
            foreach(Chromosome c in chromosomes)
            {
                double deviation;
                double squaredDeviation;

                deviation = c.NormalizedObjective - meanObjective;
                squaredDeviation = deviation * deviation;

                sum += squaredDeviation;
            }
            variance = sum / (chromosomes.Length-1);
            standardDeviation = Math.Sqrt( variance );

            //
            //
            // This code ripped from PopulationSummary for now.
            // <<<<
            //

            
            //
            // Fitness = NormalizedObjective - (meanObjective - c * standardDeviation)
            //
            foreach(Chromosome c in chromosomes)
            {
                c.NormalizedObjective = c.NormalizedObjective - (meanObjective - (C * standardDeviation));
                if ( c.NormalizedObjective  < 0 )
                {
                    c.NormalizedObjective = 0;
                }
            }
        }
示例#18
0
文件: Scaling.cs 项目: mykwillis/genX
 /// <summary>
 /// Scales a collection of chromosome's objective values and puts
 /// the result in the Fitness property.
 /// </summary>
 /// <param name="chromosomes">
 /// An array of chromosomes.
 /// </param>
 public void Scale(Chromosome[] chromosomes)
 {
     foreach(Chromosome c in chromosomes)
     {
         c.Fitness = Math.Pow( c.NormalizedObjective, power );
     }
 }
示例#19
0
文件: Scaling.cs 项目: mykwillis/genX
        /// <summary>
        /// Scales a collection of chromosome's objective values and puts
        /// the result in the Fitness property.
        /// </summary>
        /// <param name="Chromosomes">
        /// An array of chromosomes.
        /// </param>
        public void Scale(Chromosome[] Chromosomes)
        {
            //
            // We assume that the chromosomes have already been sorted
            // according to NormalizedObjective value.
            //

            //
            // Now, calculate each chromosome's fitness based on the 
            // formula...[This should be checked against Blickle & Thiel]
            //
            //  Fitness(Pos) = 2 - SP + 2·(SP - 1)·(Pos - 1) / (Nind - 1) 
            //
            for(int i=0;i<Chromosomes.Length;i++)
            {                
                Chromosomes[i].Fitness = (
                    (2 - SelectivePressure)         + 
                    ( (2 * (SelectivePressure - 1)) * (i) )
                    / (Chromosomes.Length - 1)
                    );
            }
        }
示例#20
0
文件: Scaling.cs 项目: mykwillis/genX
        /// <summary>
        /// Scales a collection of chromosome's objective values and puts
        /// the result in the Fitness property.
        /// </summary>
        /// <param name="chromosomes">
        /// An array of chromosomes.
        /// </param>
        public void Scale(Chromosome[] chromosomes)
        {
            //
            // First, we need to calculate the min, max, and average values for
            // the NormalizedObjectives.
            //
            double minObjective, maxObjective, totalObjective, avgObjective;
            minObjective = chromosomes[0].NormalizedObjective;
            maxObjective = chromosomes[0].NormalizedObjective;
            totalObjective = chromosomes[0].NormalizedObjective;
            for(int i=0;i<chromosomes.Length;i++)
            {
                totalObjective += chromosomes[i].NormalizedObjective;
                if ( chromosomes[i].NormalizedObjective < minObjective )
                {
                    minObjective = chromosomes[i].NormalizedObjective;
                }
                if ( chromosomes[i].NormalizedObjective > maxObjective )
                {
                    maxObjective = chromosomes[i].NormalizedObjective;
                }
            }
            avgObjective = totalObjective / chromosomes.Length;


            //
            // Use the calculated values to find the slope and y_intercept.
            //
            PreScale(minObjective, maxObjective, avgObjective);


            //
            // Apply the linear function to each of the chromosomes.
            //
            foreach(Chromosome c in chromosomes)
            {
                c.Fitness = (slope * c.NormalizedObjective) + y_intercept;
            }
        }
示例#21
0
文件: ga.cs 项目: mykwillis/genX
        void Mutate(Chromosome[] cs)
        {
            foreach(Chromosome c in cs)
            {
                //
                // Mutate a gene's value in this chromosome.
                //
                if ( Utils.Rand.NextDouble() < GeneMutationProbability )
                {
                    int mutationPoint = Utils.Rand.Next( c.Genes.Length );
                    Gene gene = c.Genes[mutationPoint];

                    //
                    // A globally installed valuemutator takes precedence over the
                    // default gene mutator.
                    //
                    if ( ValueMutator != null )
                    {
                        c.Genes[mutationPoint] = ValueMutator(gene);
                    }
                    else
                    {
                        // this is the Custom case
                        c.Genes[mutationPoint] = gene.Descriptor.Mutate(gene);
                    }

                    //
                    // Raise the Mutated event.
                    //
                    MutatedEventArgs e = new MutatedEventArgs();
                    e.Chromosome = c;
                    e.MutationPoint = mutationPoint;
                    e.OldGene = gene;
                    e.NewGene = c.Genes[mutationPoint];

                    OnMutated( e );
                }
#if NOTDEF
                if ( Utils.Rand.NextDouble() < OrderMutationProbability )
                {
                    if ( OrderMutator != null )
                    {
                        OrderMutator(c);
                    }
                }
#endif
            }
        }
示例#22
0
文件: ga.cs 项目: mykwillis/genX
        void Replace(Chromosome[] children)
        {
            Population nextPopulation = new Population( this, population.PopulationSize );
            for(int i=0;i<populationSize;i++)
            {
                //
                // Since the recombination record for a chromosome may contain a
                // pointer to chromosome's in the previous population, it has to be
                // cleared out.  This prevents us from getting an unbroken reference
                // chain between the current population's chromosomes all the way back
                // to the first population (which would prevent the garbage collector
                // from reclaiming any chromosome memory).
                // (There is probably some way we can configure how deep we want
                // to remember recombination records.  But that might be overkill
                // if we get everything serializing nicely.)
                //
                population.Chromosomes[i].Parents = null;
                nextPopulation.Chromosomes[i] = children[i];
                nextPopulation.Chromosomes[i].ID = nextChromosomeID++;
            }            
            

            NewPopulationEventArgs e = new NewPopulationEventArgs();
            e.OldPopulation = population;
            e.NewPopulation = nextPopulation;
            e.Generation    = generation;
            OnNewPopulation( e );

            population = nextPopulation;    // BUGBUG: should move this before the call out
        }
示例#23
0
        /*
         * mode - most frequently occuring score.         
         * median - midpoint of distribution, above which have of the scores fall, and below
         *   which the other half fall.
         */

        /// <summary>
        /// Creates a PopulationSummary from a Population.
        /// </summary>
        /// <param name="ga">The GA.</param>
        /// <param name="Population">The Population for which the 
        /// PopulationSummary will provide summary information.
        /// </param>
        public PopulationSummary( GA ga, Population Population )
        {
            double totalObjective;

            lowestObjective = System.Double.MaxValue;
            highestObjective = System.Double.MinValue;
            totalObjective = 0;

            foreach( Chromosome c in Population.Chromosomes )
            {
                totalObjective += c.RawObjective;
                if ( c.RawObjective < LowestObjective )
                {
                    lowestObjective = c.RawObjective;
                    if ( ga.ObjectiveType == ObjectiveType.MinimizeObjective )
                    {
                        bestChromosome = c;
                    }
                }
                if ( c.RawObjective > HighestObjective )
                {
                    highestObjective = c.RawObjective;
                    if ( ga.ObjectiveType == ObjectiveType.MaximizeObjective )
                    {
                        bestChromosome = c;
                    }
                }
            }
            meanObjective = totalObjective / Population.Chromosomes.Length;


            //
            // Variance is the average squared deviation from the mean.
            // Standard Deviation is just the square root of this.
            //
            double sum = 0;
            foreach(Chromosome c in Population.Chromosomes)
            {
                double deviation;
                double squaredDeviation;

                deviation = c.RawObjective - meanObjective;
                squaredDeviation = deviation * deviation;

                sum += squaredDeviation;
            }
            variance = sum / (Population.Chromosomes.Length-1);
            standardDeviation = Math.Sqrt( variance );
        }