Пример #1
0
        //public Axon AddAxon(Nuron input, double weight)
        //{
        //    if (input.Level > this.Level)
        //    {
        //        //swaps the nurons if the level is swaped
        //        return input.AddAxon(this, weight);
        //    }

        //    //enshures that the nurons are on diffrent levels
        //    if (input.Level == this.Level) throw new
        //    InvalidOperationException();

        //    //enshures that the nurons belong to the same network
        //    if (input.network != this.network) throw new
        //    InvalidOperationException();

        //    //calls upon the internal method
        //    return AddAxonInit(input, weight);
        //}

        #endregion ////////////////////////////////////////////////////////////////////

        #region Internal Methods...

        /// <summary>
        /// Connects the given input nuron to the current nuron with the
        /// given weight. Note that it dose not check the topology of the
        /// network before adding the axon, so care must be taken to avoid
        /// redundent connections. If a connection already exists between
        /// the two nurons, it returns that axon instead.
        /// </summary>
        /// <param name="input">Nuron to conect</param>
        /// <param name="weight">Weight of the connection</param>
        /// <returns>The axon between the nurons</returns>
        internal Axon AddAxonInit(NuronOld input, double weight)
        {
            ////enshures the nurons belong to the same network
            //if (network == null || network != input.network)
            //    throw new InvalidOperationException();

            //makes shure our parent network hasn't been disposed
            if (network == null)
            {
                throw new InvalidOperationException();
            }

            //sees if we alreay contain a link to the input
            Axon ax = GetAxon(input.Index);

            if (ax == null)
            {
                //obtains an index to the sorce and target
                int source = this.Index;
                int target = input.Index;

                //creates the axon and adds it to our list
                ax = new Axon(source, target, weight);
                inputs.Add(ax);
            }
            else
            {
                //sets the axons weight to our new weight
                ax.Weight = weight;
            }

            return(ax);
        }
Пример #2
0
        /// <summary>
        /// Compares the current genotype to the genotype of a diffrent
        /// nural net. The result is a positive real value that indicates
        /// how siimilar the genotypes are. This is tipicaly used to
        /// seperate a population of individules into species.
        /// </summary>
        /// <param name="other">Nural net for comparison</param>
        /// <returns>Mesure of similarity</returns>
        public double Compare(NetworkCPP other)
        {
            //used in computing the distance
            int    match    = 0;
            int    disjoint = 0;
            double wbar     = 0.0;

            //lists the axons in each of the networks
            var ittr1 = this.ListAxons();
            var ittr2 = other.ListAxons();

            foreach (Axon ax1 in ittr1)
            {
                //tries to find the matching axon
                Axon ax2 = other.FindMatch(ax1);

                if (ax2 != null)
                {
                    //computes the distance between the weights
                    double w1 = ax1.Weight;
                    double w2 = ax2.Weight;

                    wbar  += Math.Abs(w1 - w2);
                    match += 1;
                }
                else
                {
                    //counts the disjoint nodes
                    disjoint += 1;
                }
            }

            foreach (Axon ax1 in ittr2)
            {
                //only counts the missing disjoint edges
                Axon ax2 = other.FindMatch(ax1);
                if (ax2 == null)
                {
                    disjoint += 1;
                }
            }

            //determins the size of the larger network
            int size = Math.Max(this.Axons, other.Axons);

            size = (size > 20) ? size - 20 : 1;

            //couputes the distance for specisation
            double dist = (C0 * disjoint) / (double)size;

            dist += C1 * (wbar / (double)match);

            return(dist);
        }
Пример #3
0
        /// <summary>
        /// Helper method: Finds an axon in the curent network that matches a
        /// target axon from another network. If no sucth match can be found,
        /// it returns null instead.
        /// </summary>
        /// <param name="other">Target axon</param>
        /// <returns>A matching axon</returns>
        private Axon FindMatch(Axon other)
        {
            //first atempts to find the target nuron
            NuronOld n1 = nurons.GetValue(other.Target);

            if (n1 == null)
            {
                return(null);
            }

            //obtains the axon from the target
            return(n1.GetAxon(other.Source));
        }
Пример #4
0
        /// <summary>
        /// Expands the curent nural net, in place, by either inserting a
        /// new node along a pre-existing edge or creating a new edge. The
        /// probibility of either event occoring is determined by the
        /// existing topology.
        /// </summary>
        public void ExpandSelf()
        {
            NuronOld n1, n2;

            //generates a pair of random nurons
            bool test   = RandPair(out n1, out n2);
            Axon target = n2.GetAxon(n1.Index);

            if (test && target == null)
            {
                //creates a new axon between the nurons
                double weight = rng.RandGauss() * SDN;
                n2.AddAxonInit(n1, weight);
            }
            else if (test && !target.Enabled)
            {
                //reinitilises the axon with a new weight
                target.Weight  = rng.RandGauss() * SDN;
                target.Enabled = true;
            }
            else if ((n2.Level - n1.Level) > 3)
            {
                //disables the target edge
                double weight = target.Weight;
                target.Enabled = false;

                //creates a new node with a random funciton
                int     index = RandIndex();
                int     level = (n2.Level + n1.Level) / 2;
                ActFunc func  = RandFunc();

                //aborts the operation if we fail to insert
                if (index < 0)
                {
                    return;
                }

                //inserts the node into our data-structor
                NuronOld nx = new NuronOld(this, func, level, index);
                nurons.Add(index, nx);

                //adds axons to replace the missing axon
                nx.AddAxonInit(n1, 1.0);
                n2.AddAxonInit(nx, weight);
            }
        }
Пример #5
0
        /// <summary>
        /// Combines the genes of the curent nural net with the genes of
        /// another network to create a brand new offspring. The idea is
        /// that the child network will possess trates from both its
        /// parents, similar to sexual reproduction.
        /// </summary>
        /// <param name="rng">Random number generator</param>
        /// <param name="mate">Mate of the curent network</param>
        /// <returns>The child of both networks</returns>
        public NetworkCPP Combine(VRandom rng, NetworkCPP mate)
        {
            //makes a clone of the dominate parent
            NetworkCPP child = new NetworkCPP(rng, this);

            //determins weather or not to do liniar crossover
            bool   liniar = rng.RandBool(P_Linear);
            double a      = rng.NextDouble();

            //lists all the axons in the mate
            var axons = mate.ListAxons();

            foreach (Axon ax in axons)
            {
                //obtains the matching child axon
                Axon axc = child.FindMatch(ax);
                if (axc == null)
                {
                    continue;
                }

                if (liniar)
                {
                    //chooses a value between the two weights
                    double weight = axc.Weight * (1.0 - a);
                    axc.Weight = weight + (ax.Weight * a);
                }
                else
                {
                    //determins the new weight based on crossover
                    bool cross = rng.RandBool();
                    if (cross)
                    {
                        axc.Weight = ax.Weight;
                    }
                }

                //has a chance of enabling if either are disabled
                bool en = ax.Enabled && axc.Enabled;
                axc.Enabled = en || rng.RandBool(0.25);
            }

            return(child);
        }
Пример #6
0
        /// <summary>
        /// Creates a copy of a given nuron for a given network. All of the
        /// refrences to axons in the old network, now point to axons in
        /// the new network. All other values remain the same.
        /// </summary>
        /// <param name="network">The network containing this nuron</param>
        /// <param name="other">Another neuron to copy its values</param>
        internal NuronOld(NetworkCPP network, NuronOld other)
        {
            //sets the network refrence to the new network
            this.network = network;

            //copies the other vlaues
            func  = other.func;
            level = other.level;
            value = other.value;

            inputs = new VListArray <Axon>(other.inputs.Count);

            //makes a deep copy of the list of inputs
            foreach (Axon ax in other.inputs)
            {
                Axon clone = new Axon(ax);
                this.inputs.Add(clone);
            }
        }