Пример #1
0
    public static Genome Crossover(ref Genome mum, ref Genome dad, GeneticAlgorithm ga)
    {
        BestParent bestParent = GetBestParent(ref mum, ref dad);

        List <int> newPerceptrons = new List <int>();

        int curMum = 0;
        int curDad = 0;

        ConnectionGene selectedGene = null;

        Genome newGenome = RecycledGenome();

        while (!(curMum == mum.connections.Count && curDad == dad.connections.Count))
        {
            // Dad has more genes
            if (curMum == mum.connections.Count && curDad != dad.connections.Count)
            {
                if (bestParent == BestParent.dad)
                {
                    selectedGene = dad.GetConnectionGenes()[curDad];
                }

                curDad++;


                if (selectedGene == null)
                {
                    continue;
                }
            }
            // Mum has more genes
            else if (curMum != mum.connections.Count && curDad == dad.connections.Count)
            {
                if (bestParent == BestParent.mum)
                {
                    selectedGene = mum.GetConnectionGenes()[curMum];
                }

                curMum++;


                if (selectedGene == null)
                {
                    continue;
                }
            }
            // Mum gene innovation number is lower
            else if (mum.GetConnectionGenes()[curMum].innovNum < dad.GetConnectionGenes()[curDad].innovNum)
            {
                if (bestParent == BestParent.mum)
                {
                    selectedGene = mum.GetConnectionGenes()[curMum];
                }

                curMum++;


                if (selectedGene == null)
                {
                    continue;
                }
            }
            // Dad gene innovation number is lower
            else if (mum.GetConnectionGenes()[curMum].innovNum > dad.GetConnectionGenes()[curDad].innovNum)
            {
                if (bestParent == BestParent.dad)
                {
                    selectedGene = dad.GetConnectionGenes()[curDad];
                }

                curDad++;


                if (selectedGene == null)
                {
                    continue;
                }
            }
            // Both innovation numbers are equal
            else if (mum.GetConnectionGenes()[curMum].innovNum == dad.GetConnectionGenes()[curDad].innovNum)
            {
                if (Random.Range(0f, 1f) > 0.5f)
                {
                    selectedGene = mum.GetConnectionGenes()[curMum];
                }
                else
                {
                    selectedGene = dad.GetConnectionGenes()[curDad];
                }

                curDad++;
                curMum++;
            }
            else
            {
                Debug.Log("wtf");
            }

            if (selectedGene == null)
            {
                Debug.Log("Weird");
                continue;
            }
            if (newGenome.connectionGeneIndex == 0)
            {
                newGenome.AddConnectionGeneGene(new ConnectionGene(selectedGene));
            }
            else
            {
                if (newGenome.connections[newGenome.connectionGeneIndex - 1].innovNum != selectedGene.innovNum)
                {
                    newGenome.AddConnectionGeneGene(new ConnectionGene(selectedGene));
                }
            }

            newPerceptrons = AddPercepID(selectedGene.from, newPerceptrons);
            newPerceptrons = AddPercepID(selectedGene.to, newPerceptrons);
        }

        newPerceptrons.Sort();

        for (int i = 0; i < GA_Parameters.inputs + 1; i++)
        {
            newGenome = ga.innovations.CreateNeuronFromID(i, newGenome);
        }

        for (int i = 0; i < GA_Parameters.outputs; i++)
        {
            newGenome = ga.innovations.CreateNeuronFromID(GA_Parameters.inputs + 1 + i, newGenome);
        }

        for (int i = 0; i < newPerceptrons.Count; i++)
        {
            newGenome = ga.innovations.CreateNeuronFromID(newPerceptrons[i], newGenome);
        }

        MutParameters mutPar = new MutParameters(mum, dad);

        newGenome.ID      = ga.nextGenomeID;
        newGenome.inputs  = mum.inputs;
        newGenome.outputs = mum.outputs;
        newGenome.mutPar  = mutPar;

        ga.nextGenomeID++;

        newGenome.FinishGenome();

        return(newGenome);
    }