public void RunBest()
        {
            Time.timeScale = 1;

            NeatGenome genome = null;

            // Try to load the genome from the XML document.
            try
            {
                using (XmlReader xr = XmlReader.Create(champFileSavePath))
                    genome = NeatGenomeXmlIO.ReadCompleteGenomeList(xr, false, (NeatGenomeFactory)experiment.CreateGenomeFactory())[0];
            }
            catch (Exception e1)
            {
                Debug.Log(" Error loading genome from file! Loading aborted.\n" + e1.Message);
                return;
            }

            // Genomedecoders convert genomes to pheonomes
            var genomeDecoder = experiment.CreateGenomeDecoder();

            // Decode into a network
            var phenome = genomeDecoder.Decode(genome);

            GameObject obj = Instantiate(Unit, transform.position, Unit.transform.rotation) as GameObject;

            obj.AddComponent <Creature>();
            UnitController controller = obj.GetComponent <UnitController>();

            ControllerMap.Add(phenome, controller);

            controller.Activate(phenome);
        }
Exemple #2
0
    public void RunBest()
    {
        Time.timeScale = 1;

        NeatGenome genome = null;


        // Try to load the genome from the XML document.
        try
        {
            using (XmlReader xr = XmlReader.Create(champFileSavePath))
                genome = NeatGenomeXmlIO.ReadCompleteGenomeList(xr, false, (NeatGenomeFactory)experiment.CreateGenomeFactory())[0];
        }
        catch (Exception e1)
        {
            // print(champFileLoadPath + " Error loading genome from file!\nLoading aborted.\n"
            //						  + e1.Message + "\nJoe: " + champFileLoadPath);
            return;
        }

        // Get a genome decoder that can convert genomes to phenomes.
        var genomeDecoder = experiment.CreateGenomeDecoder();

        // Decode the genome into a phenome (neural network).
        var phenome = genomeDecoder.Decode(genome);

        GameObject     obj        = Instantiate(Unit, Unit.transform.position, Unit.transform.rotation) as GameObject;
        UnitController controller = obj.GetComponent <UnitController>();

        ControllerMap.Add(phenome, controller);

        controller.Activate(phenome);
    }
Exemple #3
0
        /// <summary>
        /// Refresh/update the view with the provided genome.
        /// </summary>
        public override void RefreshView(object genome)
        {
            NeatGenome neatGenome = genome as NeatGenome;

            if (null == neatGenome)
            {
                return;
            }

            // Decode genome.
            IBlackBox box = _genomeDecoder.Decode(neatGenome);

            // Update plot points.
            double x = _xMin;

            for (int i = 0; i < _sampleCount; i++, x += _xIncr)
            {
                box.ResetState();
                box.InputSignalArray[0] = x;
                box.Activate();
                _plotPointListResponse[i].Y = box.OutputSignalArray[0];
            }

            // Trigger graph to redraw.
            zed.AxisChange();
            Refresh();
        }
        private bool TryGetConnectionInner(NeatGenome <T> parent, out DirectedConnection conn, out int insertIdx)
        {
            int inputCount  = _metaNeatGenome.InputNodeCount;
            int outputCount = _metaNeatGenome.OutputNodeCount;
            int hiddenCount = parent.HiddenNodeIdArray.Length;

            // Select a source node at random.
            // Note. this can be any node (input, output or hidden).
            int totalNodeCount = parent.MetaNeatGenome.InputOutputNodeCount + hiddenCount;
            int srcId          = GetNodeIdFromIndex(parent, _rng.Next(totalNodeCount));

            // Select a target node at random.
            // Note. This cannot be an input node (so must be a hidden or output node).
            int outputHiddenCount = outputCount + hiddenCount;
            int tgtId             = GetNodeIdFromIndex(parent, inputCount + _rng.Next(outputHiddenCount));

            // Test if the chosen connection already exists.
            // Note. Connection genes are always sorted by sourceId then targetId, so we can use a binary search to
            // find an existing connection in O(log(n)) time.
            conn = new DirectedConnection(srcId, tgtId);

            if ((insertIdx = Array.BinarySearch(parent.ConnectionGenes._connArr, conn)) < 0)
            {
                // The proposed new connection does not already exist, therefore we can use it.
                // Get the position in parent.ConnectionGeneArray that the new connection should be inserted at (to maintain sort order).
                insertIdx = ~insertIdx;
                return(true);
            }

            conn      = default(DirectedConnection);
            insertIdx = default(int);
            return(false);
        }
        public static GenomeList CreateGenomeListAddedInputs(NeatGenome seedGenome, int length, NeatParameters neatParameters, IdGenerator idGenerator)
        {
            //Build the list.
            GenomeList genomeList = new GenomeList();

            // Use the seed directly just once.
            NeatGenome newGenome = new NeatGenome(seedGenome, idGenerator.NextGenomeId);

            //genomeList.Add(newGenome);

            // For the remainder we alter the weights.
            for (int i = 0; i < length; i++)
            {
                newGenome = new NeatGenome(seedGenome, idGenerator.NextGenomeId);

                // Reset the connection weights
                foreach (ConnectionGene connectionGene in newGenome.ConnectionGeneList)
                {
                    connectionGene.Weight = (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0;
                }
                newGenome.ConnectionGeneList.Add(new ConnectionGene(idGenerator.NextInnovationId, 5, newGenome.NeuronGeneList[Utilities.Next(newGenome.NeuronGeneList.Count - 7) + 7].InnovationId, (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0));
                newGenome.ConnectionGeneList.Add(new ConnectionGene(idGenerator.NextInnovationId, 6, newGenome.NeuronGeneList[Utilities.Next(newGenome.NeuronGeneList.Count - 7) + 7].InnovationId, (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0));
                genomeList.Add(newGenome);
            }

            //

            return(genomeList);
        }
Exemple #6
0
        /// <summary>
        /// Gets the species with a centroid closest to the given genome.
        /// If multiple species are equally close then we return all of the those species.
        /// </summary>
        public static List <Species <T> > GetNearestSpeciesList <T>(
            NeatGenome <T> genome,
            Species <T>[] speciesArr,
            IDistanceMetric <T> distanceMetric)
            where T : struct
        {
            var nearestSpeciesList = new List <Species <T> >(4);

            nearestSpeciesList.Add(speciesArr[0]);
            double nearestDistance = distanceMetric.CalcDistance(genome.ConnectionGenes, speciesArr[0].Centroid);

            for (int i = 1; i < speciesArr.Length; i++)
            {
                double distance = distanceMetric.CalcDistance(genome.ConnectionGenes, speciesArr[i].Centroid);
                if (distance < nearestDistance)
                {
                    nearestSpeciesList.Clear();
                    nearestSpeciesList.Add(speciesArr[i]);
                    nearestDistance = distance;
                }
                else if (distance == nearestDistance)
                {
                    nearestSpeciesList.Add(speciesArr[i]);
                }
            }
            return(nearestSpeciesList);
        }
        private static void TestGenome(IGenomeDecoder<NeatGenome, IBlackBox> decoder, NeatGenome genome)
        {
            // Decode the genome into a phenome (neural network).
            IBlackBox phenome = decoder.Decode(genome);

            List<string> lines = new List<string>();

            double v = 0f;
            while (v < Math.PI * 2f)
            {
                phenome.ResetState();

                phenome.InputSignalArray[0] = v;

                phenome.Activate();

                double result = phenome.OutputSignalArray[0];

                lines.Add(string.Format("{0}\t{1}", v, result));

                v += 0.1d;
            }

            System.IO.File.WriteAllLines(@"output.csv", lines);
        }
Exemple #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="genome"></param>
        /// <param name="activationFn">Not strictly part of a genome. But it is useful to document which function
        /// the genome is supposed to run against when decoded into a network.</param>
        public static void Write(XmlNode parentNode, NeatGenome genome, IActivationFunction activationFn)
        {
            //----- Start writing. Create document root node.
            XmlElement xmlGenome = XmlUtilities.AddElement(parentNode, "genome");

            XmlUtilities.AddAttribute(xmlGenome, "id", genome.GenomeId.ToString());
            XmlUtilities.AddAttribute(xmlGenome, "species-id", genome.SpeciesId.ToString());
            XmlUtilities.AddAttribute(xmlGenome, "age", genome.GenomeAge.ToString());
            XmlUtilities.AddAttribute(xmlGenome, "fitness", genome.Fitness.ToString("0.00"));
            XmlUtilities.AddAttribute(xmlGenome, "objective-fitness", genome.ObjectiveFitness.ToString("0.00"));
            XmlUtilities.AddAttribute(xmlGenome, "activation-fn-id", activationFn.FunctionId);

            //----- Write neurons.
            XmlElement xmlNeurons = XmlUtilities.AddElement(xmlGenome, "neurons");

            foreach (NeuronGene neuronGene in genome.NeuronGeneList)
            {
                WriteNeuron(xmlNeurons, neuronGene);
            }

            //----- Write Connections.
            XmlElement xmlConnections = XmlUtilities.AddElement(xmlGenome, "connections");

            foreach (ConnectionGene connectionGene in genome.ConnectionGeneList)
            {
                WriteConnectionGene(xmlConnections, connectionGene);
            }
        }
        public static GenomeList CreateGenomeList(Population seedPopulation, int length, NeatParameters neatParameters, IdGenerator idGenerator)
        {
            //Build the list.
            GenomeList genomeList = new GenomeList();
            int        seedIdx    = 0;

            for (int i = 0; i < length; i++)
            {
                NeatGenome newGenome = new NeatGenome((NeatGenome)seedPopulation.GenomeList[seedIdx], idGenerator.NextGenomeId);

                // Reset the connection weights
                foreach (ConnectionGene connectionGene in newGenome.ConnectionGeneList)
                {
                    connectionGene.Weight = (Utilities.NextDouble() * neatParameters.connectionWeightRange) - neatParameters.connectionWeightRange / 2.0;
                }

                genomeList.Add(newGenome);

                if (++seedIdx >= seedPopulation.GenomeList.Count)
                {                       // Back to first genome.
                    seedIdx = 0;
                }
            }
            return(genomeList);
        }
Exemple #10
0
    public void GenerateMesh(NeatGenome genome)
    {
        // Perform analysis
        AcyclicNetworkDepthAnalysis depthAnalysis = new AcyclicNetworkDepthAnalysis();
        NetworkDepthInfo            depthInfo     = depthAnalysis.CalculateNodeDepths(genome);
        int maxDepth = depthInfo._networkDepth;

        int[] nodesPerDepthLevel = new int[maxDepth];
        Dictionary <int, List <int> > nodesByDepth = new Dictionary <int, List <int> >();
        Dictionary <uint, int>        nodeIdxById  = new Dictionary <uint, int>();

        int mostNodesPerLayer = 0;

        for (int i = 0; i < genome.NodeList.Count; i++)
        {
            int        depth = depthInfo._nodeDepthArr[i];
            List <int> nodes;
            if (!nodesByDepth.TryGetValue(depth, out nodes))
            {
                nodes = new List <int>();
                nodesByDepth.Add(depth, nodes);
            }
            nodes.Add(i);
            mostNodesPerLayer = Mathf.Max(++nodesPerDepthLevel[depth], mostNodesPerLayer);
        }

        List <Vector3> vertices;
        var            neuronsMesh = GenerateNeuronsMesh(genome, nodeIdxById, maxDepth, mostNodesPerLayer, nodesByDepth, out vertices);

        neuronObject.GetComponent <MeshFilter>().mesh = neuronsMesh;

        var connectionMesh = GenerateConnectionsMesh(genome, nodeIdxById, vertices);

        connectionObject.GetComponent <MeshFilter>().mesh = connectionMesh;
    }
Exemple #11
0
    private Mesh GenerateConnectionsMesh(NeatGenome genome, Dictionary <uint, int> nodeIdxById, List <Vector3> nodeVertices)
    {
        Mesh           mesh         = new Mesh();
        List <Vector3> vertices     = new List <Vector3>();
        List <Color>   colors       = new List <Color>();
        List <int>     pointIndices = new List <int>();

        // Connections
        int idx = 0;

        foreach (var connection in genome.ConnectionList)
        {
            int sourceIdx = nodeIdxById[connection.SourceNodeId];
            int targetIdx = nodeIdxById[connection.TargetNodeId];

            var sourcePos = nodeVertices[sourceIdx];
            var targetPos = nodeVertices[targetIdx];

            vertices.Add(new Vector3((float)connection.Weight, 0, 0));
            colors.Add(new Color(sourcePos.x, sourcePos.y, targetPos.x, targetPos.y));
            pointIndices.Add(idx++);

            //Debug.Log($"[{genome.Id}] {connection.SourceNodeId} - {connection.TargetNodeId}: {connection.Weight}");
        }

        mesh.subMeshCount = 1;
        mesh.SetVertices(vertices);
        mesh.SetColors(colors);
        mesh.SetIndices(pointIndices.ToArray(), MeshTopology.Points, 0);
        return(mesh);
    }
Exemple #12
0
    public static IBlackBox LoadBrain(string filePath, INeatExperiment experiment)
    {
        NeatGenome genome = null;


        // Try to load the genome from the XML document.
        try
        {
            using (XmlReader xr = XmlReader.Create(filePath))
                genome = NeatGenomeXmlIO.ReadCompleteGenomeList(xr, false, (NeatGenomeFactory)experiment.CreateGenomeFactory())[0];
        }
        catch (Exception e1)
        {
            print(filePath + " Error loading genome from file!\nLoading aborted.\n"
                  + e1.Message + "\nJoe: " + filePath);
            return(null);
        }

        // Get a genome decoder that can convert genomes to phenomes.
        var genomeDecoder = experiment.CreateGenomeDecoder();

        // Decode the genome into a phenome (neural network).
        var phenome = genomeDecoder.Decode(genome);

        return(phenome);
    }
Exemple #13
0
    private NeatGenome loadGenome(string filename)
    {
        NeatGenome genome = null;

        DirectoryInfo dir = new DirectoryInfo(Application.persistentDataPath + string.Format("/{0}", folder_prefix));

        if (dir.Exists)
        {
            FileInfo[] info = dir.GetFiles(filename + ".xml");
            print(info.Length);
            foreach (FileInfo f in info)
            {
                try {
                    using (XmlReader xr = XmlReader.Create(Application.persistentDataPath + string.Format("/{0}/{1}", folder_prefix, f.Name)))
                        genome = NeatGenomeXmlIO.ReadCompleteGenomeList(xr, false, (NeatGenomeFactory)experiment.CreateGenomeFactory()) [0];
                } catch (Exception e1) {
                    print(" Error loading genome from file!\nLoading aborted.\n" + e1.Message);
                    continue;
                }
            }
//				Debug.Log ("Filled map with " + map + " elites.");
//			}
        }



        return(genome);
    }
Exemple #14
0
        private static void Backprop(NeatGenome genome, IGenomeDecoder<NeatGenome, IBlackBox> decoder, double learningRate)
        {
            var phenome = decoder.Decode(genome);

            var network = (FastCyclicNetwork)phenome;
            network.Momentum = 0;
            network.BackpropLearningRate = learningRate;

            //Console.WriteLine("Weights Before:");
            //PrintWeights(network);
            //Console.WriteLine();

            network.Train(new double[] { 0.3, 0.3 }, new double[] { 0.9 });

            Console.WriteLine("Weights:");
            PrintWeights(network);
            Console.WriteLine();

            network.Train(new double[] { 0.3, 0.3 }, new double[] { 0.9 });

            Console.WriteLine("Weights:");
            PrintWeights(network);
            Console.WriteLine();

        }
Exemple #15
0
        private NeatGenome <double> CreateGenome1(MetaNeatGenome <double> metaNeatGenome)
        {
            var genomeBuilder = NeatGenomeBuilderFactory <double> .Create(metaNeatGenome);

            // Define a genome that matches the one defined in example1.genome.
            var connGenes = new ConnectionGenes <double>(12);

            connGenes[0]  = (0, 5, 0.5);
            connGenes[1]  = (0, 7, 0.7);
            connGenes[2]  = (0, 3, 0.3);
            connGenes[3]  = (1, 5, 1.5);
            connGenes[4]  = (1, 7, 1.7);
            connGenes[5]  = (1, 3, 1.3);
            connGenes[6]  = (1, 6, 1.6);
            connGenes[7]  = (1, 8, 1.8);
            connGenes[8]  = (1, 4, 1.4);
            connGenes[9]  = (2, 6, 2.6);
            connGenes[10] = (2, 8, 2.8);
            connGenes[11] = (2, 4, 2.4);

            // Ensure the connections are sorted correctly.
            connGenes.Sort();

            // Wrap in a genome.
            NeatGenome <double> genome = genomeBuilder.Create(0, 0, connGenes);

            return(genome);
        }
Exemple #16
0
    public void SaveAndLoadGenome()
    {
        var metaNeatGenome = new MetaNeatGenome <double>(3, 2, true, new ReLU());
        var genomeBuilder  = NeatGenomeBuilderFactory <double> .Create(metaNeatGenome);

        // Simple acyclic graph.
        var connGenes = new ConnectionGenes <double>(6);

        connGenes[0] = (0, 3, 0.123);
        connGenes[1] = (1, 3, 1.234);
        connGenes[2] = (2, 3, -0.5835);
        connGenes[3] = (2, 4, 5.123456789);
        connGenes[4] = (2, 5, 2.5);
        connGenes[5] = (5, 4, 5.4);

        // Wrap in a genome.
        NeatGenome <double> genome = genomeBuilder.Create(0, 0, connGenes);

        // Create a memory stream to save the genome into.
        using (MemoryStream ms = new(1024))
        {
            // Save the genome.
            NeatGenomeSaver <double> .Save(genome, ms);

            // Load the genome.
            ms.Position = 0;
            NeatGenomeLoader <double> loader       = NeatGenomeLoaderFactory.CreateLoaderDouble(metaNeatGenome);
            NeatGenome <double>       genomeLoaded = loader.Load(ms);

            // Compare the original genome with the loaded genome.
            IOTestUtils.CompareGenomes(genome, genomeLoaded);
        }
    }
        /// <param name="activationFn">Not strictly part of a genome. But it is useful to document which function
        /// the genome is supposed to run against when decoded into a network.</param>
        public static void Write(XmlNode parentNode, NeatGenome genome, IActivationFunction activationFn)
        {
            //----- Start writing. Create document root node.
            XmlElement xmlGenome = XmlUtilities.AddElement(parentNode, "genome");
            XmlUtilities.AddAttribute(xmlGenome, "id", genome.GenomeId.ToString());
            XmlUtilities.AddAttribute(xmlGenome, "species-id", genome.SpeciesId.ToString());
            XmlUtilities.AddAttribute(xmlGenome, "age", genome.GenomeAge.ToString());
            XmlUtilities.AddAttribute(xmlGenome, "fitness", genome.Fitness.ToString("0.00"));
            XmlUtilities.AddAttribute(xmlGenome, "activation-fn-id", activationFn.FunctionId);

            //----- Write neurons.
            XmlElement xmlNeurons = XmlUtilities.AddElement(xmlGenome, "neurons");
            foreach(NeuronGene neuronGene in genome.NeuronGeneList)
                WriteNeuron(xmlNeurons, neuronGene);

            //----- Write modules.
            XmlElement xmlModules = XmlUtilities.AddElement(xmlGenome, "modules");
            foreach (ModuleGene moduleGene in genome.ModuleGeneList)
                WriteModule(xmlModules, moduleGene);

            //----- Write Connections.
            XmlElement xmlConnections = XmlUtilities.AddElement(xmlGenome, "connections");
            foreach(ConnectionGene connectionGene in genome.ConnectionGeneList)
                WriteConnectionGene(xmlConnections, connectionGene);

            //----- Write beahavior
            if(genome.Behavior!=null)
            {
                if(genome.Behavior.behaviorList!=null)
                {
                    XmlElement xmlBehavior = XmlUtilities.AddElement(xmlGenome, "behavior");
                    WriteBehavior(xmlBehavior,genome.Behavior);
                }
            }
        }
Exemple #18
0
        private bool TryGetConnectionInner(NeatGenome <T> parent, out DirectedConnection conn, out int insertIdx)
        {
            int inputCount  = _metaNeatGenome.InputNodeCount;
            int outputCount = _metaNeatGenome.OutputNodeCount;
            int hiddenCount = parent.HiddenNodeIdArray.Length;

            // Select a source node at random.

            // Note. Valid source nodes are input and hidden nodes. Output nodes are not source node candidates
            // for acyclic nets, because that can prevent future connections from targeting the output if it would
            // create a cycle.
            int inputHiddenCount = inputCount + hiddenCount;
            int srcIdx           = _rng.Next(inputHiddenCount);

            if (srcIdx >= inputCount)
            {
                srcIdx += outputCount;
            }
            int srcId = GetNodeIdFromIndex(parent, srcIdx);

            // Select a target node at random.
            // Note. Valid target nodes are all hidden and output nodes (cannot be an input node).
            int outputHiddenCount = outputCount + hiddenCount;
            int tgtId             = GetNodeIdFromIndex(parent, inputCount + _rng.Next(outputHiddenCount));;

            // Test for simplest cyclic connectivity - node connects to itself.
            if (srcId == tgtId)
            {
                conn      = default(DirectedConnection);
                insertIdx = default(int);
                return(false);
            }

            // Test if the chosen connection already exists.
            // Note. Connection genes are always sorted by sourceId then targetId, so we can use a binary search to
            // find an existing connection in O(log(n)) time.
            conn = new DirectedConnection(srcId, tgtId);

            if ((insertIdx = Array.BinarySearch(parent.ConnectionGenes._connArr, conn)) >= 0)
            {
                // The proposed new connection already exists.
                conn      = default(DirectedConnection);
                insertIdx = default(int);
                return(false);
            }

            // Test if the connection will form a cycle in the wider network.
            int totalNodeCount = _metaNeatGenome.InputOutputNodeCount + hiddenCount;

            if (_cyclicTest.IsConnectionCyclic(parent.ConnectionGenes._connArr, parent.NodeIndexByIdMap, totalNodeCount, conn))
            {
                conn      = default(DirectedConnection);
                insertIdx = default(int);
                return(false);
            }

            // Get the position in parent.ConnectionGeneArray that the new connection should be inserted at (to maintain sort order).
            insertIdx = ~insertIdx;
            return(true);
        }
        public void TestAddNode3()
        {
            var pop           = CreateNeatPopulation();
            var genomeBuilder = NeatGenomeBuilderFactory <double> .Create(pop.MetaNeatGenome);

            var genome = pop.GenomeList[0];

            var strategy = new AddNodeStrategy <double>(
                pop.MetaNeatGenome, genomeBuilder,
                pop.GenomeIdSeq, pop.InnovationIdSeq, pop.GenerationSeq,
                pop.AddedNodeBuffer);

            IRandomSource rng = RandomDefaults.CreateRandomSource();

            CircularBuffer <NeatGenome <double> > genomeRing = new CircularBuffer <NeatGenome <double> >(10);

            genomeRing.Enqueue(genome);

            for (int i = 0; i < 5000; i++)
            {
                NeatGenome <double> childGenome = CreateAndTestChildGenome(genome, strategy, rng);

                // Add the new child genome to the ring.
                genomeRing.Enqueue(childGenome);

                // Take the genome at the tail of the ring for the next parent.
                genome = genomeRing[0];
            }
        }
        public void calcFitness(string genomeFile, int type)
        {
            XmlDocument doc = new XmlDocument();

            doc.Load(genomeFile);
            NeatGenome genome = XmlNeatGenomeReaderStatic.Read(doc);

            INetworkEvaluator eval;

            if (type == 0)
            {
                eval = new CTRNNNetworkEvaluator(4, 12, 12);
            }
            else if (type == 1)
            {
                eval = new SUPGNetworkEvaluator(4, 12, 12);
            }
            else
            {
                doClune = true;
                eval    = new CluneNetworkEvaluator(20, 20, 20);
            }

            var tempNet = genome.Decode(null);

            MessageBox.Show(eval.threadSafeEvaluateNetwork(tempNet)[0].ToString());
        }
Exemple #21
0
        private void RedrawGraph(NeatGenome genome)
        {
            IBlackBox box = _experiment.GetBlackBox(genome);

            Color trueColor  = panPlot.TrueColor;
            Color falseColor = panPlot.FalseColor;

            var samples = Enumerable.Range(0, 1000).
                          Select(o =>
            {
                Vector3D pos = Math3D.GetRandomVector(new Vector3D(0, 0, 0), new Vector3D(1, 1, 1));

                box.ResetState();

                //box.InputSignalArray.CopyFrom()
                box.InputSignalArray[0] = pos.X;
                box.InputSignalArray[1] = pos.Y;
                box.InputSignalArray[2] = pos.Z;

                box.Activate();

                double percent = box.OutputSignalArray[0];

                Color color = UtilityWPF.AlphaBlend(trueColor, falseColor, percent);

                return(Tuple.Create(pos.ToPoint(), color));
            });

            panPlot.ClearFrame();
            panPlot.AddDots(samples, .01, false);
        }
        /// <summary>
        /// Determine the set of hidden node IDs that have been deleted as a result of a connection deletion.
        /// I.e. a node only exists if a connection connects to it, therefore if there are no other connections
        /// referring to a node then it has been deleted, with the exception of input and output nodes that
        /// always exist.
        /// </summary>
        private static (int?, int?) GetDeletedNodeIds(
            NeatGenome <T> parent, int deleteIdx,
            DirectedConnection[] childConnArr)
        {
            // Get the two node IDs referred to by the deleted connection.
            int?nodeId1 = parent.ConnectionGenes._connArr[deleteIdx].SourceId;
            int?nodeId2 = parent.ConnectionGenes._connArr[deleteIdx].TargetId;

            // Set IDs to null for input/output nodes (these nodes are fixed and therefore cannot be deleted).
            // Also, for cyclic networks nodeId1 and 2 could refer to the same node (a cyclic connection on the same node), if
            // so then we don't need to set nodeId2.
            if (nodeId1.Value < parent.MetaNeatGenome.InputOutputNodeCount)
            {
                nodeId1 = null;
            }

            if (nodeId2.Value < parent.MetaNeatGenome.InputOutputNodeCount || nodeId1 == nodeId2)
            {
                nodeId2 = null;
            }

            if (!nodeId1.HasValue && !nodeId2.HasValue)
            {
                return(null, null);
            }

            if (!nodeId1.HasValue)
            {
                // 'Shuffle up' nodeId2 into nodeId1.
                nodeId1 = nodeId2;
                nodeId2 = null;
            }

            if (!nodeId2.HasValue)
            {
                if (!IsNodeConnectedTo(childConnArr, nodeId1 !.Value))
                {
                    return(nodeId1.Value, null);
                }
                return(null, null);
            }

            (bool, bool)isConnectedTuple = AreNodesConnectedTo(childConnArr, nodeId1 !.Value, nodeId2.Value);
            if (!isConnectedTuple.Item1 && !isConnectedTuple.Item2)
            {
                return(nodeId1.Value, nodeId2.Value);
            }

            if (!isConnectedTuple.Item1)
            {
                return(nodeId1.Value, null);
            }

            if (!isConnectedTuple.Item2)
            {
                return(nodeId2.Value, null);
            }

            return(null, null);
        }
Exemple #23
0
        public void SetBrain(INetwork network, bool useSUPG = false, NeatGenome genome = null, INetwork cppn = null, int[] triggerMap = null)
        {
            if (useSUPG)
            {
                supgOutputs = new float[network.TotalNeuronCount /*- (network.InputNeuronCount + network.OutputNeuronCount)*/, wavelength]; // need at least as many rows as the number of hidden neurons
                // set all supgOutputs to min value to signal they have not been cached yet
                for (int i = 0; i < network.TotalNeuronCount /*- (network.InputNeuronCount + network.OutputNeuronCount)*/; i++)
                {
                    for (int j = 0; j < wavelength; j++)
                    {
                        supgOutputs[i, j] = float.MinValue;
                    }
                }
            }

            this.network    = network;
            this.useSUPG    = useSUPG;
            this.genome     = genome;
            this.cppn       = cppn;
            this.triggerMap = triggerMap;
            bool[] useSUPGArray = new bool[genome.NeuronGeneList.Count];
            useSUPGArray[7] = true;
            useSUPGArray[8] = true;

            if (useSUPG)
            {
                ((FloatFastConcurrentNetwork)network).UseSUPG      = false;
                ((FloatFastConcurrentNetwork)network).useSUPGArray = useSUPGArray;
            }
            brain = network;
        }
Exemple #24
0
 public RobotIndividual(Robot robot, Individual[] parents)
 {
     Robot           = robot;
     Genome          = robot.Genome;
     Parents         = parents;
     _distanceMetric = new EuclideanDistanceMetric();
 }
Exemple #25
0
    private NeatGenome <T> CreateGenomeInner(
        NeatGenome <T> parent1,
        NeatGenome <T> parent2,
        IRandomSource rng)
    {
        // Resolve a flag that determines if *all* disjoint genes from the secondary parent will be included in the child genome, or not.
        // This approach is from SharpNEAT v2.x and is preserved to act as baseline in v4.x, but better strategies may exist.
        bool includeSecondaryParentGene = DiscreteDistribution.SampleBernoulli(rng, _secondaryParentGeneProbability);

        // Enumerate over the connection genes in both parents.
        foreach (var geneIndexPair in EnumerateParentGenes(parent1.ConnectionGenes, parent2.ConnectionGenes))
        {
            // Create a connection gene based on the current position in both parents.
            ConnectionGene <T>?connGene = CreateConnectionGene(
                parent1.ConnectionGenes, parent2.ConnectionGenes,
                geneIndexPair.Item1, geneIndexPair.Item2,
                includeSecondaryParentGene, rng);

            if (connGene.HasValue)
            {   // Attempt to add the gene to the child genome we are building.
                _connGeneListBuilder.TryAddGene(connGene.Value);
            }
        }

        // Convert the genes to the structure required by NeatGenome.
        ConnectionGenes <T> connGenes = _connGeneListBuilder.ToConnectionGenes();

        // Create and return a new genome.
        return(_genomeBuilder.Create(
                   _genomeIdSeq.Next(),
                   _generationSeq.Peek,
                   connGenes));
    }
Exemple #26
0
        /// <summary>
        /// Create a new child genome from a given parent genome.
        /// </summary>
        /// <param name="parent">The parent genome.</param>
        /// <param name="rng">Random source.</param>
        /// <returns>A new child genome.</returns>
        public NeatGenome <T> CreateChildGenome(NeatGenome <T> parent, IRandomSource rng)
        {
            // Clone the parent's connection weight array.
            var weightArr = (T[])parent.ConnectionGenes._weightArr.Clone();

            // Apply mutation to the connection weights.
            _weightMutationScheme.MutateWeights(weightArr, rng);

            // Create the child genome's ConnectionGenes object.
            // Note. The parent genome's connection arrays are re-used; these remain unchanged because we are mutating
            // connection *weights* only, so we can avoid the cost of cloning these arrays.
            var connGenes = new ConnectionGenes <T>(
                parent.ConnectionGenes._connArr,
                weightArr);

            // Create and return a new genome.
            // Note. The parent's ConnectionIndexArray and HiddenNodeIdArray can be re-used here because the new genome
            // has the same set of connections (same neural net structure).
            return(_genomeBuilder.Create(
                       _genomeIdSeq.Next(),
                       _generationSeq.Peek,
                       connGenes,
                       parent.HiddenNodeIdArray,
                       parent.NodeIndexByIdMap,
                       parent.DirectedGraph,
                       parent.ConnectionIndexMap));
        }
 /// <summary>
 /// Create and return a NeatEvolutionAlgorithm with a single seed genome.
 /// </summary>
 public NeatEvolutionAlgorithm <NeatGenome> CreateEvolutionAlgorithm(NeatGenome seed)
 {
     // Create evolution algorithm.
     return(CreateEvolutionAlgorithm(_populationSize, seed.BirthGeneration, new List <NeatGenome> {
         seed
     }));
 }
Exemple #28
0
    /// <summary>
    ///  Creates an instance of the current champion
    /// </summary>
    public void RunBest()
    {
        champRunning = true;
        NeatGenome genome = LoadChampion();

        // Get a genome decoder that can convert genomes to phenomes.
        var genomeDecoder = experiment.CreateGenomeDecoder();
        // Decode the genome into a phenome (neural network).
        var phenome = genomeDecoder.Decode(genome);

        InstantiateCandidate(phenome);
        GameObject bestInstance = ControllerMap[phenome].gameObject;

        // Special tag so we can selectively actuate on these units.
        bestInstance.tag = "BestUnit";
        // Also removes the tag from child components (but no granchildren. This
        // is currently ok since these elements have no coliders and champions
        // are destroyed before entering evolution).
        // These cannot use "BestUnit" or we will be in trouble when we destroy
        // the unit!
        foreach (Transform child in bestInstance.transform)
        {
            child.gameObject.tag = "Untagged";
        }

        // This is called if we want the champions to be evaluated, mostly for
        // research reasons.
        if (false)
        {
            Coroutiner.StartCoroutine(EvaluateChamp(phenome));
        }
    }
    private void saveBestGenomeToolStripMenuItem_Click(object sender, EventArgs e)
    {
        // Get the current best genome.
        NeatGenome <double> bestGenome = _neatPop?.BestGenome;

        if (bestGenome is null)
        {
            return;
        }

        // Ask the user to select a file path and name to save to.
        string filepath = SelectFileToSave("Save best genome", "genome", "(*.genome)|*.genome");

        if (string.IsNullOrEmpty(filepath))
        {
            return;
        }

        // Save the genome.
        try
        {
            NeatGenomeSaver <double> .Save(bestGenome, filepath);
        }
        catch (Exception ex)
        {
            __log.ErrorFormat("Error saving genome; [{0}]", ex.Message);
        }
    }
Exemple #30
0
        /// <summary>
        /// Load a population from a zip archive file containing one or more genome file entries (with a .genome file extension).
        /// </summary>
        /// <param name="path">Path to the zip file to load.</param>
        /// <returns>A list of the loaded genomes.</returns>
        public List <NeatGenome <T> > LoadFromZipArchive(string path)
        {
            if (!File.Exists(path))
            {
                throw new IOException($"File does not exist [{path}]");
            }

            using (ZipArchive zipArchive = ZipFile.OpenRead(path))
            {
                // Alloc genome list with an appropriate capacity.
                List <NeatGenome <T> > genomeList = new List <NeatGenome <T> >(zipArchive.Entries.Count);

                // Loop the genome file entries, loading each in turn.
                foreach (ZipArchiveEntry zipEntry in zipArchive.Entries)
                {
                    // Skip non-genome files.
                    if (Path.GetExtension(zipEntry.Name) != ".genome")
                    {
                        continue;
                    }

                    using (Stream zipEntryStream = zipEntry.Open())
                    {
                        NeatGenome <T> genome = _genomeLoader.Load(zipEntryStream);
                        genomeList.Add(genome);
                    }
                }

                return(genomeList);
            }
        }
    void Update () 
	{
	    if (Input.GetKey(KeyCode.Space) || Input.GetKeyDown(KeyCode.UpArrow))
	    {
	        currentGenome = evolutionHelper.MutateGenome(currentGenome);
            //Debug.Log("Current generation: " + currentGenome.BirthGeneration);
            //var byteCount = System.Text.ASCIIEncoding.ASCII.GetByteCount(NeatGenomeXmlIO.Save(currentGenome, true).OuterXml);
            //Debug.LogWarning("Byte count: " + byteCount);

            var phenome = genomeDecoder.Decode(currentGenome);
            
	        Mesh mesh = ArtefactEvaluator.Evaluate(phenome, m_voxelVolume, out evaluationInfo);

	        mesh.RecalculateNormals();
	        //The diffuse shader wants uvs so just fill with a empty array, they're not actually used
	        mesh.uv = new Vector2[mesh.vertices.Length];
	        // destroy mesh object to free up memory
	        GameObject.DestroyImmediate(m_meshGameObject.GetComponent<MeshFilter>().mesh);

	        m_meshGameObject.GetComponent<MeshFilter>().mesh = mesh;
	        //m_meshGameObject.GetComponent<Renderer>().material.color = ArtefactEvaluator.artefactColor;

            SaveGenome();
	    }
	}
Exemple #32
0
        /// <summary>
        /// Refresh/update the view with the provided genome.
        /// </summary>
        public override void RefreshView(object genome)
        {
            NeatGenome neatGenome = genome as NeatGenome;

            if (null == neatGenome)
            {
                return;
            }

            // Decode genome.
            IBlackBox box = _genomeDecoder.Decode(neatGenome);

            // Probe the black box.
            _blackBoxProbe.Probe(box, _yArrTarget);

            // Update plot points.
            double[] xArr = _paramSamplingInfo._xArr;
            for (int i = 0; i < xArr.Length; i++)
            {
                if (!_generativeMode)
                {
                    box.ResetState();
                    box.InputSignalArray[0] = xArr[i];
                }
                box.Activate();
                _plotPointListResponse[i].Y = _yArrTarget[i];
            }

            // Trigger graph to redraw.
            zed.AxisChange();
            Refresh();
        }
Exemple #33
0
        private NeatGenome <T> CreateGenomeInner(NeatGenome <T> parent1, NeatGenome <T> parent2)
        {
            // Randomly select one parent as being the primary parent.
            if (_rng.NextBool())
            {
                VariableUtils.Swap(ref parent1, ref parent2);
            }

            // Enumerate over the connection genes in both parents.
            foreach (var geneIndexPair in EnumerateParentGenes(parent1.ConnectionGenes, parent2.ConnectionGenes))
            {
                // Create a connection gene based on the current position in both parents.
                ConnectionGene <T>?connGene = CreateConnectionGene(
                    parent1.ConnectionGenes, parent2.ConnectionGenes,
                    geneIndexPair.Item1, geneIndexPair.Item2,
                    out bool isSecondaryGene);

                if (connGene.HasValue)
                {
                    // Attempt to add the gene to the child genome we are building.
                    _builder.TryAddGene(connGene.Value, isSecondaryGene);
                }
            }

            // Convert the genes to the structure required by NeatGenome.
            var connGenes = _builder.ToConnectionGenes();

            // Create and return a new genome.
            return(_genomeBuilder.Create(
                       _genomeIdSeq.Next(),
                       _generationSeq.Peek,
                       connGenes));
        }
Exemple #34
0
    /**
     * Assigns an AI brain to this player. This is used when
     * loading a brain from an existing neural network xml champion file.
     */
    public AIFighter getFighterBrain()
    {
        //try to load a champion file. If any issues, use default AI.
        try
        {
            // Initialise log4net (log to console).
            XmlConfigurator.Configure(new FileInfo("log4net.properties"));

            // Experiment classes encapsulate much of the nuts and bolts of setting up a NEAT search.
            AIExperiment experiment = new AIExperiment(new AIFighterEvaluatorFactory());

            // Load config XML.
            XmlDocument xmlConfig = new XmlDocument();
            xmlConfig.Load("ai.config.xml");
            experiment.Initialize("AI", xmlConfig.DocumentElement);

            // assign genome decoder for reading champion files
            IGenomeDecoder <NeatGenome, IBlackBox> decoder = experiment.CreateGenomeDecoder();

            //load existing champion file into a genome
            string     championFileLocation = "coevolution_champion.xml";
            XmlReader  xr     = XmlReader.Create(championFileLocation);
            NeatGenome genome = NeatGenomeXmlIO.ReadCompleteGenomeList(xr, false)[0];

            //decode genome into a usable AIFighter brain.
            return(new AIFighter(decoder.Decode(genome)));
        }
        catch (System.Exception e)
        {
            Debug.Log("Unable to load CHAMPION xml file. It may not exist.\n" + e);
            return(null);
        }
    }
Exemple #35
0
        public void CacheChampion(NeatGenome championGenome)
        {
            _championGenomeMemoryStream.SetLength(0);

            using (var xmlWriter = XmlWriter.Create(_championGenomeMemoryStream, _xmlWriterSettings))
            {
                _neatExperiment.SavePopulation(xmlWriter, new List<NeatGenome> { championGenome });
            }
        }
 /// <summary>
 /// Writes a single NeatGenome to XML within a containing 'Root' element and the activation function
 /// library that the genome is associated with.
 /// The XML is returned as a newly created XmlDocument.
 /// </summary>
 /// <param name="genome">The genome to save.</param>
 /// <param name="nodeFnIds">Indicates if node activation function IDs should be emitted. They are required
 /// for HyperNEAT genomes but not for NEAT.</param>
 public static XmlDocument SaveComplete(NeatGenome genome, bool nodeFnIds)
 {
     XmlDocument doc = new XmlDocument();
     using(XmlWriter xw = doc.CreateNavigator().AppendChild())
     {
         WriteComplete(xw, genome, nodeFnIds);
     }
     return doc;
 }
		public static NeatGenome Read(XmlElement xmlGenome)
		{
			int inputNeuronCount=0;
			int outputNeuronCount=0;

			uint id = uint.Parse(XmlUtilities.GetAttributeValue(xmlGenome, "id"));

			//--- Read neuron genes into a list.
			NeuronGeneList neuronGeneList = new NeuronGeneList();
			XmlNodeList listNeuronGenes = xmlGenome.SelectNodes("neurons/neuron");
			foreach(XmlElement xmlNeuronGene in listNeuronGenes)
			{
				NeuronGene neuronGene = ReadNeuronGene(xmlNeuronGene);

				// Count the input and output neurons as we go.
				switch(neuronGene.NeuronType)
				{
					case NeuronType.Input:
						inputNeuronCount++;
						break;
					case NeuronType.Output:
						outputNeuronCount++;
						break;
				}

				neuronGeneList.Add(neuronGene);
			}

            //--- Read module genes into a list.
            List<ModuleGene> moduleGeneList = new List<ModuleGene>();
            XmlNodeList listModuleGenes = xmlGenome.SelectNodes("modules/module");
            foreach (XmlElement xmlModuleGene in listModuleGenes) {
                moduleGeneList.Add(ReadModuleGene(xmlModuleGene));
            }

			//--- Read connection genes into a list.
			ConnectionGeneList connectionGeneList = new ConnectionGeneList();
			XmlNodeList listConnectionGenes = xmlGenome.SelectNodes("connections/connection");
			foreach(XmlElement xmlConnectionGene in listConnectionGenes)
				connectionGeneList.Add(ReadConnectionGene(xmlConnectionGene));
			
			//return new NeatGenome(id, neuronGeneList, connectionGeneList, inputNeuronCount, outputNeuronCount);
            NeatGenome g = new NeatGenome(id, neuronGeneList, moduleGeneList, connectionGeneList, inputNeuronCount, outputNeuronCount);
            g.Behavior = ReadBehavior(xmlGenome.SelectSingleNode("behavior"));
            g.Behavior.objectives = new double[6];
            g.objectives = new double[6];


            // JUSTIN: Read grid/trajectory info
            g.GridCoords = ReadGrid(xmlGenome.SelectSingleNode("grid"));
            g.Behavior.trajectory = ReadTrajectory(xmlGenome.SelectSingleNode("trajectory"));

            return g;
		}
        /// <summary>
        /// For saving and vizualization, we somtimes need to change the genome
        /// BackProp for instance, happens on the phenotype and so if we want to see/save those changes
        /// we need to send the data back to NeatGenome
        /// </summary>
        /// <param name="genomeToWrite">The genome whose weights are being changed</param>
        /// <param name="connections">we set the genome's weights to the weights of these connections</param>
        /// <returns></returns>
        public static NeatGenome ChangeGenomeWeights(NeatGenome genomeToWrite, FastConnection[] connections)
        {
            IConnectionList connectionList = genomeToWrite.ConnectionList;
            int connectionCount = connectionList.Count;

            for (int i = 0; i < connectionCount; i++)
            {
                genomeToWrite.ConnectionGeneList[i].Weight = connections[i]._weight;
            }
            return genomeToWrite;
        }
        public static void Write(XmlNode parentNode, NeatGenome genome)
		{
			//----- Start writing. Create document root node.
			XmlElement xmlGenome = XmlUtilities.AddElement(parentNode, "genome");
			XmlUtilities.AddAttribute(xmlGenome, "id", genome.GenomeId.ToString());
			XmlUtilities.AddAttribute(xmlGenome, "species-id", genome.SpeciesId.ToString());
			XmlUtilities.AddAttribute(xmlGenome, "age", genome.GenomeAge.ToString());
			XmlUtilities.AddAttribute(xmlGenome, "fitness", genome.Fitness.ToString("0.00"));
			XmlUtilities.AddAttribute(xmlGenome, "realfitness", genome.RealFitness.ToString("0.00"));
            XmlUtilities.AddAttribute(xmlGenome, "adaptable", genome.networkAdaptable.ToString());
            XmlUtilities.AddAttribute(xmlGenome, "modulated", genome.networkModulatory.ToString());

            //----- Write neurons.
            XmlElement xmlNeurons = XmlUtilities.AddElement(xmlGenome, "neurons");
            foreach (NeuronGene neuronGene in genome.NeuronGeneList)
                WriteNeuron(xmlNeurons, neuronGene);

            //----- Write modules.
            XmlElement xmlModules = XmlUtilities.AddElement(xmlGenome, "modules");
            foreach (ModuleGene moduleGene in genome.ModuleGeneList)
                WriteModule(xmlModules, moduleGene);

            //----- Write connections.
			XmlElement xmlConnections = XmlUtilities.AddElement(xmlGenome, "connections");
			foreach(ConnectionGene connectionGene in genome.ConnectionGeneList)
				WriteConnectionGene(xmlConnections, connectionGene);
		    
			
		    //----- Write beahavior
		    if(genome.Behavior!=null)
		    {
		        if(genome.Behavior.behaviorList!=null)
		        {
		            XmlElement xmlBehavior = XmlUtilities.AddElement(xmlGenome, "behavior");
		            WriteBehavior(xmlBehavior,genome.objectives,genome.Behavior);        
		        }
		    }

            //----- JUSTIN: Write grid coords
            if (genome.GridCoords != null)
            {
                XmlElement xmlGridCoords = XmlUtilities.AddElement(xmlGenome, "grid");
                WriteGridCoords(xmlGridCoords, genome.GridCoords);
            }

            //----- JUSTIN: Write trajectory
            if (genome.Behavior.trajectory != null && genome.Behavior.trajectory.Count > 0)
            {
                XmlElement xmlTrajectory = XmlUtilities.AddElement(xmlGenome, "trajectory");
                WriteTrajectory(xmlTrajectory, genome.Behavior.trajectory);
            }
		}
        /// <summary>
        ///     Serializes a NEAT genome into a string.
        /// </summary>
        /// <param name="neatGenome">The NEAT genome object to serialize.</param>
        /// <returns>The serialized NEAT genome string.</returns>
        public static string GetGenomeXml(NeatGenome neatGenome)
        {
            // Create a new string writer into which to write the genome XML
            StringWriter genomeStringWriter = new StringWriter();

            // Serialize the genome to XML, but write it into a string writer instead of outputting to a file
            if (neatGenome != null)
            {
                using (XmlTextWriter genomeTextWriter = new XmlTextWriter(genomeStringWriter))
                {
                    WriteComplete(genomeTextWriter, neatGenome, false);
                }
            }

            // Convert to a string representation and return
            return genomeStringWriter.ToString();
        }
    void Start ()
	{ 
        evolutionHelper = new EvolutionHelper(k_numberOfInputs, k_numberOfOutputs);
        currentGenome = evolutionHelper.CreateInitialGenome();
        genomeDecoder = new NeatGenomeDecoder(NetworkActivationScheme.CreateAcyclicScheme());
        ArtefactEvaluator.DefaultInputType = InputType;

        SaveGenome();
        Sine.__DefaultInstance.Curve = sineCurve;

        m_meshGameObject = new GameObject("Mesh");
        m_meshGameObject.AddComponent<MeshFilter>();
        m_meshGameObject.AddComponent<MeshRenderer>();
        m_meshGameObject.AddComponent<ProceduralMesh>();
        m_meshGameObject.GetComponent<Renderer>().material = standardMaterial;
        Camera.main.GetComponent<CameraMouseOrbit>().target = m_meshGameObject.transform;
	}
    void CreateMesh(NeatGenome genome, GameObject attachedGameObject)
    {
        var phenome = genomeDecoder.Decode(genome);

        Mesh mesh = ArtefactEvaluator.Evaluate(phenome, m_voxelVolume, out evaluationInfo);

        mesh.RecalculateNormals();
        //The diffuse shader wants uvs so just fill with a empty array, they're not actually used
        mesh.uv = new Vector2[mesh.vertices.Length];
        // destroy mesh object to free up memory
        GameObject.DestroyImmediate(attachedGameObject.GetComponent<MeshFilter>().mesh);

        attachedGameObject.GetComponent<MeshFilter>().mesh = mesh;

        var meshCollider = attachedGameObject.GetComponent<MeshCollider>();
        if (meshCollider != null)
            Destroy(meshCollider);
        attachedGameObject.AddComponent<MeshCollider>();
    }
        public static void Write(XmlNode parentNode, NeatGenome genome)
		{
			//----- Start writing. Create document root node.
			XmlElement xmlGenome = XmlUtilities.AddElement(parentNode, "genome");
			XmlUtilities.AddAttribute(xmlGenome, "id", genome.GenomeId.ToString());
			XmlUtilities.AddAttribute(xmlGenome, "species-id", genome.SpeciesId.ToString());
			XmlUtilities.AddAttribute(xmlGenome, "age", genome.GenomeAge.ToString());
			XmlUtilities.AddAttribute(xmlGenome, "fitness", genome.Fitness.ToString("0.00"));
			XmlUtilities.AddAttribute(xmlGenome, "realfitness", genome.RealFitness.ToString("0.00"));
            XmlUtilities.AddAttribute(xmlGenome, "adaptable", genome.networkAdaptable.ToString());
            XmlUtilities.AddAttribute(xmlGenome, "modulated", genome.networkModulatory.ToString());
            // Schrum: Extra properties necessary for multimodal networks to make sense
            XmlUtilities.AddAttribute(xmlGenome, "outputsperpolicy", genome.OutputsPerPolicy.ToString());

            //----- Write neurons.
            XmlElement xmlNeurons = XmlUtilities.AddElement(xmlGenome, "neurons");
            foreach (NeuronGene neuronGene in genome.NeuronGeneList)
                WriteNeuron(xmlNeurons, neuronGene);

            //----- Write modules.
            XmlElement xmlModules = XmlUtilities.AddElement(xmlGenome, "modules");
            foreach (ModuleGene moduleGene in genome.ModuleGeneList)
                WriteModule(xmlModules, moduleGene);

            //----- Write connections.
			XmlElement xmlConnections = XmlUtilities.AddElement(xmlGenome, "connections");
			foreach(ConnectionGene connectionGene in genome.ConnectionGeneList)
				WriteConnectionGene(xmlConnections, connectionGene);
		    
			
		    //----- Write beahavior
		    if(genome.Behavior!=null)
		    {
		        if(genome.Behavior.behaviorList!=null)
		        {
		            XmlElement xmlBehavior = XmlUtilities.AddElement(xmlGenome, "behavior");
		            WriteBehavior(xmlBehavior,genome.Behavior);        
		        }
		    }
		}
Exemple #44
0
        private static void BackpropEpochs(NeatGenome genome, IGenomeDecoder<NeatGenome, IBlackBox> decoder, double learningRate, int epochs)
        {
            var phenome = decoder.Decode(genome);

            var network = (FastCyclicNetwork)phenome;
            network.Momentum = 0;
            network.BackpropLearningRate = learningRate;

            //Console.WriteLine("Weights Before:");
            //PrintWeights(network);
            //Console.WriteLine();

            //double[][] inputs = TrainXOR(epochs, network);
            
            for(int i = 0; i < epochs; i++)
                network.Train(new double[] { 0.3, 0.3 }, new double[] { 0.9 });

            Console.WriteLine("Weights After:");
            PrintWeights(network);
            Console.WriteLine();

            //RunXor(network, inputs);
        }
        /// <summary>
        /// Add a ConnectionGene to the builder, but only if the connection is not already present (as determined by it's neuron ID endpoints).
        /// </summary>
        /// <param name="connectionGene">The connection to add.</param>
        /// <param name="parentGenome">The conenction's parent genome. This is used to obtain NeuronGene(s) for the connection endpoints.</param>
        /// <param name="overwriteExisting">A flag that indicates if this connection should take precedence oevr an existing connection with
        /// the same endpoints.</param>
        public void TryAddGene(ConnectionGene connectionGene, NeatGenome parentGenome, bool overwriteExisting)
        {
            // Check if a matching gene has already been added.
            ConnectionEndpointsStruct connectionKey = new ConnectionEndpointsStruct(connectionGene.SourceNodeId, connectionGene.TargetNodeId);
            
            ConnectionGene existingConnectionGene;
            if(!_connectionGeneDictionary.TryGetValue(connectionKey, out existingConnectionGene))
            {   // Add new connection gene.
                ConnectionGene connectionGeneCopy = new ConnectionGene(connectionGene);
                _connectionGeneDictionary.Add(connectionKey, connectionGeneCopy);

                // Insert connection gene into a list. Use more efficient approach (append to end) if we know the gene belongs at the end.
                if(connectionGeneCopy.InnovationId > _highestConnectionGeneId) {
                    _connectionGeneList.Add(connectionGeneCopy);
                    _highestConnectionGeneId = connectionGeneCopy.InnovationId;
                } else {
                    _connectionGeneList.InsertIntoPosition(connectionGeneCopy);
                }

                // Add neuron genes (if not already added).
                // Source neuron.
                NeuronGene srcNeuronGene;
                if(!_neuronDictionary.TryGetValue(connectionGene.SourceNodeId, out srcNeuronGene))
                {
                    srcNeuronGene = parentGenome.NeuronGeneList.GetNeuronById(connectionGene.SourceNodeId);
                    srcNeuronGene = new NeuronGene(srcNeuronGene, false); // Make a copy.
                    _neuronDictionary.Add(srcNeuronGene.Id, srcNeuronGene);
                }

                // Target neuron.
                NeuronGene tgtNeuronGene;
                if(!_neuronDictionary.TryGetValue(connectionGene.TargetNodeId, out tgtNeuronGene))
                {
                    tgtNeuronGene = parentGenome.NeuronGeneList.GetNeuronById(connectionGene.TargetNodeId);
                    tgtNeuronGene = new NeuronGene(tgtNeuronGene, false); // Make a copy.
                    _neuronDictionary.Add(tgtNeuronGene.Id, tgtNeuronGene);
                }

                // Register connectivity with each neuron.
                srcNeuronGene.TargetNeurons.Add(tgtNeuronGene.Id);
                tgtNeuronGene.SourceNeurons.Add(srcNeuronGene.Id);
            }
            else if(overwriteExisting)
            {   // The genome we are building already has a connection with the same neuron endpoints as the one we are
                // trying to add. It didn't match up during correlation because it has a different innovation number, this
                // is possible because the innovation history buffers throw away old innovations in a FIFO manner in order
                // to prevent them from bloating.

                // Here the 'overwriteExisting' flag is set so the gene we are currently trying to add is probably from the
                // fitter parent, and therefore we want to use its connection weight in place of the existing gene's weight.
                existingConnectionGene.Weight = connectionGene.Weight;
            }
        }
    void SpawnParentAndSeeds(NeatGenome parent)
    {
        CreateMesh(parent, parentGameObject);

        seeds.Clear();
        for (int i = 0; i < numberOfChildren; i++)
        {
            var child = evolutionHelper.MutateGenome(parent);
            seeds.Add(child);
            CreateMesh(child, seedsGameObjects[i]);
        }
    }
        /// <summary>
        /// Writes a NeatGenome to XML.
        /// </summary>
        /// <param name="xw">XmlWriter to write XML to.</param>
        /// <param name="genome">Genome to write as XML.</param>
        /// <param name="nodeFnIds">Indicates if node activation function IDs should be emitted. They are required
        /// for HyperNEAT genomes but not for NEAT.</param>
        public static void Write(XmlWriter xw, NeatGenome genome, bool nodeFnIds)
        {
            xw.WriteStartElement(__ElemNetwork);
            xw.WriteAttributeString(__AttrId, genome.Id.ToString(NumberFormatInfo.InvariantInfo));
            xw.WriteAttributeString(__AttrBirthGeneration, genome.BirthGeneration.ToString(NumberFormatInfo.InvariantInfo));
            xw.WriteAttributeString(__AttrFitness, genome.EvaluationInfo.Fitness.ToString("R", NumberFormatInfo.InvariantInfo));

            // Emit nodes.
            StringBuilder sb = new StringBuilder();
            xw.WriteStartElement(__ElemNodes);
            foreach(NeuronGene nGene in genome.NeuronGeneList)
            {
                xw.WriteStartElement(__ElemNode);
                xw.WriteAttributeString(__AttrType, NetworkXmlIO.GetNodeTypeString(nGene.NodeType));
                xw.WriteAttributeString(__AttrId, nGene.Id.ToString(NumberFormatInfo.InvariantInfo));
                if(nodeFnIds)
                {	// Write activation fn ID.
                    xw.WriteAttributeString(__AttrActivationFunctionId, nGene.ActivationFnId.ToString(NumberFormatInfo.InvariantInfo));

                    // Write aux state as comma separated list of real values.
                    XmlIoUtils.WriteAttributeString(xw, __AttrAuxState, nGene.AuxState);
                }
                xw.WriteEndElement();
            }
            xw.WriteEndElement();

            // Emit connections.
            xw.WriteStartElement(__ElemConnections);
            foreach(ConnectionGene cGene in genome.ConnectionList)
            {
                xw.WriteStartElement(__ElemConnection);
                xw.WriteAttributeString(__AttrId, cGene.InnovationId.ToString(NumberFormatInfo.InvariantInfo));
                xw.WriteAttributeString(__AttrSourceId, cGene.SourceNodeId.ToString(NumberFormatInfo.InvariantInfo));
                xw.WriteAttributeString(__AttrTargetId, cGene.TargetNodeId.ToString(NumberFormatInfo.InvariantInfo));
                xw.WriteAttributeString(__AttrWeight, cGene.Weight.ToString("R", NumberFormatInfo.InvariantInfo));
                xw.WriteEndElement();
            }
            xw.WriteEndElement();

            // </Network>
            xw.WriteEndElement();
        }
        /// <summary>
        /// Refresh/update the view with the provided genome.
        /// </summary>
        public override void RefreshView(object genome)
        {
            _box = null;
            _neatGenome = genome as NeatGenome;
            if(null == _neatGenome) {
                return;
            }

            // Decode genome.
            _box = _genomeDecoder.Decode(_neatGenome);

            // Generate new test case.
            _testCaseField.InitTestCase(_largeBoxTestCase++ % 3);

            // Paint test case and network response.
            PaintView(_box);
        }
        /// <summary>
        /// Writes a single NeatGenome to XML within a containing 'Root' element and the activation
        /// function library that the genome is associated with.
        /// </summary>
        /// <param name="xw">XmlWriter to write XML to.</param>
        /// <param name="genome">Genome to write as XML.</param>
        /// <param name="nodeFnIds">Indicates if node activation function IDs should be emitted. They are required
        /// for HyperNEAT genomes but not for NEAT.</param>
        public static void WriteComplete(XmlWriter xw, NeatGenome genome, bool nodeFnIds)
        {
            // <Root>
            xw.WriteStartElement(__ElemRoot);

            // Write activation function library.
            NetworkXmlIO.Write(xw, genome.ActivationFnLibrary);

            // <Networks>
            xw.WriteStartElement(__ElemNetworks);

            // Write single genome.
            Write(xw, genome, nodeFnIds);

            // </Networks>
            xw.WriteEndElement();

            // </Root>
            xw.WriteEndElement();
        }
        public NeatEvolutionAlgorithm<NeatGenome> CreateEvolutionAlgorithm(NeatGenome seed, IGenomeListEvaluator<NeatGenome> eval = null)
        {
            // Create a genome factory with our neat genome parameters object and the appropriate number of input and output neuron genes.
            IGenomeFactory<NeatGenome> genomeFactory = CreateGenomeFactory();

            // Create an initial population of randomly generated genomes.
            List<NeatGenome> genomeList = genomeFactory.CreateGenomeList(_populationSize, 0, seed);

            return CreateEvolutionAlgorithm(genomeFactory, genomeList, eval);
        }
        public static void WriteNeatGenome(string serializedGenomePath, NeatGenome genomeToWrite)
        {
            // Create a reader for the serialized genome
            XmlWriter writer = XmlWriter.Create(serializedGenomePath);

            NeatGenomeXmlIO.WriteComplete(writer, genomeToWrite, true);
            writer.Close();
        }
 public NeatGenome MutateGenome(NeatGenome genome)
 {
     return genome.CreateOffspring(genome.BirthGeneration + 1);
 }