private static void RunSelectionAndMutation()
        {
            foreach (String identifier in identifierPopulations.Keys.ToList())
            {
                List <BaseModule> oldPopulation = identifierPopulations[identifier];

                if (oldPopulation.Count <= Constants.MinPopulationSize)
                {
                    continue;
                }

                List <BaseModule> newPopulation = new List <BaseModule>();

                newPopulation.AddRange(oldPopulation.Where(x => x.TimesUsed == 0));
                oldPopulation.RemoveAll(x => x.TimesUsed == 0);

                int eliteSize = (int)Math.Max(1, oldPopulation.Count * Constants.EliteRatio);
                IEnumerable <BaseModule> elite = oldPopulation.OrderBy(x => x.AverageRelativeError).Take(eliteSize);
                elite = elite.Distinct();

                newPopulation.AddRange(elite);
                newPopulation.AddRange(elite.Select(x => {
                    if (randomizer.NextDouble() < Constants.ComplexifyProbability)
                    {
                        return(x.GetComplexifiedModule());
                    }
                    else
                    {
                        return(x.GetMutatedModule());
                    }
                }));

                if (elite.Average(x => x.Fitness) < Constants.EliteFitnessThreshold)
                {
                    double averageComplexity = newPopulation.Average(x => x.Complexity);

                    for (int i = newPopulation.Count(); i < Constants.PopulationSize; i++)
                    {
                        BaseModule newModule = Module.GenerateSimpleModule(identifier, newPopulation.First().InputsCount);

                        if (newModule.Complexity < averageComplexity / 4)
                        {
                            newModule.Complexify();
                        }

                        newPopulation.Add(Module.GenerateSimpleModule(identifier, newPopulation.First().InputsCount));
                    }
                }
                else if (!identifierFullyTrained[identifier])
                {
                    identifierFullyTrained[identifier] = true;
                    Console.WriteLine(identifier + " is trained.");
                }

                identifierPopulations[identifier] = newPopulation;
            }
        }
예제 #2
0
        public override double Compute(List <double> inputs)
        {
            if (Instructions.Contains("k") && !Instructions.Contains("r"))
            {
                return(0);
            }

            Stack <double> stack = new Stack <double>();
            List <string>  instructionsToBeDone = new List <string>(Instructions);

            stack.Push(0);

            while (instructionsToBeDone.Count != 0)
            {
                string instruction = instructionsToBeDone[0];
                instructionsToBeDone.RemoveAt(0);

                if (instructionsToBeDone.Count > 500)
                {
                    return(0);
                }

                if (Double.TryParse(instruction, out double currentValue))
                {
                    stack.Push(currentValue);
                }
                else if (instruction.StartsWith("i") && int.TryParse(instruction.Substring(1), out int index))
                {
                    stack.Push(inputs[index]);
                }
                else if (instruction == "r")
                {
                    int    repetitions = (int)Math.Abs(stack.Pop());
                    string operation   = instructionsToBeDone[0];
                    instructionsToBeDone.RemoveAt(0);

                    List <string> instructionsToBeRepeated = new List <string>(instructionsToBeDone);
                    instructionsToBeDone.Clear();

                    for (int k = 1; k <= repetitions; k++)
                    {
                        foreach (string instructionToBeRepeated in instructionsToBeRepeated)
                        {
                            if (instructionToBeRepeated == "k")
                            {
                                instructionsToBeDone.Add(k.ToString());
                            }
                            else
                            {
                                instructionsToBeDone.Add(instructionToBeRepeated);
                            }
                        }

                        if (k > 1)
                        {
                            instructionsToBeDone.Add(operation);
                        }
                    }
                }
                else
                {
                    if (!ModuleManager.HasIdentifier(instruction))
                    {
                        ModuleManager.AddIdentifier(instruction, stack.Count - 1);
                    }

                    BaseModule currentModule = ModuleManager.GetModule(instruction);

                    modulesUsedLast.Add(currentModule);

                    List <double> arguments = new List <double>();

                    for (int i = 0; i < currentModule.InputsCount; i++)
                    {
                        arguments.Insert(0, stack.Pop());
                    }

                    stack.Push(currentModule.Compute(arguments));
                }
            }

            return(stack.Pop());
        }