Esempio n. 1
0
        private static Genome crossDominant(NeatManager neat, Genome dominant, Genome other)
        {
            if (dominant.synapses.Count == 0 || other.synapses.Count == 0)
            {
                return(null);
            }

            int similarityNeurons = -1;

            for (int i = 1; i < 100000; i++)
            {
                if (dominant.hasSynapse(i) && other.hasSynapse(i))
                {
                    similarityNeurons = i;
                }
            }

            if (similarityNeurons == -1)
            {
                throw new Exception("No similarity between Genomes");
            }

            Genome newGenome = new Genome(neat, null, dominant.inputNeurons.ToArray(), dominant.outputNeurons.ToArray());

            for (int i = 1; i <= dominant.getHighestInnovationNumber(); i++)
            {
                if (dominant.hasSynapse(i))
                {
                    int    innovationNumber, inputNeuron, outputNeuron;
                    double weigth;
                    bool   enabled;

                    if (other.hasSynapse(i))
                    {
                        Random r = new Random();

                        if (r.Next(0, 1) == 1)
                        {
                            innovationNumber = dominant.synapses[i].innovationNumber;
                            inputNeuron      = dominant.synapses[i].from;
                            outputNeuron     = dominant.synapses[i].to;
                            weigth           = dominant.synapses[i].weight;
                            enabled          = dominant.synapses[i].enabled;
                        }
                        else
                        {
                            innovationNumber = other.synapses[i].innovationNumber;
                            inputNeuron      = other.synapses[i].from;
                            outputNeuron     = other.synapses[i].to;
                            weigth           = other.synapses[i].weight;
                            enabled          = other.synapses[i].enabled;
                        }
                    }
                    else
                    {
                        innovationNumber = dominant.synapses[i].innovationNumber;
                        inputNeuron      = dominant.synapses[i].from;
                        outputNeuron     = dominant.synapses[i].to;
                        weigth           = dominant.synapses[i].weight;
                        enabled          = dominant.synapses[i].enabled;
                    }
                    newGenome.addSynapse(new Synapse(innovationNumber, inputNeuron, outputNeuron, weigth, enabled), dominant, other);
                }
            }

            newGenome.removeDuplicateSynapses();
            newGenome.mutate();

            return(newGenome);
        }
Esempio n. 2
0
        // REF: [GITHUB] SanderGielisse logic for distance
        // between genomes (eg compatibility)
        // (https://github.com/SanderGielisse/Mythan)
        public static double distance(Genome a, Genome b)
        {
            int aLength = a.getHighestInnovationNumber();
            int bLength = b.getHighestInnovationNumber();

            Genome longest;
            Genome shortest;

            if (aLength > bLength)
            {
                longest  = a;
                shortest = b;
            }
            else
            {
                longest  = b;
                shortest = a;
            }

            int shortestLength = shortest.getHighestInnovationNumber();
            int longestLength  = longest.getHighestInnovationNumber();

            double disjoint = 0;
            double excess   = 0;

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

            for (int i = 0; i < longestLength; i++)
            {
                Synapse aa = longest.getSynapse(i);
                Synapse bb = shortest.getSynapse(i);

                if ((aa == null && bb != null) || (aa != null && bb == null))
                {
                    // only present in one of them

                    if (i <= shortestLength)
                    {
                        disjoint++;
                    }
                    else if (i > shortestLength)
                    {
                        excess++;
                    }
                }
                if (aa != null && bb != null)
                {
                    double distance = Math.Abs(aa.weight - bb.weight);
                    weights.Add(distance);
                }
            }

            double total = 0;
            double size  = 0;

            foreach (double w in weights)
            {
                total += w;
                size++;
            }

            double averageWeightDistance = total / size;
            double n  = longest.synapses.Count;
            double c1 = Config.DISTANCE_EXCESS_WEIGHT;
            double c2 = Config.DISTANCE_DISJOINT_WEIGHT;
            double c3 = Config.DISTANCE_WEIGHTS_WEIGHT;

            double d = ((c1 * excess) / n) + ((c2 * disjoint) / n) + (c3 * averageWeightDistance);

            return(d);
        }