Exemple #1
0
 private void Initialize(IGeneticIndividual progenitor)//called by constructor//randomly decide the aspects of each individual in individuals.
 {
     for (int i = 0; i < individuals.Length; i++)
     {
         individuals[i] = progenitor;
         individuals[i].Randomize();
     }
 }
Exemple #2
0
    public IGeneticIndividual TrainGeneration(int numGenerations)//execute a number of iterations of the algorithm creating more fit solutions. Return most fit individual
    {
        for (int i = 0; i < numGenerations; i++)
        {
            generationCount++;
            //create elite array
            IGeneticIndividual[] eliteIndividuals = new IGeneticIndividual[numToSave];
            for (int j = 0; j < numToSave; j++)
            {
                eliteIndividuals[j] = individuals[j];
            }
            //create 2 dim array of parents(1) for each child(0)
            IGeneticIndividual[,] reproductionGroups = new IGeneticIndividual[numChildrenNeeded, numParents]; //uses tournament selection process to fill array
            for (int childIter = 0; childIter < reproductionGroups.GetLength(0); childIter++)                 //iterate once per child
            {
                for (int parentIter = 0; parentIter < reproductionGroups.GetLength(1); parentIter++)          //iterate once per parent. This will
                {
                    IGeneticIndividual[] tournamentSubset = new IGeneticIndividual[tournamentSize];
                    for (int touranmentIter = 0; touranmentIter < tournamentSubset.Length; touranmentIter++)
                    {
                        tournamentSubset[touranmentIter] = individuals[(int)(RandHolder.NextDouble() * populationSize)];//pick a random individual
                    }
                    Array.Sort(tournamentSubset);
                    reproductionGroups[childIter, parentIter] = tournamentSubset[0];
                }
            }
            //generate children
            IGeneticIndividual[] newChildren = new IGeneticIndividual[numChildrenNeeded];//create empty array to hold newly generated children
            for (int childIter = 0; childIter < newChildren.Length; childIter++)
            {
                IGeneticIndividual[] reproductionGroup = new IGeneticIndividual[numParents];//fill the single dimensioned array, reproductionGroup, with its corresponding individuals from the 2 dimensional array, reproductionGroups.
                for (int parentIter = 0; parentIter < reproductionGroup.Length; parentIter++)
                {
                    reproductionGroup[parentIter] = reproductionGroups[childIter, parentIter];
                }
                newChildren[childIter] = reproductionGroup[0].Reproduce(reproductionGroup, numCrossoverPoints, 1)[0];//generate a single child with reproductionGroup as its parents. Method called by reproductionGroup[0] for convenience.
            }
            //mutate over children array
            for (int mutationIter = 0; mutationIter < populationSize; mutationIter++)
            {
                Mutate(mutationIter);
            }
            //combine elite and children array and copy into individuals array
            for (int eliteIter = 0; eliteIter < eliteIndividuals.Length; eliteIter++)//copy the high fitness individuals that were saved from the previous generation
            {
                individuals[eliteIter] = eliteIndividuals[eliteIter];
            }
            for (int childIter = 0; childIter < newChildren.Length; childIter++)//copy the newly generated children after the elite individuals
            {
                individuals[eliteIndividuals.Length + childIter] = newChildren[childIter];
            }

            FitnessSort();      //order the individuals by fitness
        }
        return(individuals[0]); //the highest fitness
    }
        /// <summary>
        /// Returns a child of the two parents. 
        /// </summary>
        /// <param name="parentOne"></param>
        /// <param name="parentTwo"></param>
        /// <returns></returns>
        public IGeneticIndividual Reproduce(IGeneticIndividual parentOne, IGeneticIndividual parentTwo)
        {
            var one = (parentOne as Individual);
                var two = (parentTwo as Individual);

                var childOne = GenerateChild(one, two);
                var childTwo = GenerateChild(two, one);

                var child = ChooseRandomChild(childOne, childTwo);
                return child;
        }
Exemple #4
0
    public IGeneticIndividual[] Reproduce(IGeneticIndividual[] IParents, int numCrossoverPoints, int numChildren)
    {
        int numParents = IParents.Length;//convenient variable to have

        //convert array of type IGeneticIndividual to type TestGeneticIndividual
        TestGeneticIndividual[] parents = new TestGeneticIndividual[numParents];
        for (int i = 0; i < numParents; i++)
        {
            parents[i] = IParents[i] as TestGeneticIndividual;
        }
        TestGeneticIndividual[] children = new TestGeneticIndividual[numChildren]; //variable to hold generated children. Will be output by method
        for (int childIter = 0; childIter < numChildren; childIter++)              //iterate once for each child to be generated
        {
            int[] crossoverPoints = new int[numCrossoverPoints];
            //fill crossoverPoints array with random ints which are indexes of genes array
            for (int i = 0; i < crossoverPoints.Length; i++)
            {
                crossoverPoints[i] = (int)(RandHolder.NextDouble() * parents[0].genes.Length);
            }
            int activeParentIndex = 0;
            //generate child
            children[childIter] = new TestGeneticIndividual(parents[0].genes.Length);
            for (int i = 0; i < parents[0].genes.Length; i++)
            {
                children[childIter].genes[i] = parents[activeParentIndex].genes[i];
                for (int iter = 0; iter < numCrossoverPoints; iter++)
                {
                    if (i == crossoverPoints[iter])
                    {
                        int temp = (int)(RandHolder.NextDouble() * (parents.Length - 1));//minus one for value exclusion, so between first and second to last index
                        if (temp != activeParentIndex)
                        {
                            activeParentIndex = temp;
                        }
                        else
                        {
                            activeParentIndex = parents.Length - 1;//minus one because it is max index of array
                        }
                    }
                }
            }
        }
        //convert array of type TestGeneticIndividual to type IGeneticIndividual
        IGeneticIndividual[] IChildren = new IGeneticIndividual[numChildren];
        for (int i = 0; i < numChildren; i++)
        {
            IChildren[i] = children[i] as IGeneticIndividual;
        }
        return(IChildren);
    }
Exemple #5
0
 public int CompareTo(IGeneticIndividual obj)//to be used by Arrays.sort in GeneticAlgorithm.cs>FitnessSort()
 {
     if (this.Fitness() > obj.Fitness())
     {
         return(-1);//precede in sort order
     }
     else if (this.Fitness() < obj.Fitness())
     {
         return(1);//succeed in sort order
     }
     else
     {
         return(0);//equal in sort
     }
 }
Exemple #6
0
 public int CompareTo(IGeneticIndividual individual)
 {
     if (this.Fitness() > individual.Fitness())
     {
         return(-1);//precede in sort order
     }
     else if (this.Fitness() < individual.Fitness())
     {
         return(1);//succeed in sort order
     }
     else
     {
         return(0);//equal in sort
     }
 }
Exemple #7
0
    public GeneticAlgorithm(IGeneticIndividual progenitor, int populationSize, int numParents, float environmentalPressure, float eliteFraction, int numCrossoverPoints, float mutationChance, int tournamentSize)//initialization of arrays and variables
    {
        this.populationSize        = populationSize;
        this.numParents            = numParents;
        this.environmentalPressure = environmentalPressure;
        this.eliteFraction         = eliteFraction;
        this.numCrossoverPoints    = numCrossoverPoints;
        this.mutationChance        = mutationChance;
        this.tournamentSize        = tournamentSize;

        numToSave         = (int)(eliteFraction * populationSize);
        numChildrenNeeded = populationSize - numToSave;//each child will have its own set of parents

        individuals = new IGeneticIndividual[populationSize];
        Initialize(progenitor);
        FitnessSort();
    }
        /// <summary>
        /// Use the distance formula to assign a distance to each pixel of the individuals from the targets. 
        /// The total fitness is the average fitness of all the pixels. 
        /// </summary>
        /// <param name="individual"></param>
        private void EvaluateIndividual(IGeneticIndividual individual)
        {
            var target = _configuration.Target;
                var genome = (individual as Individual).Genome;
                double fitness = 0;

                for (int index = 0; index < target.Count; index++)
                {
                    var targetPixel = target[index];
                    var individualPixel = genome[index];

                    float rDistance = (targetPixel.R - individualPixel.R);
                    float gDistance = (targetPixel.G - individualPixel.G);
                    float bDistance = (targetPixel.B - individualPixel.B);

                    float distance = ((rDistance * rDistance) + (gDistance * gDistance) + (bDistance * bDistance));

                    fitness += Math.Abs(distance - MAXIMUM_FITNESS) + 1;
                }

                individual.Fitness = fitness / target.Count;
        }
Exemple #9
0
 public int CompareTo(object obj)//should never be called because should never be compared to other data types but needs to be here to satisfy compiler
 {
     if (obj is IGeneticIndividual)
     {
         IGeneticIndividual GAObj = (IGeneticIndividual)obj;
         if (this.Fitness() > GAObj.Fitness())
         {
             return(-1);//precede in sort order
         }
         else if (this.Fitness() < GAObj.Fitness())
         {
             return(1);//succeed in sort order
         }
         else
         {
             return(0);//equal in sort
         }
     }
     else
     {
         throw new NotImplementedException();
     }
 }
Exemple #10
0
 public int CompareTo(object obj)
 {
     if (obj is IGeneticIndividual)
     {
         IGeneticIndividual GAObj = (IGeneticIndividual)obj;
         if (this.Fitness() > GAObj.Fitness())
         {
             return(-1);//precede in sort order
         }
         else if (this.Fitness() < GAObj.Fitness())
         {
             return(1);//succeed in sort order
         }
         else
         {
             return(0);//equal in sort
         }
     }
     else
     {
         throw new System.NotImplementedException();
     }
 }
 /// <summary>
 /// Mutate the individual. 
 /// </summary>
 /// <param name="individual"></param>
 public void Mutate(IGeneticIndividual individual)
 {
     var toMutate = individual as Individual;
         ChangeGenome(toMutate);
 }
Exemple #12
0
    public IGeneticIndividual[] Reproduce(IGeneticIndividual[] IParents, int numCrossoverPoints, int numChildren)  //returns an array of nets given an array of all parents.
    // Doesn't necessarily need to be called by one of the parents but that's probably convenient.
    //numCrossover points SHOULD be > numParents-1 (to use all parents at least once), but it's fine if not
    {
        int numParents = IParents.Length;//convenient variable to have

        //convert array of type IGeneticIndividual to type NeuralNet
        NeuralNet[] parents = new NeuralNet[numParents];
        for (int i = 0; i < numParents; i++)
        {
            parents[i] = IParents[i] as NeuralNet;
        }
        NeuralNet[] children = new NeuralNet[numChildren];            //variable to hold generated children. Will be output by method
        for (int childIter = 0; childIter < numChildren; childIter++) //iterate once for each child to be generated
        {
            //generate random crossoverPoints
            int[,] crossoverPoints = new int[numCrossoverPoints, 3];    //3 because (i, j, k) are (layer, node, weight)
            for (int cpIter = 0; cpIter < numCrossoverPoints; cpIter++) //iterate for each crossover point and generate it. Code copied from Mutate()
            {
                //layer to cp//
                int i = (int)(RandHolder.NextDouble() * (parents[0].numHiddenLayers + 1)); //+1 for output
                //node to cp//
                int j = -1;                                                                //should cause an index out of bounds if not set by subsequent if cases
                if (i == 0)
                {                                                                          //if first hidden layer (same as else case)(same number of nodes as hidden layer so doesn't matter)
                    j = (int)(RandHolder.NextDouble() * parents[0].hiddenLayerSize);
                }
                else if (i == parents[0].numHiddenLayers)
                {//if output layer
                    j = (int)(RandHolder.NextDouble() * parents[0].numOutputs);
                }
                else
                {//if any other hidden layer
                    j = (int)(RandHolder.NextDouble() * parents[0].hiddenLayerSize);
                }
                //weight to cp//
                int k = -1;                                                                //should cause an index out of bounds if not set by subsequent if cases
                if (i == 0)                                                                //if first hidden layer (same as else case)(same number of nodes as hidden layer so doesn't matter)
                {
                    k = (int)(RandHolder.NextDouble() * (parents[0].numInputs) + 1);       //+1 for bias
                }
                else if (i == parents[0].numHiddenLayers)                                  //if output layer same as else case
                {
                    k = (int)(RandHolder.NextDouble() * (parents[0].hiddenLayerSize) + 1); //+1 for bias
                }
                else//if any other hidden layer
                {
                    k = (int)(RandHolder.NextDouble() * (parents[0].hiddenLayerSize) + 1);//+1 for bias
                }

                //assign i,j,k to crossoverPoints
                crossoverPoints[cpIter, 0] = i;
                crossoverPoints[cpIter, 1] = j;
                crossoverPoints[cpIter, 2] = k;//duplicate crossover points might exist but honestly who cares
            }
            //create array to hold new layers, nodes, weights
            Layer[] newLayers = new Layer[parents[0].numHiddenLayers + 1];

            //fill newLayers
            int activeParentIndex = 0;

            for (int i = 0; i < parents[0].numHiddenLayers + 1; i++)                                         //+1 for output layer
            {
                if (i == 0)                                                                                  //first hidden layer
                {
                    double[,] newWeights = new double[parents[0].hiddenLayerSize, parents[0].numInputs + 1]; //create empty container, +1 for bias
                    for (int j = 0; j < newWeights.GetLength(0); j++)
                    {
                        for (int k = 0; k < newWeights.GetLength(1); k++)//this will run for each weight and bias
                        {
                            //check if currently at a crossover point if so then swap the activeParentIndex
                            for (int iter = 0; iter < numCrossoverPoints; iter++)//check for each crossover point
                            {
                                if (crossoverPoints[iter, 0] == i && crossoverPoints[iter, 1] == j && crossoverPoints[iter, 2] == k)
                                {
                                    activeParentIndex = (int)(RandHolder.NextDouble() * (numParents));//choose a random parent including currently active parent
                                }
                            }
                            newWeights[j, k] = parents[activeParentIndex].layers[i].Weights[j, k];//copy the value from the active aprent
                        }
                    }
                    newLayers[i] = new Layer(parents[0].numInputs, parents[0].hiddenLayerSize, newWeights);        //assign new weights to newLayers array in the form of a newly instantiated Layer
                }
                else if (i > 0 && i < parents[0].numHiddenLayers)                                                  //all other hidden layers
                {
                    double[,] newWeights = new double[parents[0].hiddenLayerSize, parents[0].hiddenLayerSize + 1]; //create empty container, +1 for bias
                    for (int j = 0; j < newWeights.GetLength(0); j++)
                    {
                        for (int k = 0; k < newWeights.GetLength(1); k++)//this will run for each weight and bias
                        {
                            //check if currently at a crossover point if so then swap the activeParentIndex
                            for (int iter = 0; iter < numCrossoverPoints; iter++)//check for each crossover point
                            {
                                if (crossoverPoints[iter, 0] == i && crossoverPoints[iter, 1] == j && crossoverPoints[iter, 2] == k)
                                {
                                    int temp = (int)(RandHolder.NextDouble() * (numParents - 1));//the minus one is because we are avoiding the current activeParentIndex in this reassignment
                                    if (temp < activeParentIndex)
                                    {
                                        activeParentIndex = temp;
                                    }
                                    else//if greater than or equal to activeParentIndex
                                    {
                                        activeParentIndex = temp + 1;
                                    }
                                }
                            }
                            newWeights[j, k] = parents[activeParentIndex].layers[i].Weights[j, k];//copy the value from the active parent
                        }
                    }
                    newLayers[i] = new Layer(parents[0].numInputs, parents[0].hiddenLayerSize, newWeights);   //assign new weights to newLayers array in the form of a newly instantiated Layer
                }
                else if (i == parents[0].numHiddenLayers)                                                     //output layer
                {
                    double[,] newWeights = new double[parents[0].numOutputs, parents[0].hiddenLayerSize + 1]; //create empty container, +1 for bias
                    for (int j = 0; j < newWeights.GetLength(0); j++)
                    {
                        for (int k = 0; k < newWeights.GetLength(1); k++)//this will run for each weight and bias
                        {
                            //check if currently at a crossover point if so then swap the activeParentIndex
                            for (int iter = 0; iter < numCrossoverPoints; iter++)//check for each crossover point
                            {
                                if (crossoverPoints[iter, 0] == i && crossoverPoints[iter, 1] == j && crossoverPoints[iter, 2] == k)
                                {
                                    int temp = (int)(RandHolder.NextDouble() * (numParents - 1));//the minus one is because we are avoiding the current activeParentIndex in this reassignment
                                    if (temp < activeParentIndex)
                                    {
                                        activeParentIndex = temp;
                                    }
                                    else//if greater than or equal to activeParentIndex
                                    {
                                        activeParentIndex = temp + 1;
                                    }
                                }
                            }
                            newWeights[j, k] = parents[activeParentIndex].layers[i].Weights[j, k];//copy the value from the active aprent
                        }
                    }
                    newLayers[i] = new Layer(parents[0].hiddenLayerSize, parents[0].numOutputs, newWeights);//assign new weights to newLayers array in the form of a newly instantiated Layer
                }
                else
                {
                    throw new IndexOutOfRangeException();
                }
            }

            children[childIter] = new NeuralNet(parents[0].numInputs, parents[0].numOutputs, parents[0].numHiddenLayers, parents[0].hiddenLayerSize, parents[0].TestInputSets, parents[0].TestOutputSets) //create empty with same params as parent
            {
                layers = newLayers                                                                                                                                                                        //assign the data to complete the child
            };
        }
        //convert array of type NeuralNet to type IGeneticIndividual
        IGeneticIndividual[] IChildren = new IGeneticIndividual[numChildren];
        for (int i = 0; i < numChildren; i++)
        {
            IChildren[i] = children[i] as IGeneticIndividual;
        }
        return(IChildren);
    }