Beispiel #1
0
        private IEntity SelectOne(IEntityList entities, int tournamentSize)
        {
            var index = Random.GetInt(0, entities.Count);
            var best  = entities[index];

            for (int i = 1; i < tournamentSize; i++)
            {
                index = Random.GetInt(0, entities.Count);
                var next             = entities[index];
                var comparisonResult = FitnessComparer.Compare(best.Fitness, next.Fitness);
                if (comparisonResult > 0)
                {
                    next.Fitness.TournamentWinner++;
                    best.Fitness.TournamentLoser++;
                    best = next;
                }
                else
                {
                    best.Fitness.TournamentWinner++;
                    next.Fitness.TournamentLoser++;
                }
            }

            return(best);
        }
        public override IEntityList Replace(IPopulation targetPopulation, IEntityList offspring, IEntityList parents, IPopulation sourcePopulation)
        {
            var inserted       = new EntityList(1);
            var populationSize = Parameters.GetValue(Algorithm.ParameterNames.PopulationSize);

            //TODO: FitnessComparer.SelectWorst, SelectBest

            if (offspring.Count == 0)
            {
                return(inserted);
            }

            var entityToRemove = FitnessComparer.Dominates(parents[0].Fitness, parents[1].Fitness) ? parents[0] : parents[1];
            var entityToAdd    = (offspring.Count > 1 && FitnessComparer.Dominates(offspring[0].Fitness, offspring[1].Fitness)) ? offspring[1] : offspring[0];

            if (FitnessComparer.Dominates(entityToRemove.Fitness, entityToAdd.Fitness))
            {
                targetPopulation.Add(entityToAdd);
                inserted.Add(entityToAdd);

                if (sourcePopulation.Count > populationSize)
                {
                    sourcePopulation.Remove(entityToRemove);
                }
            }

            return(inserted);
        }
Beispiel #3
0
        public void MergeToBests(IEntityList entities)
        {
            IEntityList travelers = new EntityList(entities.Count);
            bool        anyMerged = false;

            for (int e = 0; e < entities.Count; e++)
            {
                if (entities[e].Fitness.IsLethal())
                {
                    continue;
                }

                bool merged = FitnessComparer.MergeToBests(Algorithm.Population.Bests, entities[e]);
                if (merged)
                {
                    travelers.Add(entities[e]);
                    var timeString = DateTime.Now.ToString("HH:mm:ss.ffff");
                    Debug.WriteLine(timeString + " " + entities[e].ToString());
                    var stat = Algorithm.Population.FitnessStatistics.StatisticVariables[0];
                    Debug.WriteLine($"{timeString} Mean: {stat.Mean}, Deviation: {stat.Deviation}");
                    anyMerged = true;
                }
            }

            if (anyMerged && NewEntityMergedToBest != null)
            {
                NewEntityMergedToBest(Algorithm.Population.Bests);
            }

            if (LaunchTravelers != null && travelers.Count > 0)
            {
                LaunchTravelers(travelers, TravelerTypes.Best);
            }
        }
Beispiel #4
0
        /// <summary>
        /// Sorts the population according to
        /// </summary>
        /// <param name="solver"></param>
        /// <param name="op"></param>
        public void Sort(
            Solver <GenomeType, ProblemType, WeightType> solver,
            IFitnessCalculator <GenomeType, ProblemType, WeightType> op)
        {
            // create comparer.
            FitnessComparer comparer = new FitnessComparer(solver, op);

            // sort using comparer.
            _individuals.Sort(comparer);
        }
        private int SelectOne(IEntityList entities, int size)
        {
            var index = Random.GetInt(0, entities.Count);
            var worst = index;

            for (int i = 1; i < size; i++)
            {
                index = Random.GetInt(0, entities.Count);
                var comparisonResult = FitnessComparer.Compare(entities[worst].Fitness, entities[index].Fitness);
                if (comparisonResult < 0)
                {
                    worst = index;
                }
            }

            return(worst);
        }
Beispiel #6
0
    private void Start()
    {
        // actors ignore each other
        Physics2D.IgnoreLayerCollision(10, 10, true);
        ImportPremadeBrain();

        // reset scores
        generation      = 0;
        globalBestScore = 0;
        globalFastest   = 0;
        globalMostLaps  = 0;
        globalBestBrain = null;
        population      = null;

        if (play)
        {
            Instantiate(player);
        }
        else
        {
            if (testBrain)
            {
                NeuralNetwork testb = JsonUtility.FromJson <NeuralNetwork>(ReadBrain(readFile));
                StartCoroutine(AssignBrain(Instantiate(player).GetComponent <PlayerController>(), testb));
            }
            else
            {
                fc         = new FitnessComparer();
                population = new PlayerController[populationCount];

                for (int j = 0; j < populationCount; j++)
                {
                    GameObject p = Instantiate(player);
                    population[j] = p.GetComponent <PlayerController>();
                }
                populationAlive = populationCount;
            }
        }
    }
Beispiel #7
0
        public override IOperation Apply()
        {
            double maxSelPress    = MaximumSelectionPressureParameter.ActualValue.Value;
            double successRatio   = SuccessRatioParameter.ActualValue.Value;
            IScope scope          = ExecutionContext.Scope;
            IScope parents        = scope.SubScopes[0];
            IScope offspring      = scope.SubScopes[1];
            int    populationSize = parents.SubScopes.Count;

            // retrieve actual selection pressure and success ratio
            DoubleValue selectionPressure = SelectionPressureParameter.ActualValue;

            if (selectionPressure == null)
            {
                selectionPressure = new DoubleValue(0);
                SelectionPressureParameter.ActualValue = selectionPressure;
            }
            DoubleValue currentSuccessRatio = CurrentSuccessRatioParameter.ActualValue;

            if (currentSuccessRatio == null)
            {
                currentSuccessRatio = new DoubleValue(0);
                CurrentSuccessRatioParameter.ActualValue = currentSuccessRatio;
            }

            // retrieve next population
            ItemList <IScope> population         = OffspringPopulationParameter.ActualValue;
            ItemList <IScope> virtual_population = OffspringVirtualPopulationParameter.ActualValue;

            IntValue successfulOffspring;

            if (population == null)
            {
                population = new ItemList <IScope>();
                OffspringPopulationParameter.ActualValue = population;
                selectionPressure.Value   = 0; // initialize selection pressure for this round
                currentSuccessRatio.Value = 0; // initialize current success ratio for this round
                successfulOffspring       = new IntValue(0);
                OffspringPopulationWinnersParameter.ActualValue = successfulOffspring;

                virtual_population = new ItemList <IScope>();
                OffspringVirtualPopulationParameter.ActualValue = virtual_population;
            }
            else
            {
                successfulOffspring = OffspringPopulationWinnersParameter.ActualValue;
            }

            int successfulOffspringAdded = 0;

            // implement the ActualValue fetch here - otherwise the parent scope would also be included, given that there may be 1000 or more parents, this is quite unnecessary
            string tname          = SuccessfulOffspringParameter.TranslatedName;
            double tmpSelPress    = selectionPressure.Value;
            double tmpSelPressInc = 1.0 / populationSize;

            for (int i = 0; i < offspring.SubScopes.Count; i++)
            {
                // fetch value
                IVariable tmpVar;
                if (!offspring.SubScopes[i].Variables.TryGetValue(tname, out tmpVar))
                {
                    throw new InvalidOperationException(Name + ": Could not determine if an offspring was successful or not.");
                }
                BoolValue tmp = (tmpVar.Value as BoolValue);
                if (tmp == null)
                {
                    throw new InvalidOperationException(Name + ": The variable that indicates whether an offspring is successful or not must contain a BoolValue.");
                }

                // add to population
                if (tmp.Value)
                {
                    IScope currentOffspring = offspring.SubScopes[i];
                    offspring.SubScopes.RemoveAt(i);
                    i--; // next loop should continue with the subscope at index i which replaced currentOffspring
                    population.Add(currentOffspring);
                    successfulOffspringAdded++;
                }
                else
                {
                    IScope currentOffspring = offspring.SubScopes[i];
                    offspring.SubScopes.RemoveAt(i);
                    i--;
                    virtual_population.Add(currentOffspring); // add to losers pool
                }
                tmpSelPress += tmpSelPressInc;

                double tmpSuccessRatio = (successfulOffspring.Value + successfulOffspringAdded) / ((double)populationSize);
                if (tmpSuccessRatio >= successRatio && (population.Count + virtual_population.Count) >= populationSize)
                {
                    break;
                }
            }
            successfulOffspring.Value += successfulOffspringAdded;

            // calculate actual selection pressure and success ratio
            selectionPressure.Value   = tmpSelPress;
            currentSuccessRatio.Value = successfulOffspring.Value / ((double)populationSize);

            // check if enough children have been generated (or limit of selection pressure or evaluted solutions is reached)
            if (((EvaluatedSolutionsParameter.ActualValue.Value < MaximumEvaluatedSolutionsParameter.ActualValue.Value) &&
                 (selectionPressure.Value < maxSelPress) &&
                 (currentSuccessRatio.Value < successRatio)) ||
                ((population.Count + virtual_population.Count) < populationSize))
            {
                // more children required -> reduce left and start children generation again
                scope.SubScopes.Remove(parents);
                scope.SubScopes.Remove(offspring);
                while (parents.SubScopes.Count > 0)
                {
                    IScope parent = parents.SubScopes[0];
                    parents.SubScopes.RemoveAt(0); // TODO: repeated call of RemoveAt(0) is inefficient?
                    scope.SubScopes.Add(parent);   // order of subscopes is reversed
                }

                IOperator offspringCreator = OffspringCreatorParameter.ActualValue as IOperator;
                if (offspringCreator == null)
                {
                    throw new InvalidOperationException(Name + ": More offspring are required, but no operator specified for creating them.");
                }
                return(ExecutionContext.CreateOperation(offspringCreator)); // this assumes that this operator will be called again indirectly or directly
            }
            else
            {
                // enough children generated
                var fitnessComparer = new FitnessComparer(QualityParameter.TranslatedName, MaximizationParameter.ActualValue.Value);
                population.Sort(fitnessComparer); // sort individuals by descending fitness

                // keeps only the best successRatio * populationSize solutions in the population (the remaining ones are added to the virtual population)
                int removed = 0;
                for (int i = 0; i < population.Count; i++)
                {
                    double tmpSuccessRatio = i / (double)populationSize;
                    if (tmpSuccessRatio > successRatio)
                    {
                        virtual_population.Add(population[i]);
                        removed++;
                    }
                }
                population.RemoveRange(population.Count - removed, removed);

                //fill up population with best remaining children (successful or unsuccessful)
                virtual_population.Sort(fitnessComparer);
                int offspringNeeded = populationSize - population.Count;
                for (int i = 0; i < offspringNeeded && i < virtual_population.Count; i++)
                {
                    population.Add(virtual_population[i]); // children are sorted by descending fitness
                }

                offspring.SubScopes.Clear();
                offspring.SubScopes.AddRange(population);

                scope.Variables.Remove(OffspringPopulationParameter.TranslatedName);
                scope.Variables.Remove(OffspringVirtualPopulationParameter.TranslatedName);
                scope.Variables.Remove(OffspringPopulationWinnersParameter.TranslatedName);
                return(base.Apply());
            }
        }
        static void Main(string[] args)
        {
            Maze         maze       = new Maze();
            Random       rand       = new Random(System.DateTime.Now.Millisecond);
            List <Robot> robots     = new List <Robot>();
            int          generation = 1;

            //Create comma delimted output file and open stream to it
            System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(@"c:\Users\Pehr\Documents\robotDataFile.csv");
            streamWriter.WriteLine("Initial Fitness:");

            // Create initial population of robots
            for (int i = 0; i < startingPopulationSize; i++)
            {
                robots.Add(new Robot(rand));

                robots[i].ProcessRobot(maze);

                System.Console.Write(robots[i].Fitness);
                System.Console.Write("  ");

                //Write intial data to output file
                streamWriter.WriteLine(robots[i].Fitness);
            }

            // Sort our robots by fitness
            FitnessComparer fitnessComparer = new FitnessComparer();

            robots.Sort(fitnessComparer);

            // While fitness[highest sorted] < 0.9 or maybe 1.0
            while (robots[0].Fitness < fitnessThreshold)
            {
                // Save our fittest (first) 10 robots for the next generation and kill off the least fit 10 (last) robots
                List <Robot> fittestRobots = new List <Robot>();

                for (int i = 0; i < saveKillCount; i++)
                {
                    robots.RemoveAt(robots.Count - 1);
                    fittestRobots.Add(new Robot(robots[i].GenoType, robots[i].Fitness));
                }

                // Randomly sort our robot list to create random pairs for crossover
                robots.Sort(delegate(Robot x, Robot y) { return((x.Fitness == y.Fitness) ? 0 : rand.Next(0, 1)); });

                // Iterate through our list pairing robots and performing crossover or mutation
                for (int i = 0; i < robots.Count; i++)
                {
                    int crossoverMutationChoser = rand.Next(0, 9);

                    // 70% chance of crossover (and must be at least 2 robots left)
                    if (i < robots.Count - 1 && crossoverMutationChoser < crossoverChance)
                    {
                        Robot parentOne = robots[i];
                        Robot parentTwo = robots[i + 1];
                        Robot.Crossover(ref parentOne, ref parentTwo, rand);
                        // ProcessRobot will get a new fitness value
                        robots[i].ProcessRobot(maze);
                        robots[i + 1].ProcessRobot(maze);
                    }
                    else
                    // 30% chance of mutation
                    {
                        robots[i].Mutate(rand);
                        // ProcessRobot will get a new fitness value
                        robots[i].ProcessRobot(maze);
                    }
                }
                // Re-add our fittest robots
                for (int i = 0; i < saveKillCount; i++)
                {
                    robots.Add(fittestRobots[i]);
                }
                generation++;
                System.Console.Write("New generation: ");

                // Put our robots in fitness sort order
                robots.Sort(fitnessComparer);

                streamWriter.WriteLine(String.Format("Fitness Generation[{0}]:", generation));
                String phenoType = new String(robots[0].PhenoType);
                streamWriter.WriteLine(String.Format("Fittest Phenotype: {0}", phenoType));

                // Print out our current fitness data
                for (int i = 0; i < robots.Count; i++)
                {
                    System.Console.Write(robots[i].Fitness);
                    System.Console.Write("  ");

                    //Write current fitness data to output file
                    streamWriter.WriteLine(robots[i].Fitness);
                }
            }
            System.Console.Write("Final fitness values: ");
            streamWriter.WriteLine(String.Format("Final Fitness Generation[{0}]:", generation));
            String pheno = new String(robots[0].PhenoType);

            streamWriter.WriteLine(String.Format("Fittest Phenotype: {0}", pheno));

            StreamWriter fitPhenoWriter = new StreamWriter(@"c:\Users\Pehr\Documents\robotSolution.txt");

            fitPhenoWriter.Write(pheno);
            fitPhenoWriter.Close();

            for (int i = 0; i < robots.Count; i++)
            {
                System.Console.Write(robots[i].Fitness);
                System.Console.Write("  ");

                //Write current fitness data to output file
                streamWriter.WriteLine(robots[i].Fitness);
            }
            streamWriter.Close();
            // Wait for input so data can be viewed on console
            System.Console.ReadKey();
        }