コード例 #1
0
        public void Overwrite(NetworkAuto genome)
        {
            //NOTE: Need to assert that the inputs and outputs match

            this.axons.Clear();
            this.nurons.Clear();

            //used in itterating all the axons and nurons
            var g_axons  = genome.axons.ListItems();
            var g_nurons = genome.nurons.ListItems();

            foreach (Nuron n1 in g_nurons)
            {
                //nurons.Overwrite(n1.Index, n1);
                Nuron temp = new Nuron(this, n1);
                nurons.Add(temp.Index, temp);
            }

            foreach (Axon a1 in g_axons)
            {
                //axons.Overwrite(a1.Index, a1);
                Axon temp = new Axon(a1);
                axons.Add(temp.Index, temp);
            }
        }
コード例 #2
0
        /// <summary>
        /// Removes unused Nurons and Axons from the network, reducing the overall
        /// size of the network without effecting it's functionality.
        /// </summary>
        public void ReduceNetwork()
        {
            var ittr1  = axons.ListItems();
            var trash1 = new Stack <Axon>();

            foreach (Axon ax in ittr1)
            {
                if (ax.Enabled)
                {
                    continue;
                }
                else
                {
                    trash1.Push(ax);
                }
            }

            while (trash1.Count > 0)
            {
                Axon ax = trash1.Pop();
                axons.Remove(ax.Index);
            }

            var ittr2  = nurons.ListItems();
            var trash2 = new Stack <Nuron>();

            foreach (Nuron n in ittr2)
            {
                var  ittr3 = axons.ListItems();
                bool clear = false;

                foreach (Axon ax in ittr3)
                {
                    if (ax.Source == n.Index || ax.Target == n.Index)
                    {
                        clear = true;
                        break;
                    }
                }

                if (clear)
                {
                    continue;
                }
                else
                {
                    trash2.Push(n);
                }
            }

            while (trash2.Count > 0)
            {
                Nuron n = trash2.Pop();
                nurons.Remove(n.Index);
            }
        }
コード例 #3
0
        public double Compare(NetworkAuto genome)
        {
            //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.axons.ListItems();
            var ittr2 = genome.axons.ListItems();

            foreach (Axon ax1 in ittr1)
            {
                //tries to find the matching axon
                Axon ax2 = genome.axons.GetValue(ax1.Index);

                if (ax2 != null)
                {
                    //computes the distance bteween 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)
            {
                //counts the disjoint edges from the other network
                bool test = this.axons.HasKey(ax1.Index);
                if (!test)
                {
                    disjoint += 1;
                }
            }

            //determins the size of the larger network
            int size = Math.Max(this.NumAxons, genome.NumAxons);
            //size = (size > 20) ? size - 20 : 1;

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

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

            return(dist);
        }
コード例 #4
0
        public NetworkAuto(NetworkAuto other)
        {
            //copies the global settings
            this.recurent = other.recurent;

            //obtains the raw statistics of the opposing network
            int ninputs  = other.inputs.Length;
            int noutputs = other.outputs.Length;
            int nnurons  = other.nurons.Count;
            int naxons   = other.axons.Count;

            //makes tables large enough to hold the nurons and axons
            nurons = new TableSystem <Int32, Nuron>(nnurons);
            axons  = new TableSystem <Int32, Axon>(naxons);

            //dose the same for the inputs and outputs
            inputs  = new int[ninputs];
            outputs = new int[noutputs];

            //makes copies of all the nurons in the original network
            var ittr1 = other.nurons.ListItems();

            foreach (Nuron n in ittr1)
            {
                Nuron temp = new Nuron(this, n);
                nurons.Add(temp.Index, temp);
            }

            //makes copies of all the axons in the original network
            var ittr2 = other.axons.ListItems();

            foreach (Axon ax in ittr2)
            {
                Axon temp = new Axon(ax);
                axons.Add(temp.Index, temp);
            }

            //copies the input and output indicies
            for (int i = 0; i < inputs.Length; i++)
            {
                this.inputs[i] = other.inputs[i];
            }

            for (int i = 0; i < outputs.Length; i++)
            {
                this.outputs[i] = other.outputs[i];
            }
        }
コード例 #5
0
        //In this method we assume a standard mutation rate of 1.0;
        public void Mutate(VRandom rng, double rate)
        {
            //makes shure the rate is positive
            rate = Math.Abs(rate);

            double selector = rng.NextDouble();


            if (selector < P_EXPAND)
            {
                //expands the network
                Expand(rng);
            }
            else if (selector < P_TOGGEL)
            {
                Axon ax = GetRandomAxon(rng);

                if (ax.Enabled)
                {
                    //outright disables the nuron
                    ax.Enabled = false;
                }
                else
                {
                    //resets the neuron to a large weight
                    ax.Weight  = rng.RandGauss() * SD_NEW;
                    ax.Enabled = true;
                }
            }
            else
            {
                Axon ax = GetRandomAxon(rng);

                if (ax.Enabled)
                {
                    //permutes the weight by a small amount
                    double delta = rng.RandGauss() * SD_SHIFT;
                    ax.Weight = ax.Weight + delta;
                }
                else
                {
                    //resets the nuron to a small weight
                    double delta = rng.RandGauss() * SD_SHIFT;
                    ax.Weight  = delta;
                    ax.Enabled = true;
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Initalizes the network, adding axons between all the input and output
        /// nurons. Usualy this is done when the network is first instanciated.
        /// At first, the weights of all connections will be one. In order to get
        /// the network into a random state, you will need to call the Randomize
        /// function.
        /// </summary>
        private void Initialise()
        {
            //creates axons betwen all input-output pairs
            //and randomizes the coneciton weights

            for (int i = 0; i < inputs.Length; i++)
            {
                for (int j = 0; j < outputs.Length; j++)
                {
                    Axon ax = new Axon(inputs[i], outputs[j], 1.0);
                    axons.Overwrite(ax.Index, ax);

                    //We need to use the overwrite method here, incase Initialse
                    //has been called before, allowing for reinitializaiton
                }
            }
        }
コード例 #7
0
        private void Expand(VRandom rng)
        {
            Nuron n1, n2;

            //generates a pair of random nurons on diffrent levels
            bool pass = GetRandomPair(rng, out n1, out n2);

            if (!pass)
            {
                return;
            }

            //determins if this should be a recurent conneciton
            bool testrec = recurent;

            testrec = testrec && !n1.IsInput;
            testrec = testrec && rng.RandBool(P_Recur);

            if (testrec)
            {
                Nuron nx = n1;
                n1 = n2;
                n2 = nx;
            }

            //creates a temporary axon between the two nurons
            double w    = rng.RandGauss() * SD_NEW;
            Axon   temp = new Axon(n1.Index, n2.Index, w);

            //atempts to gain the actual axon if it exists
            Axon actual = axons.GetValue(temp.Index);

            if (actual == null)
            {
                //adds the new axon into the network
                axons.Add(temp.Index, temp);
            }
            else if (actual.Enabled == false)
            {
                //reneables the axon and updates it weight
                actual.Enabled = true;
                actual.Weight  = temp.Weight;
            }
            else
            {
                //determins if we are able to insert a new node
                int nid1 = GetRandomIndex(rng);
                if (nid1 < 0)
                {
                    return;
                }

                //sets the level of the new node in the middle
                if (Math.Abs(n1.Level - n2.Level) < 3)
                {
                    return;
                }
                int level = (n1.Level + n2.Level) / 2;

                //adds a new node to the network
                ActFunc act = GetRandomActivation(rng);
                Nuron   n3  = new Nuron(this, act, nid1, level);
                nurons.Add(n3.Index, n3);

                //inserts two new axons where the old one used to be
                int nid0 = actual.Source;
                int nid2 = actual.Target;

                //Axon ax1 = new Axon(nid0, nid1, actual.Weight);
                //Axon ax2 = new Axon(nid1, nid2, temp.Weight);

                Axon ax1 = new Axon(nid0, nid1, actual.Weight);
                Axon ax2 = new Axon(nid1, nid2, 1.0);

                //we use the overwitre comand because there may be hash collisions
                axons.Overwrite(ax1.Index, ax1);
                axons.Overwrite(ax2.Index, ax2);

                //deactivates the old axon
                actual.Enabled = false;
            }
        }
コード例 #8
0
        public void Crossover(VRandom rng, NetworkAuto genome)
        {
            //throw new NotImplementedException();

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

            //lists all the axons and nurons in the mate
            var ittr1 = genome.nurons.ListItems();
            var ittr2 = genome.axons.ListItems();

            foreach (Nuron n in ittr1)
            {
                //obtains the matching child nuron
                Nuron nc = nurons.GetValue(n.Index);

                if (nc == null)
                {
                    //adds the missing nuron
                    nc = new Nuron(this, n);
                    nurons.Add(nc.Index, nc);
                }
                //else
                //{
                //    //determins the activation based on crossover
                //    bool cross = rng.RandBool();
                //    if (cross) nc.Func = n.Func;
                //}
            }

            foreach (Axon ax in ittr2)
            {
                //obtains the matching child axon
                Axon axc = axons.GetValue(ax.Index);

                if (axc == null)
                {
                    //adds the missing axon, but disabled
                    axc         = new Axon(ax);
                    axc.Enabled = false;
                    axons.Add(axc.Index, axc);
                }
                else
                {
                    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;
                        }
                    }

                    //if the axon is present in both networks, it has a
                    //strong chance of becoming enabled
                    bool en = ax.Enabled && axc.Enabled;
                    axc.Enabled = en || rng.RandBool(0.25);
                }
            }
        }
コード例 #9
0
        public void Overwrite2(NetworkAuto genome)
        {
            //used in itterating all the axons and nurons
            var g_axons  = genome.axons.ListItems();
            var g_nurons = genome.nurons.ListItems();

            foreach (Nuron n1 in g_nurons)
            {
                //tries to find the matching nuron in the current network
                Nuron n0 = nurons.GetValue(n1.Index);

                if (n0 != null)
                {
                    ////copies the genome data if it finds a match
                    //n0.Func = n1.Func;
                }
                else
                {
                    //creates a copy of the first nurons and adds it
                    n0 = new Nuron(this, n1);
                    nurons.Add(n0.Index, n0);
                }
            }

            foreach (Axon a1 in g_axons)
            {
                //tries to find the matching axon in the current network
                Axon a0 = axons.GetValue(a1.Index);

                if (a0 != null)
                {
                    //copies the genome data if it finds a match
                    a0.Weight  = a1.Weight;
                    a0.Enabled = a1.Enabled;
                }
                else
                {
                    //creates a copy of the first axon and adds it
                    a0 = new Axon(a1);
                    axons.Add(a0.Index, a0);
                }
            }


            ////////////////////////////////////////////////////////////////////


            //used to clean up the remaining Axons
            int count1 = genome.axons.Count - axons.Count;

            count1 = Math.Min(count1, 0) + 8;
            var trash1 = new DequeArray <Axon>(count1);
            var ittr1  = axons.ListItems();

            //marks missing Axons for deletion
            foreach (Axon a in ittr1)
            {
                if (genome.axons.HasKey(a.Index))
                {
                    continue;
                }
                else
                {
                    trash1.PushFront(a);
                }
            }

            //deletes the missing Axons
            while (!trash1.Empty)
            {
                Axon del = trash1.PopFront();
                axons.Remove(del.Index);
            }

            //used to clean up the remaining Nurons
            int count2 = genome.nurons.Count - nurons.Count;

            count2 = Math.Min(count2, 0) + 8;
            var trash2 = new DequeArray <Nuron>(count2);
            var ittr2  = nurons.ListItems();

            //marks missing Nurons for deletion
            foreach (Nuron n in ittr2)
            {
                if (genome.nurons.HasKey(n.Index))
                {
                    continue;
                }
                else
                {
                    trash2.PushFront(n);
                }
            }

            //deletes the missing Nurons
            while (!trash2.Empty)
            {
                Nuron del = trash2.PopFront();
                nurons.Remove(del.Index);
                del.ClearData();
            }

            trash1.Dispose();
            trash2.Dispose();
        }