Пример #1
0
        AddNewNeuronLinks(int linkIndex, CInnovation innovations)
        {
            float initialWeight = m_vecLinks[linkIndex].Weight;

            int from = m_vecLinks[linkIndex].FromNeuron;
            int to   = m_vecLinks[linkIndex].ToNeuron;

            SNeuronGene fromNeuron = m_vecNeurons[GetNeuronIndexById(from)];
            SNeuronGene toNeuron   = m_vecNeurons[GetNeuronIndexById(from)];

            // The depth of the neuron is used to determine if the new link
            // feeds backwards (i.e it is a recurrent link) or forwards.
            float newDepth = (fromNeuron.SplitY + toNeuron.SplitY) / 2;
            float newWidth = (fromNeuron.SplitX + toNeuron.SplitX) / 2;

            int innovationID = innovations.CheckInnovation(from, to,
                                                           InnovationType.NewNeuron);
            bool alreadyUsed = innovationID >= 0 &&
                               UsingNeuronID(innovations.GetNeuronID(innovationID));

            if (innovationID < 0 || alreadyUsed)
            {
                AddNeuronNewInnovation(innovations, from, to, newWidth,
                                       newDepth, initialWeight);
            }
            else
            {
                int newNeuronID = innovations.GetNeuronID(innovationID);
                AddNeuronExistingInnovation(innovations, newNeuronID, from, to,
                                            newWidth, newDepth, initialWeight);
            }
        }
Пример #2
0
        Cga(int inputs, int outputs)
        {
            m_Population = new List <CGenome> ();

            for (int i = 0; i < _params.NumGenomesToSpawn; i++)
            {
                m_Population.Add(new CGenome(nextGenomeID++, inputs, outputs));
            }
            m_PopSize = m_Population.Count;

            // Create simple genome used for innovations database
            CGenome genome = new CGenome(1, inputs, outputs);

            m_vecSpecies = new List <CSpecies> ();

            innovation = new CInnovation(genome.GetLinks(), genome.GetNeurons());

            vecSplits = new List <SplitDepth> ();

            // Create the network depth lookup table.
            Split(0, 1, 0);
        }
Пример #3
0
        AddNeuronNewInnovation(CInnovation innovations, int from, int to,
                               float newWidth, float newDepth, float initialWeight)
        {
            int newNeuronID = innovations.CreateNewInnovation(from, to,
                                                              InnovationType.NewNeuron, NeuronType.Hidden,
                                                              newWidth, newDepth);

            // In addition to adding the new neuron two new links
            // are created and stored in the innovations database
            int idLink1 = innovations.NextInnovationID();

            innovations.CreateNewInnovation(from, newNeuronID,
                                            InnovationType.NewLink);

            int idLink2 = innovations.NextInnovationID();

            innovations.CreateNewInnovation(newNeuronID, to,
                                            InnovationType.NewLink);

            CreateNewNeuronLinks(from, to, newNeuronID, idLink1, idLink2,
                                 newWidth, newDepth, initialWeight);
        }
Пример #4
0
        AddNeuronExistingInnovation(CInnovation innovations, int newNeuronID,
                                    int from, int to, float newWidth, float newDepth,
                                    float initialWeight)
        {
            int idLink1 = innovations.CheckInnovation(from, newNeuronID,
                                                      InnovationType.NewLink);
            int idLink2 = innovations.CheckInnovation(newNeuronID, to,
                                                      InnovationType.NewLink);

            /*
             * This should not happen because if we got here the
             * links should logically already have a innovation
             */
            if (idLink1 < 0 || idLink2 < 0)
            {
                Debug.LogError("Error: no link genes found for neuron");
                return;
            }

            CreateNewNeuronLinks(from, to, newNeuronID, idLink1, idLink2,
                                 newWidth, newDepth, initialWeight);
        }
Пример #5
0
        AddNeuron(float mutationRate, CInnovation innovations,
                  int numTriesToFindOldLink)
        {
            if (Random.value > mutationRate)
            {
                return;
            }

            // If this flag is true a valid link for the new neuron has been
            // found.
            bool foundLink = false;

            // Store the index of the link that will be used.
            int linkIndex = 0;

            if (m_vecLinks.Count < (m_iNumInputs + m_iNumOutputs + _params.MinHiddenNeurons))
            {
                foundLink = FindNeuronLinkBiased(out linkIndex, numTriesToFindOldLink);

                if (!foundLink)
                {
                    return;
                }
            }
            else /* The genome is complex enough to select any link */
            {
                do
                {
                    linkIndex = Random.Range(0, NumGenes());
                }while (!CanLinkBeSplit(linkIndex));
            }

            // Disable this link first so we can replace it with two new.
            m_vecLinks[linkIndex].Disable();

            AddNewNeuronLinks(linkIndex, innovations);
        }
Пример #6
0
        AddLink(float mutationRate, float chanceOfLooped,
                CInnovation innovations, int numTriesToFindLoop,
                int numTriesToAddLink)
        {
            if (Random.value > mutationRate)
            {
                return;
            }

            int neuron1_ID = -1;
            int neuron2_ID = -1;

            // If this flag is true a recurrent link is added.
            bool setRecurrent = false;

            // There is a chance that this will be a looped recurrent link
            // (i.e a neuron that has a link directly to itself).
            if (Random.value < chanceOfLooped)
            {
                setRecurrent = AddLoopedRecurrentLink(out neuron1_ID,
                                                      out neuron2_ID, numTriesToFindLoop);
            }
            else
            {
                AddNonReccurentLink(out neuron1_ID, out neuron2_ID,
                                    numTriesToAddLink);
            }

            if (neuron1_ID < 0 || neuron2_ID < 0)
            {
                return;
            }

            // Does the database already hold a similar innovation?
            int innovationID = innovations.CheckInnovation(neuron1_ID,
                                                           neuron2_ID, InnovationType.NewLink);

            // Check if this link is a recurrent link (non-looped).
            // If the link feeds backward it is a recurrent link.
            //
            // A backward link is characterized with the fact that the from
            // neuron has a greater SplitY value than the to neuron.
            if (m_vecNeurons[GetNeuronIndexById(neuron1_ID)].SplitY >
                m_vecNeurons[GetNeuronIndexById(neuron2_ID)].SplitY)
            {
                setRecurrent = true;
            }

            if (innovationID < 0)
            {
                // This innovation does not exist so we add a new innovation
                // to the database with a id so we can later refer to it by
                // its new id. The new link gene will be tagged with this id.
                innovations.CreateNewInnovation(neuron1_ID, neuron2_ID,
                                                InnovationType.NewLink);
                innovationID = innovations.NextInnovationID() - 1;
            }

            // Assign the innovation id to a new link gene.
            SLinkGene newGene = new SLinkGene(neuron1_ID, neuron2_ID,
                                              true /* enable */,
                                              innovationID,
                                              Random.Range(-1.0f, 1.0f) /* initial weight */,
                                              setRecurrent);

            m_vecLinks.Add(newGene);
        }