Exemple #1
0
        /// <summary>
        /// Creates a prototype network, with the given number of inputs and
        /// outputs. The network starts out maximily connected with axons between
        /// each pair of input and output nurons. There are no hidden nurons.
        /// The weight of each axon is initialy set to one.
        /// </summary>
        /// <param name="inputs">Number of input nurons</param>
        /// <param name="outputs">Number of output nurons</param>
        public NetworkAuto(int inputs, int outputs)
        {
            ////initialises the tables for the nurons and axons
            //nurons = new TableOpen<Int32, Nuron>(256);
            //axons = new TableOpen<Int32, Axon>(1024);

            //initialises the tables for the nurons and axons
            nurons = new TableSystem <Int32, Nuron>(256);
            axons  = new TableSystem <Int32, Axon>(1024);

            //creates arrays to remember the inputs and outputs
            this.inputs  = new int[inputs];
            this.outputs = new int[outputs];

            //creates all the input nurons
            for (int i = 0; i < inputs; i++)
            {
                Nuron n = new Nuron(this, ActFunc.Input, i, 0);
                nurons.Add(n.Index, n);
                this.inputs[i] = n.Index; //i
            }

            //creates all the output nurons
            for (int i = 0; i < outputs; i++)
            {
                Nuron n = new Nuron(this, ActFunc.Sigmoid, MAX_ID - i, MAX_LV);
                nurons.Add(n.Index, n);
                this.outputs[i] = n.Index; //MAX_ID - i
            }

            //adds conecitons between all the nodes
            Initialise();
        }
Exemple #2
0
        /// <summary>
        /// Helper mehtod: Selects a pair of nurons at random from diffrent
        /// levels of the network. The nurons are always listed in order. It
        /// returns false if it was ubale to generate a valid pair.
        /// </summary>
        /// <param name="rng">A random number generator</param>
        /// <param name="n1">The lower level nuron</param>
        /// <param name="n2">The upper level nuron</param>
        /// <returns>True if a vaild pair was generated</returns>
        private bool GetRandomPair(VRandom rng, out Nuron n1, out Nuron n2)
        {
            //generates two random nurons
            n1 = GetRandomNuron(rng);
            n2 = GetRandomNuron(rng);

            int   count = 0;
            Nuron n3    = null;

            //keeps searching while the nurons are on the same level
            while (n1.Level == n2.Level && count < MAX_TRY)
            {
                n3 = GetRandomNuron(rng);
                n1 = n2;
                n2 = n3;
                count++;
            }

            //swaps the nurons if they are out of order
            if (n1.Level > n2.Level)
            {
                n3 = n1;
                n1 = n2;
                n2 = n3;
            }

            //indicates if we found a valid pair
            return(n1.Level != n2.Level);
        }
Exemple #3
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);
            }
        }
Exemple #4
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);
            }
        }
Exemple #5
0
 public void SetInput(Vector data)
 {
     //fills each of the input nurons with the vector data
     for (int i = 0; i < inputs.Length; i++)
     {
         Nuron n = nurons.GetValue(inputs[i]);
         n.Value = data.GetExtended(i);
         n.Prev  = n.Value;
     }
 }
Exemple #6
0
        public Vector ReadOutput()
        {
            //creates a new vector to hold the result
            Vector result = new Vector(outputs.Length);

            //copies the output nurons into the result vector
            for (int i = 0; i < outputs.Length; i++)
            {
                Nuron n = nurons.GetValue(outputs[i]);
                result[i] = n.Value;
            }

            //returns the result
            return(result);
        }
Exemple #7
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];
            }
        }
Exemple #8
0
        public void WriteOutputTo(Vector result)
        {
            //enshures that the result vector can hold the output
            if (result.Length != outputs.Length)
            {
                throw new ArgumentException
                          ("Reslut vector dose not match network topology.", "result");
            }

            //copies the output nurons into the result vector
            for (int i = 0; i < outputs.Length; i++)
            {
                Nuron n = nurons.GetValue(outputs[i]);
                result[i] = n.Value;
            }
        }
Exemple #9
0
        public void Propergate()
        {
            var ittr0 = nurons.ListItems();

            foreach (Nuron nx in ittr0)
            {
                //Skips input nurons
                if (nx.IsInput)
                {
                    continue;
                }

                //clears the value and updates the previous value
                nx.Prev  = nx.Value;
                nx.Value = 0.0;
            }

            var ittr1 = axons.ListItems();

            foreach (Axon ax in ittr1)
            {
                //skips disabled nurons
                if (!ax.Enabled)
                {
                    continue;
                }

                //obtains both nurons from the axon
                Nuron n1 = nurons.GetValue(ax.Source);
                Nuron n2 = nurons.GetValue(ax.Target);

                //updates the target based on the input
                n2.Value += (n1.Prev * ax.Weight);
            }

            var ittr2 = nurons.ListItems();

            foreach (Nuron nx in ittr2)
            {
                //activates each of the nurons
                nx.Activate();
            }
        }
Exemple #10
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;
            }
        }
Exemple #11
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);
                }
            }
        }
Exemple #12
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();
        }